"""Describe frozen chronological results; never select or modify models.

Uncertainty rule fixed before results: 1,000 within-period moving-block draws,
30 calendar days per block, seed 20260921. Intervals describe sensitivity to
these observed days, not feature-vintage validity or repeated-search error.
"""
from __future__ import annotations

import argparse
import json
from pathlib import Path

import numpy as np
import pandas as pd


def summarize(folder: Path) -> dict:
    result = json.loads((folder / 'results.json').read_text())
    if result['status'] != 'complete':
        raise ValueError('Only complete frozen comparisons may be summarized')
    metrics = pd.DataFrame(result['rows'])
    daily = pd.read_csv(folder / 'daily_returns.csv', index_col=0)
    years = sorted(metrics.year.unique())
    rows = []
    for arm in ('expanding', 'three_year', 'five_year'):
        candidate = metrics[metrics.arm == arm].set_index('year').loc[years]
        trend = metrics[metrics.arm == 'trend'].set_index('year').loc[years]
        gross = float(np.prod(1 + candidate.pnl_pct / 100))
        benchmark = float(np.prod(1 + trend.pnl_pct / 100))
        wins = int((candidate.pnl_pct > trend.pnl_pct).sum())
        coverage = bool((candidate.exits >= 3).all())
        # Paired blocks retain contemporaneous market moves; resample each
        # outer period separately rather than pretending the four are IID.
        rng = np.random.default_rng(20260921)
        distributions = np.zeros(1000)
        for year in years:
            pair = daily[[f'{year}_{arm}', f'{year}_trend']].dropna()
            log_relative = (np.log1p(pair.iloc[:, 0]) - np.log1p(pair.iloc[:, 1])).to_numpy()
            if not len(log_relative) or not np.isfinite(log_relative).all():
                raise ValueError('Invalid paired daily returns')
            block = min(30, len(log_relative))
            for i in range(1000):
                starts = rng.integers(0, len(log_relative) - block + 1,
                                      size=int(np.ceil(len(log_relative) / block)))
                sample = np.concatenate([log_relative[s:s + block] for s in starts])[:len(log_relative)]
                distributions[i] += sample.sum()
        low, high = np.expm1(np.quantile(distributions, [.025, .975])) * 100
        rows.append(dict(arm=arm, chained_return_pct=(gross - 1) * 100,
                         trend_chained_return_pct=(benchmark - 1) * 100,
                         excess_return_percentage_points=(gross - benchmark) * 100,
                         relative_wealth_pct=(gross / benchmark - 1) * 100,
                         relative_wealth_block_interval_low_pct=float(low),
                         relative_wealth_block_interval_high_pct=float(high),
                         period_wins=wins, completed_trades=int(candidate.exits.sum()),
                         every_period_three_completed_trades=coverage,
                         decision=('inconclusive_coverage' if not coverage else
                                   'promising_retrospective_only' if gross > benchmark and wins >= 3
                                   else 'advantage_not_demonstrated')))
    summary = dict(method='1000 paired within-period moving-block draws, 30 days, seed20260921',
                   caveat='Descriptive uncertainty; not adjusted for repeated historical inspection or revised features.',
                   rows=rows)
    (folder / 'decision_summary.json').write_text(json.dumps(summary, indent=2) + '\n')
    pd.DataFrame(rows).to_csv(folder / 'decision_summary.csv', index=False)
    print(pd.DataFrame(rows).to_string(index=False))
    return summary


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('folder', type=Path)
    summarize(parser.parse_args().folder)
