# app/src/trading/decision/models.py

from __future__ import annotations

from dataclasses import dataclass, field

from src.trading.market_intelligence.common.enums import EngineStatus
from src.trading.market_intelligence.common.models import CoordinatorResult
from src.trading.market_intelligence.common.reasons import ReasonCode
from src.trading.market_intelligence.common.scores import (
    EngineConfidence,
    EngineScore,
)
from src.trading.market_intelligence.common.types import (
    ContextDict,
    DiagnosticMessages,
    DurationMs,
    PayloadDict,
)


@dataclass(frozen=True, slots=True)
class TradingDiagnostics:
    reason: ReasonCode = ReasonCode.UNKNOWN
    details: ContextDict = field(default_factory=dict)
    warnings: DiagnosticMessages = field(default_factory=list)
    errors: DiagnosticMessages = field(default_factory=list)

    @property
    def has_warnings(self) -> bool:
        return bool(self.warnings)

    @property
    def has_errors(self) -> bool:
        return bool(self.errors)


@dataclass(frozen=True, slots=True)
class TradingEvaluationMeta:
    trading_version: str
    calculated_at: float | None = None
    duration_ms: DurationMs | None = None


@dataclass(frozen=True, slots=True)
class TradingDecision:
    coordinator_result: CoordinatorResult
    diagnostics: TradingDiagnostics = field(default_factory=TradingDiagnostics)
    meta: TradingEvaluationMeta | None = None
    payload: PayloadDict = field(default_factory=dict)

    status: EngineStatus = EngineStatus.UNKNOWN
    score: EngineScore = field(default_factory=EngineScore)
    confidence: EngineConfidence = field(default_factory=EngineConfidence)
    reason: ReasonCode = ReasonCode.UNKNOWN

    @property
    def is_usable(self) -> bool:
        return self.status in {
            EngineStatus.OK,
            EngineStatus.PARTIAL,
            EngineStatus.STALE,
        }

    @property
    def has_errors(self) -> bool:
        return self.diagnostics.has_errors