from __future__ import annotations

import argparse
import json
from pathlib import Path
from typing import Any
import yaml


ROOT = Path(__file__).resolve().parents[1]
DEFAULT_HIST = ROOT / "Temp" / "proposal_evaluation_history.json"
DEFAULT_OUT = ROOT / "Temp" / "short_horizon_outcome_monitor_v1.json"
DEFAULT_POLICY = ROOT / "spec" / "strategy_execution_lock_policy.yaml"


def _load(path: Path) -> dict[str, Any]:
    if not path.exists():
        return {}
    try:
        payload = json.loads(path.read_text(encoding="utf-8"))
    except Exception:
        return {}
    return payload if isinstance(payload, dict) else {}


def _summary_rate(node: dict[str, Any]) -> tuple[int, float]:
    eval_cnt = int(node.get("evaluated_count") or 0)
    match_rate = float(node.get("match_rate_pct") or 0.0) if eval_cnt > 0 else 0.0
    return eval_cnt, match_rate


def _load_policy(path: Path) -> dict[str, Any]:
    if not path.exists():
        return {}
    try:
        payload = yaml.safe_load(path.read_text(encoding="utf-8"))
    except Exception:
        return {}
    root = payload.get("strategy_execution_lock_policy") if isinstance(payload, dict) else {}
    obj = root.get("short_horizon_outcome_monitor_v1") if isinstance(root, dict) else {}
    return obj if isinstance(obj, dict) else {}


def main() -> int:
    ap = argparse.ArgumentParser()
    ap.add_argument("--history", default=str(DEFAULT_HIST))
    ap.add_argument("--out", default=str(DEFAULT_OUT))
    ap.add_argument("--policy", default=str(DEFAULT_POLICY))
    args = ap.parse_args()

    hist_path = Path(args.history)
    out_path = Path(args.out)
    policy_path = Path(args.policy)
    if not hist_path.is_absolute():
        hist_path = ROOT / hist_path
    if not out_path.is_absolute():
        out_path = ROOT / out_path
    if not policy_path.is_absolute():
        policy_path = ROOT / policy_path

    h = _load(hist_path)
    pol = _load_policy(policy_path)
    s = h.get("summary") if isinstance(h.get("summary"), dict) else {}
    t1 = s.get("t1_horizon") if isinstance(s.get("t1_horizon"), dict) else {}
    t5 = s.get("t5_horizon") if isinstance(s.get("t5_horizon"), dict) else {}

    t1_n, t1_rate = _summary_rate(t1)
    t5_n, t5_rate = _summary_rate(t5)
    combined_n = t1_n + t5_n
    combined_score = round((t1_rate * 0.5) + (t5_rate * 0.5), 2) if combined_n > 0 else 0.0
    min_samples = int(pol.get("min_samples_data_insufficient") or 20)
    low_conf_samples = int(pol.get("low_conf_samples_threshold") or 40)
    pass_score = float(pol.get("pass_score_threshold") or 60.0)
    if combined_n < min_samples:
        gate = "DATA_INSUFFICIENT"
    elif combined_n < low_conf_samples:
        gate = "LOW_CONFIDENCE"
    else:
        gate = "PASS" if combined_score >= pass_score else "CAUTION"

    result = {
        "formula_id": "SHORT_HORIZON_OUTCOME_MONITOR_V1",
        "usage": "MONITOR_ONLY",
        "order_lock_binding": False,
        "metrics": {
            "t1_evaluated_count": t1_n,
            "t1_match_rate_pct": t1_rate,
            "t5_evaluated_count": t5_n,
            "t5_match_rate_pct": t5_rate,
            "combined_evaluated_count": combined_n,
            "combined_score": combined_score,
        },
        "policy_used": {
            "policy_path": str(policy_path),
            "min_samples_data_insufficient": min_samples,
            "low_conf_samples_threshold": low_conf_samples,
            "pass_score_threshold": pass_score,
        },
        "gate": gate,
    }
    out_path.parent.mkdir(parents=True, exist_ok=True)
    out_path.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
    print(json.dumps(result, ensure_ascii=False, indent=2))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
