"""
Response schemas — the exact contract the client's frontend can rely on.

Every field is explicitly typed and Optional where a model can legitimately
have no answer (e.g. no SARIMAX model exists yet for a brand-new district).
This means the client gets a 200 with nulls in known places, never a
500 because a key was missing from a dict.
"""

from typing import Optional

from pydantic import BaseModel


class ClimateOutput(BaseModel):
    forecast_rainfall_mm: Optional[float] = None
    forecast_temp_c: Optional[float] = None
    anomaly_score: float = 0.0
    anomaly_label: str = "unknown"  # normal | high | low | unknown


class FeasibilityOutput(BaseModel):
    label: str  # suitable | risky | not_suitable
    confidence: float
    top_factors: list[str] = []


class YieldOutput(BaseModel):
    expected_yield_ton_ha: float
    uncertainty_ton_ha: float = 0.0
    unit: str = "tonnes per hectare"


class TrendOutput(BaseModel):
    trend: str  # upward | downward | stable | volatile
    slope: Optional[float] = None
    confidence: float


class AlternativeCrop(BaseModel):
    crop: str
    score: float
    reason: Optional[str] = None


class RecommendationOutput(BaseModel):
    alternatives: list[AlternativeCrop]


class MarketOutput(BaseModel):
    price_forecast_per_quintal: Optional[float] = None
    demand_level: str = "unknown"  # high | medium | low | unknown
    price_volatility: str = "unknown"  # high | medium | low | unknown


class ModelOutputs(BaseModel):
    climate: ClimateOutput
    feasibility: FeasibilityOutput
    yield_prediction: YieldOutput
    trend: TrendOutput
    recommendation: RecommendationOutput
    market: MarketOutput
    conflicts: list[str] = []


class CropAnalysisResult(BaseModel):
    request_id: str
    input: dict
    models: ModelOutputs
    explanation: str
    model_version: str
    processing_ms: int
    cached: bool = False


class ErrorResponse(BaseModel):
    """Standard error shape returned for every 4xx/5xx — never a bare exception."""
    error_code: str
    message: str
    request_id: str
