"""The ONE backtest->ref path. Every reconciliation-gated strategy produces its `backtest_summary` here,
dispatched on `STRATEGY_REGISTRY[sid]["definition"]["backtest"]["kind"]`. Replaces the three fragmented
mechanisms (inline _persist_track_backtest_ref, the bybit-persist-sleeve-ret Job, the B3 equity runner).
A missing/failed ref is best-effort (returns None) -> the gate WAITs (false-WAIT-safe)."""
from __future__ import annotations

import datetime as _dt
from typing import Any

from fxhnt.application.bybit_forward_track import backtest_summary_from_rows
from fxhnt.application.forward_models import BacktestSummary
from fxhnt.registry import STRATEGY_REGISTRY

_EPOCH = _dt.date(1970, 1, 1)


def _iso(epoch_day: int) -> str:
    """epoch_day (days since 1970-01-01 UTC) -> ISO date string. Same idiom as
    `bybit_forward_track`'s `_EPOCH + timedelta(days=d)` conversion."""
    return (_EPOCH + _dt.timedelta(days=int(epoch_day))).isoformat()


def registry_backtest_kind(strategy_id: str) -> str:
    return STRATEGY_REGISTRY[strategy_id]["definition"].get("backtest", {}).get("kind", "none")


def backtest_ref(strategy_id: str, store: Any, *, build_strategy: Any = None) -> BacktestSummary | None:
    """Produce the reconciliation-gate backtest reference for `strategy_id`, or None (gate WAITs).
    `build_strategy` (a zero-arg callable returning a ForwardStrategy) is required for `recompute-replay`.
    `store` (an AnalyticalStore) is required for `sleeve`/`report`."""
    kind = registry_backtest_kind(strategy_id)
    if kind == "none":
        return None
    if kind == "recompute-replay":
        if build_strategy is None:
            return None
        rows, _ = build_strategy().advance(None, {})
        return backtest_summary_from_rows(strategy_id, rows) if len(rows) >= 2 else None
    if kind == "sleeve":
        from fxhnt.application.bybit_book_eval import sleeve_returns_from_store
        # Real contract: sleeve_returns_from_store(store, edge, *, universe=None, cost_bps=0.0, ...)
        #   -> {epoch_day: ret}  (store FIRST, edge SECOND — mirrors funding_dispersion_eval's
        # `sleeve_returns_from_store(bybit_store, "xsfunding", universe=overlap, cost_bps=cost_bps)` call for
        # the SAME edge). `strategy_id` doubles as the `edge` name for sleeve-kind strategies (e.g.
        # "xsfunding"). cost_bps=5.5 matches the SAME per-turnover cost the live 4-edge book and the carry
        # engine charge (`BybitFourEdgeStrategy`'s default / `carry_metrics_from_store`'s `base_cost_bps`) —
        # the reconciliation gate must reconcile against a NET-of-cost reference, at the same basis the live
        # track books. `universe=None`: `store` is expected to already be scoped to the right read (a
        # `TimescaleFeatureStore`/`_UniverseRestrictedStore`-compatible `AnalyticalStore`) by the caller.
        series = sleeve_returns_from_store(store, strategy_id, cost_bps=5.5)   # {epoch_day: ret}
        rows = [(_iso(day), ret) for day, ret in sorted(series.items())]       # -> [(iso_date, ret), ...]
        return backtest_summary_from_rows(strategy_id, rows) if len(rows) >= 2 else None
    if kind == "report":
        from fxhnt.application.backtest_refs_report import report_backtest_summary
        return report_backtest_summary(strategy_id, store)     # built in Task 5
    if kind == "model-ref":
        # Executed tracks reconcile against their MODELED counterpart's backtest ref, resolved at the gate
        # layer (CockpitBacktestRefProvider._REF_ALIAS in forward_ingest.py). This module only WRITES
        # backtest_summary rows; an exec twin must never write one under its own or its model's sid, so it
        # produces NO ref here (the gate alias supplies it). Non-`none` kind keeps it out of the invariant's
        # offender list while staying honest that it has no self-ref.
        return None
    raise ValueError(f"unknown backtest kind {kind!r} for {strategy_id}")
