"""Regime-conditional evaluation — judge a strategy's returns WITHIN each regime, so a regime-specialist
(strong in its regime, flat overall) is found, and a strategy is tagged with the regimes it truly works in.

This is both more powerful (specialists are invisible on the full sample) and more disciplined (a
theory-driven split by market state, not a data-mined parameter)."""
from __future__ import annotations

import numpy as np

from fxhnt.domain.gauntlet import evaluate
from fxhnt.domain.models import Verdict
from fxhnt.domain.regime.classifier import WARMUP

_MIN_HALF = 30  # min obs each side of the within-regime IS/OOS split


def evaluate_by_regime(
    returns: np.ndarray, labels: tuple[str, ...], *, oos_fraction: float = 0.4, min_obs: int = 120,
    n_trials: int = 1, sr_variance: float = 0.0, dsr_min: float = 0.95, oos_min_sharpe: float = 0.0,
    max_is_oos_decay: float = 0.5, has_economic_rationale: bool = True,
) -> dict[str, Verdict]:
    """Return {regime: Verdict} for every regime with enough observations. The regimes where the verdict
    passes are the strategy's specialty."""
    r = np.asarray(returns, float)
    out: dict[str, Verdict] = {}
    for regime in sorted({lbl for lbl in labels if lbl != WARMUP}):
        idx = np.array([i for i, lbl in enumerate(labels) if lbl == regime])
        if len(idx) < min_obs:
            continue
        rr = r[idx]  # chronological within the regime (idx ascending) -> a valid IS/OOS split by order
        split = int((1.0 - oos_fraction) * len(rr))
        if split < _MIN_HALF or len(rr) - split < _MIN_HALF:
            continue
        out[regime] = evaluate(
            rr[:split], rr[split:], n_trials=n_trials, sr_variance=sr_variance, dsr_min=dsr_min,
            oos_min_sharpe=oos_min_sharpe, max_is_oos_decay=max_is_oos_decay,
            has_economic_rationale=has_economic_rationale,
        )
    return out
