"""Strategy-lifecycle domain — the persistent population the factory breeds.

A StrategyRecord is a regime-specialist candidate: one strategy applied across a set of markets, tagged
with the regimes it actually works in (per-regime verdict) and a lifecycle status. The factory writes
discoveries here; the executor reads DEPLOYED specialists; the global trial counter lives alongside so the
deflation stays honest at fleet scale.
"""
from __future__ import annotations

import datetime as dt
from enum import StrEnum

from pydantic import BaseModel, Field

from fxhnt.domain.models import AssetClass, StrategySpec


class StrategyStatus(StrEnum):
    DISCOVERED = "discovered"          # passed the (pre-filter) gauntlet in ≥1 regime, not yet forward-tested
    FORWARD = "forward_tracking"       # accumulating a real-time paper track record (the un-gameable filter)
    DEPLOYED = "deployed"              # live in the book when its regime is active
    RETIRED = "retired"                # edge decayed / regime gone / failed forward


class RegimeFit(BaseModel):
    """A strategy's verdict WITHIN one regime — it is a specialist where `passed`."""
    regime: str
    dsr: float
    is_sharpe: float
    oos_sharpe: float
    passed: bool


class StrategyRecord(BaseModel):
    strategy_id: str
    markets: list[str]
    asset_class: AssetClass
    spec: StrategySpec
    regime_fits: list[RegimeFit] = Field(default_factory=list)
    status: StrategyStatus = StrategyStatus.DISCOVERED
    discovered_at: dt.datetime
    updated_at: dt.datetime
    n_trials_at_discovery: int = 0     # the global trial count when found — honesty-at-scale record
    source: str = ""                   # which agent / territory found it

    # forward-validation track — the un-gameable filter (only accrues on real, post-discovery bars)
    forward_started: str = ""          # data bar date when forward tracking began
    forward_last_date: str = ""        # last data bar marked into the forward track
    forward_days: int = 0              # in-regime forward observations
    forward_sum: float = 0.0           # Σ forward in-regime returns
    forward_sumsq: float = 0.0         # Σ forward in-regime returns²
    # the in-regime forward return sequence (for CUSUM edge-decay)
    forward_returns: list[float] = Field(default_factory=list)

    def specialist_regimes(self) -> list[str]:
        """The regimes this strategy is a (passing) specialist in."""
        return [f.regime for f in self.regime_fits if f.passed]

    def forward_mean(self) -> float:
        return self.forward_sum / self.forward_days if self.forward_days else 0.0

    def forward_sharpe(self) -> float:
        if self.forward_days < 2:
            return 0.0
        mean = self.forward_sum / self.forward_days
        var = self.forward_sumsq / self.forward_days - mean * mean
        return (mean / var**0.5) * (252.0**0.5) if var > 0 else 0.0


def strategy_id(markets: list[str], asset_class: AssetClass, spec: StrategySpec) -> str:
    """Deterministic identity for a (markets × strategy) specialist — re-discovery merges, not dupes."""
    import hashlib

    key = f"{','.join(sorted(markets))}|{asset_class.value}|{spec.key()}"
    return f"{spec.kind}-{hashlib.sha1(key.encode()).hexdigest()[:10]}"
