from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime, timezone
from decimal import Decimal

from src.market.context import CoinMarketContext


@dataclass(frozen=True)
class DataQualityDecision:
    allowed: bool
    reasons: tuple[str, ...]


class DataQualityGate:
    def __init__(self, *, max_age_seconds: int = 90, max_spread_pct: Decimal = Decimal("0.20"), min_reliability_score: Decimal = Decimal("0.75")) -> None:
        self.max_age_seconds = max_age_seconds
        self.max_spread_pct = max_spread_pct
        self.min_reliability_score = min_reliability_score

    def evaluate(self, context: CoinMarketContext, *, degraded_mode_active: bool = False, now: datetime | None = None) -> DataQualityDecision:
        reasons: list[str] = []
        now = now or datetime.now(timezone.utc)
        if context.stale_data or context.age_seconds(now) > self.max_age_seconds:
            reasons.append("stale_context")
        if not context.l2_available or context.spread_pct is None:
            reasons.append("missing_l2_book")
        elif context.spread_pct > self.max_spread_pct:
            reasons.append("spread_too_wide")
        if context.reliability_score < self.min_reliability_score:
            reasons.append("low_reliability")
        if degraded_mode_active:
            reasons.append("api_degraded")
        return DataQualityDecision(allowed=not reasons, reasons=tuple(reasons))
