#!/usr/bin/env python3
from __future__ import annotations

import argparse
import json
from pathlib import Path

import pandas as pd

from validate_targeted_candidates import evaluate_candidate


def shortlist(df: pd.DataFrame, top_n: int) -> pd.DataFrame:
    a = df[df['bet_count'] >= 25].sort_values(['bet_acc', 'bet_count', 'test_acc'], ascending=[False, False, False]).head(top_n)
    b = df.sort_values(['bet_acc', 'bet_count', 'test_acc'], ascending=[False, False, False]).head(top_n)
    out = pd.concat([a, b], ignore_index=True).drop_duplicates(subset=['feature_mode', 'feature_set', 'train_window', 'model_name', 'threshold'])
    return out.reset_index(drop=True)


def main() -> None:
    parser = argparse.ArgumentParser(description='Run stability validation on shortlisted candidates for arbitrary leagues.')
    parser.add_argument('--input-dir', type=Path, required=True)
    parser.add_argument('--codes', nargs='+', required=True)
    parser.add_argument('--top-n', type=int, default=12)
    args = parser.parse_args()

    summary = {}
    for code in args.codes:
        src = pd.read_csv(args.input_dir / f'{code}_search_results.csv')
        candidates = shortlist(src, args.top_n)
        rows = []
        for _, row in candidates.iterrows():
            row = row.copy()
            row['candidate_name'] = row.get('candidate_name', f"{code}_{len(rows)+1}")
            result = evaluate_candidate(code, row)
            fold_df = pd.DataFrame([r.__dict__ for r in result['folds']])
            if not fold_df.empty:
                fold_df.to_csv(args.input_dir / f"{row['candidate_name']}_folds.csv", index=False, encoding='utf-8-sig')
            rows.append({
                'candidate_name': row['candidate_name'],
                'stable': result['stable'],
                'mean_bet_acc': result['mean_bet_acc'],
                'min_bet_acc': result['min_bet_acc'],
                'total_bet_count': result['total_bet_count'],
                'single_split_bet_acc': float(row['bet_acc']),
                'single_split_bet_count': int(row['bet_count']),
                'feature_mode': row['feature_mode'],
                'feature_set': row['feature_set'],
                'train_window': row['train_window'],
                'model_name': row['model_name'],
                'threshold': float(row['threshold']),
            })
        out = pd.DataFrame(rows).sort_values(['stable', 'mean_bet_acc', 'min_bet_acc', 'total_bet_count'], ascending=[False, False, False, False])
        out.to_csv(args.input_dir / f'{code}_stable_search_summary.csv', index=False, encoding='utf-8-sig')
        summary[code] = out.head(20).to_dict(orient='records')
    (args.input_dir / 'stable_search_summary.json').write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding='utf-8')
    print(json.dumps(summary, ensure_ascii=False, indent=2))


if __name__ == '__main__':
    main()
