"""Pydantic schemas for fundamental data endpoints."""

from __future__ import annotations

from datetime import date, datetime

from pydantic import BaseModel


class MetricIndustry(BaseModel):
    label: str
    median: float
    favorable_percentile: int  # 0-100, polarity-aware (higher = more favorable)
    peer_count: int


class MetricHistoryPoint(BaseModel):
    period_end: str  # YYYY-MM-DD
    value: float | None


class MetricItem(BaseModel):
    key: str
    value: float | None = None
    history: list[MetricHistoryPoint] = []
    industry: MetricIndustry | None = None
    period_end: str | None = None
    filed_date: str | None = None
    caveat: str | None = None
    source: str = "sec"


class EarningsNext(BaseModel):
    date: str
    session: str
    days_until: int


class EarningsRecent(BaseModel):
    announce_date: str
    period_end: str | None = None
    eps_estimate: float | None = None
    eps_actual: float | None = None
    surprise_pct: float | None = None


class EarningsObject(BaseModel):
    next: EarningsNext | None = None
    recent: list[EarningsRecent] = []


class Valuation(BaseModel):
    pe: float | None = None
    fcf_yield: float | None = None
    market_cap_est: float | None = None
    pe_industry: MetricIndustry | None = None
    fcf_yield_industry: MetricIndustry | None = None
    price_date: str | None = None


class FundamentalsReads(BaseModel):
    """Deterministic text outputs, separate from the numeric metrics.

    ``by_key`` is a fixed map over every metric key plus ``pe`` and ``fcf_yield``,
    each a read string or null. ``header`` is null when there is no read at all."""

    header: str | None = None
    by_key: dict[str, str | None] = {}


class FundamentalResponse(BaseModel):
    """Envelope-ready fundamental data response.

    Legacy fields are preserved unchanged (they come from ``fundamental_data`` /
    the legacy providers). The additive v1 objects — earnings, metrics, valuation,
    reads — are SEC/Dolt-derived and independent; a null legacy field is never
    mapped onto the new SEC metrics and vice-versa.
    """

    symbol: str
    pe_ratio: float | None = None
    revenue_growth: float | None = None
    earnings_surprise: float | None = None
    market_cap: float | None = None
    next_earnings_date: date | None = None
    fetched_at: datetime | None = None
    unavailable_fields: dict[str, str] = {}

    # --- additive v1 (always present; empty/null when unavailable) ---
    earnings: EarningsObject | None = None
    metrics: list[MetricItem] | None = None
    valuation: Valuation | None = None
    reads: FundamentalsReads | None = None
    setup_eligible: bool = True
    setup_block_code: str | None = None
    setup_block_reason: str | None = None
