"""Pydantic response models for Stock Oracle API."""

from __future__ import annotations

from typing import Any

from pydantic import BaseModel, Field

# ---------------------------------------------------------------------------
# Company Info
# ---------------------------------------------------------------------------


class CompanyInfo(BaseModel):
    ticker: str
    name: str | None = None
    cik: str | None = None
    exchange: str | None = None
    sector: str | None = None
    industry: str | None = None
    country: str | None = None
    market_cap: float | None = None
    extra: dict[str, Any] = Field(default_factory=dict)


# ---------------------------------------------------------------------------
# SEC Filings
# ---------------------------------------------------------------------------


class FilingEntry(BaseModel):
    accession_no: str
    form_type: str
    filing_date: str  # ISO date string
    accepted_at: str | None = None
    primary_document: str | None = None
    description: str | None = None
    items: list[str] = Field(default_factory=list)


class FilingSearchResponse(BaseModel):
    ticker: str
    filings: list[FilingEntry] = Field(default_factory=list)
    total: int = 0


class ExhibitDocument(BaseModel):
    exhibit_type: str
    filename: str | None = None
    url: str | None = None


class FilingDocumentsResponse(BaseModel):
    accession_no: str
    exhibits: list[ExhibitDocument] = Field(default_factory=list)


class ExhibitResponse(BaseModel):
    accession_no: str
    exhibit_type: str
    content: str
    content_type: str = "text/plain"


# ---------------------------------------------------------------------------
# Price / Market Data
# ---------------------------------------------------------------------------


class PriceBar(BaseModel):
    date: str  # ISO date
    open: float
    high: float
    low: float
    close: float
    volume: int
    vwap: float | None = None
    trade_count: int | None = None


class PriceDataResponse(BaseModel):
    ticker: str
    bars: list[PriceBar] = Field(default_factory=list)
    source: str = "yfinance"


class PriceQuote(BaseModel):
    ticker: str
    price: float
    bid: float | None = None
    ask: float | None = None
    volume: int | None = None
    timestamp: str | None = None


class IntradayBar(BaseModel):
    timestamp: str
    open: float
    high: float
    low: float
    close: float
    volume: int


class IntradayResponse(BaseModel):
    ticker: str
    bars: list[IntradayBar] = Field(default_factory=list)
    timeframe: str = "1m"


# ---------------------------------------------------------------------------
# Financial / XBRL
# ---------------------------------------------------------------------------


class FinancialPeriod(BaseModel):
    period: str  # e.g. "2025-Q4"
    period_end: str  # ISO date
    revenue: float | None = None
    net_income: float | None = None
    eps: float | None = None
    gross_margin: float | None = None
    operating_margin: float | None = None
    extra: dict[str, Any] = Field(default_factory=dict)


class FinancialDataResponse(BaseModel):
    ticker: str
    periods: list[FinancialPeriod] = Field(default_factory=list)


# ---------------------------------------------------------------------------
# FRED
# ---------------------------------------------------------------------------


class FredObservation(BaseModel):
    date: str  # ISO date
    value: float | None = None


class FredProxyResponse(BaseModel):
    series_id: str
    observations: list[FredObservation] = Field(default_factory=list)
    realtime_start: str | None = None
    realtime_end: str | None = None


class FredSeriesInfo(BaseModel):
    id: str
    title: str | None = None
    frequency: str | None = None
    units: str | None = None
    notes: str | None = None


# ---------------------------------------------------------------------------
# FINRA Short Volume
# ---------------------------------------------------------------------------


class ShortVolumeEntry(BaseModel):
    date: str  # ISO date
    short_volume: int
    short_exempt_volume: int | None = None
    total_volume: int | None = None


class ShortVolumeResponse(BaseModel):
    symbol: str
    data: list[ShortVolumeEntry] = Field(default_factory=list)


class ShortRatioPoint(BaseModel):
    date: str
    short_ratio: float | None = None
    short_percent: float | None = None


class ShortRatioResponse(BaseModel):
    symbol: str
    data: list[ShortRatioPoint] = Field(default_factory=list)


# ---------------------------------------------------------------------------
# Dividends
# ---------------------------------------------------------------------------


class DividendCalendarEntry(BaseModel):
    ticker: str
    ex_dividend_date: str
    amount: float
    declaration_date: str | None = None
    record_date: str | None = None
    payment_date: str | None = None
    currency: str = "USD"
    dividend_type: str = "regular"
    frequency: str | None = None
    as_of_date: str
    source: str


class DividendUpcomingResponse(BaseModel):
    dividends: list[DividendCalendarEntry] = Field(default_factory=list)
    total_count: int = 0
    metadata: dict[str, Any] = Field(default_factory=dict)


class DividendHistoryResponse(BaseModel):
    symbol: str
    dividends: list[DividendCalendarEntry] = Field(default_factory=list)
    total_count: int = 0
    annual_yield_estimate: float | None = None
    metadata: dict[str, Any] = Field(default_factory=dict)


class DividendIngestResponse(BaseModel):
    symbols_processed: int
    total_records_upserted: int
    failed_symbols: list[str] = Field(default_factory=list)
    status: str
    metadata: dict[str, Any] = Field(default_factory=dict)


# ---------------------------------------------------------------------------
# Screener
# ---------------------------------------------------------------------------


class ScreenerStock(BaseModel):
    symbol: str
    name: str | None = None
    exchange: str | None = None
    market_cap: float | None = None
    avg_volume: float | None = None


class ScreenerResponse(BaseModel):
    stocks: list[ScreenerStock] = Field(default_factory=list)
    total: int = 0
    page: int = 1
    page_size: int = 250


# ---------------------------------------------------------------------------
# Attention
# ---------------------------------------------------------------------------


class EntityInfo(BaseModel):
    ticker: str
    canonical_name: str
    wiki_title: str | None = None
    gdelt_query: str | None = None
    aliases: list[str] = Field(default_factory=list)
    resolver_confidence: float = 0.0
    is_manual_override: bool = False


class EntityResolveResponse(BaseModel):
    ticker: str
    entity: EntityInfo
    status: str
    message: str


class WikiFeatures(BaseModel):
    views: int | None = None
    baseline_10d: float | None = None
    spike_10d: float | None = None
    zscore_20d: float | None = None


class NewsFeatures(BaseModel):
    article_count_1d: int = 0
    article_count_3d: int = 0
    unique_domains_3d: int = 0
    us_article_count_3d: int = 0
    gdelt_status: str = "not_collected"


class EventAttentionResponse(BaseModel):
    ticker: str
    event_date: str
    entity: EntityInfo
    wiki: WikiFeatures
    news: NewsFeatures
    metadata: dict[str, Any] = Field(default_factory=dict)


class CollectionStatusResponse(BaseModel):
    ticker: str
    source: str
    records_collected: int
    date_range: dict[str, Any] = Field(default_factory=dict)
    status: str
