"""Provider protocols and lightweight data transfer objects.

Protocols define the interface for external data providers.
DTOs are simple dataclasses — NOT SQLAlchemy models — used to
transfer data between providers and the service layer.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import date, datetime
from typing import Protocol


# ---------------------------------------------------------------------------
# Data Transfer Objects
# ---------------------------------------------------------------------------


@dataclass(frozen=True, slots=True)
class OHLCVData:
    """Lightweight OHLCV record returned by market data providers."""

    ticker: str
    date: date
    open: float
    high: float
    low: float
    close: float
    volume: int


@dataclass(frozen=True, slots=True)
class SentimentData:
    """Sentiment analysis result returned by sentiment providers."""

    ticker: str
    classification: str  # "bullish" | "bearish" | "neutral"
    confidence: int  # 0-100
    source: str
    timestamp: datetime
    reasoning: str = ""
    citations: list[dict[str, str]] = field(default_factory=list)  # [{"url": ..., "title": ...}]
    recommendation: str | None = None  # "buy" | "hold" | "avoid" — actionable LLM view


@dataclass(frozen=True, slots=True)
class FundamentalData:
    """Fundamental metrics returned by fundamental providers."""

    ticker: str
    pe_ratio: float | None
    revenue_growth: float | None
    earnings_surprise: float | None
    market_cap: float | None
    fetched_at: datetime
    next_earnings_date: date | None = None
    unavailable_fields: dict[str, str] = field(default_factory=dict)


# ---------------------------------------------------------------------------
# Provider Protocols
# ---------------------------------------------------------------------------


class MarketDataProvider(Protocol):
    """Protocol for OHLCV market data providers."""

    async def fetch_ohlcv(
        self, ticker: str, start_date: date, end_date: date
    ) -> list[OHLCVData]:
        """Fetch OHLCV data for a ticker in a date range."""
        ...


class SentimentProvider(Protocol):
    """Protocol for sentiment analysis providers."""

    async def fetch_sentiment(self, ticker: str) -> SentimentData:
        """Fetch current sentiment analysis for a ticker."""
        ...


class FundamentalProvider(Protocol):
    """Protocol for fundamental data providers."""

    async def fetch_fundamentals(self, ticker: str) -> FundamentalData:
        """Fetch fundamental data for a ticker."""
        ...
