#!/usr/bin/env python3
"""Train the classic three-round agent by self-play, then measure it."""

from __future__ import annotations

import argparse
import json
from pathlib import Path

import jax

from lost_cities_jax.match_eval import carry_probe, match_evaluate
from lost_cities_jax.match_ppo import create_match_train_state, match_train
from lost_cities_jax.ppo import load_config, restore_checkpoint


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("--config", default="configs/jax_ppo/match-selfplay.yaml")
    parser.add_argument("--eval-only", type=Path, default=None)
    parser.add_argument("--matches", type=int, default=1024)
    parser.add_argument("--set", action="append", default=[])
    args = parser.parse_args()

    cfg = load_config(args.config)
    for override in args.set:
        path, _, raw = override.partition("=")
        section, _, field = path.partition(".")
        target = getattr(cfg, section)
        current = getattr(target, field)
        value = type(current)(raw) if not isinstance(current, bool) else raw == "true"
        setattr(target, field, value)

    if args.eval_only is None:
        run_dir = match_train(cfg)
        checkpoint = run_dir / "latest"
    else:
        checkpoint = args.eval_only

    state = create_match_train_state(cfg, jax.random.PRNGKey(0))
    state = restore_checkpoint(Path(checkpoint), state)

    result = match_evaluate(cfg, state.params, matches=args.matches)
    print("\n== duplicate match eval (self-play) ==")
    print(json.dumps(result, indent=2, sort_keys=True))

    print("\n== carry probe: does round-three play react to the deficit? ==")
    rows = carry_probe(cfg, state.params, matches=args.matches // 2)
    header = f"{'carry':>7}{'win_rate':>10}{'opened':>9}{'wagers':>9}{'deck_race':>11}{'plies':>8}"
    print(header)
    for row in rows:
        print(
            f"{row['carry']:>7}{row['win_rate']:>10.3f}{row['opened_colors']:>9.2f}"
            f"{row['wagers_played']:>9.2f}{row['deck_race_rate']:>11.3f}{row['mean_plies']:>8.0f}"
        )
    Path(checkpoint).parent.joinpath("carry_probe.json").write_text(
        json.dumps({"eval": result, "probe": rows}, indent=2, sort_keys=True)
    )


if __name__ == "__main__":
    main()
