from __future__ import annotations

from typing import Any, Literal

from pydantic import BaseModel, ConfigDict, Field

from jarvis_finance.api.schemas.portfolio_performance import PerformanceCoverageResponse

ReadinessStatus = Literal["ready", "partial", "not_ready", "not_applicable"]


class WealthPeriod(BaseModel):
    model_config = ConfigDict(extra="forbid", populate_by_name=True)

    preset: Literal["ytd", "previous_year", "12m", "all"]
    from_: str = Field(alias="from")
    to: str


class WealthDimensionStatus(BaseModel):
    model_config = ConfigDict(extra="forbid")

    status: ReadinessStatus
    reason_code: str | None


class WealthReadinessDimensions(BaseModel):
    model_config = ConfigDict(extra="forbid")

    current_value: WealthDimensionStatus
    freshness: WealthDimensionStatus
    reconciliation: WealthDimensionStatus
    performance: WealthDimensionStatus
    policy: WealthDimensionStatus


class WealthReadinessMetric(BaseModel):
    model_config = ConfigDict(extra="forbid")

    key: str
    label: str
    status: ReadinessStatus
    included_sources: list[str]
    missing_sources: list[str]
    as_of: str | None
    period: WealthPeriod
    blocker: str | None
    action: str | None
    reason_code: str | None


class WealthReadiness(BaseModel):
    model_config = ConfigDict(extra="forbid")

    dimensions: WealthReadinessDimensions
    metrics: list[WealthReadinessMetric]


class WealthDiagnostic(BaseModel):
    model_config = ConfigDict(extra="forbid")

    dimension: Literal[
        "current_value", "freshness", "reconciliation", "performance", "policy"
    ]
    affected_sources: list[str]
    message: str
    action: str
    reason_code: str
    prominent: bool


class WealthSource(BaseModel):
    model_config = ConfigDict(extra="forbid")

    key: str
    label: str
    provider_label: str | None = None
    kind: str
    source_role: Literal["account", "canonical_value"] | None = None
    performance_scope: Literal["postfinance", "truewealth", "crypto"] | None = None
    current_value_chf: str | None
    current_value_status: ReadinessStatus
    change_chf: str | None
    net_contributions_chf: str | None
    return_pct: str | None
    as_of: str | None
    freshness_status: Literal["fresh", "stale", "unavailable", "unknown"]
    freshness_reason_code: str | None = None
    expected_as_of: str | None = None
    reconciliation_status: Literal["reconciled", "difference", "not_assessable"]
    performance_status: ReadinessStatus


class WealthCockpitResponse(BaseModel):
    """Runtime-validated contract for the read-only wealth cockpit."""

    model_config = ConfigDict(extra="forbid")

    scope_label: str
    not_net_worth: bool
    period: WealthPeriod
    data_cutoff: str
    kpis: list[dict[str, Any]]
    totals: dict[str, Any]
    history: dict[str, Any]
    distribution: list[dict[str, Any]]
    sources: list[WealthSource]
    readiness: WealthReadiness
    diagnostics: list[WealthDiagnostic]
    performance_coverage: PerformanceCoverageResponse
    policy: dict[str, Any]
    planning: dict[str, Any]
    data_quality: dict[str, Any]
    hints: list[str]
    method: dict[str, str]
