"""Pydantic models for parsed financial candidates."""

from __future__ import annotations

from enum import Enum

from pydantic import BaseModel, Field


class CandidateType(str, Enum):
    """Types of financial entities detected by the deterministic parser."""

    TICKER = "ticker"
    CURRENCY = "currency"
    MONEY = "money"
    PERCENTAGE = "percentage"
    BASIS_POINTS = "basis_points"
    RANGE = "range"
    EPS = "eps"
    REVENUE = "revenue"
    DATE = "date"
    FISCAL_PERIOD = "fiscal_period"


class PeriodAnnotation(BaseModel):
    """Optional period context for a parsed candidate (e.g., Q1, FY2025)."""

    period_type: str = Field(description="Type: quarter, year, fiscal_year, half")
    period_value: str = Field(description="Normalized period: Q1, Q2, H1, FY")
    year: int | None = Field(default=None, description="Calendar or fiscal year")


class ParsedCandidate(BaseModel):
    """A single parsed financial entity with source offset and normalization.

    Stores both the literal text as it appeared in the source document and the
    normalized numeric value (if applicable). Exact character offsets allow
    downstream evidence linking back to the source.
    """

    candidate_type: CandidateType = Field(description="Classification of the parsed entity")
    literal_value: str = Field(min_length=1, description="Exact text as it appears in source")
    normalized_value: float | None = Field(default=None, description="Normalized numeric value")
    unit: str | None = Field(default=None, description="Unit: USD, EUR, %, bps, etc.")
    start_char: int = Field(ge=0, description="Start character offset in source text")
    end_char: int = Field(gt=0, description="End character offset in source text (exclusive)")
    period: PeriodAnnotation | None = Field(default=None, description="Optional fiscal/calendar period")
