"""Tests for #133 / FU-5 — captured-mode calibration of the halacha panel.

Covers the PURE helpers in scripts/halacha_panel_calibrate.py
(summarize_calibration, bucket_by_round): from captured (panel ⋈ chair) pairs
they must report the split-rate and auto-precision the panel ACTUALLY delivered
against the chair's ground-truth, and break it down per round-day so the loop's
trend is visible. Fully OFFLINE (no DB, no LLM, no re-voting).
"""

from __future__ import annotations

import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "scripts"))
import halacha_panel_calibrate as cal  # noqa: E402


def _pair(chair, verdict, action, ts="2026-06-12T04:00:00Z"):
    # judge votes are irrelevant to split-rate/precision here; keep them aligned
    return {
        "chair_keep": chair, "verdict": verdict, "applied_action": action,
        "round_ts": ts, "rule_statement": "r",
        "claude_vote": chair, "claude_reason": "",
        "deepseek_vote": chair, "deepseek_reason": "",
        "gemini_vote": chair, "gemini_reason": "",
    }


def test_split_rate_and_precision():
    pairs = [
        _pair(True, "unanimous_yes", "approved"),   # auto-correct
        _pair(False, "unanimous_no", "rejected"),   # auto-correct
        _pair(False, "unanimous_yes", "approved"),  # auto WRONG (false-keep)
        _pair(True, "split", "chair"),              # escalated
    ]
    s = cal.summarize_calibration(pairs)
    assert s["n"] == 4
    assert s["escalated"] == 1
    assert s["auto_decided"] == 3
    assert s["split_rate"] == 0.25
    # 3 auto-decisions, 1 wrong (false-keep) → precision 2/3
    assert s["false_keep"] == 1 and s["false_drop"] == 0
    assert round(s["auto_precision"], 2) == 0.67


def test_empty_pairs_safe():
    s = cal.summarize_calibration([])
    assert s["n"] == 0
    assert s["split_rate"] is None and s["auto_precision"] is None


def test_unlabeled_pairs_filtered():
    s = cal.summarize_calibration([_pair(None, "split", "chair")])
    assert s["n"] == 0  # chair=None contributes no calibration signal


def test_bucket_by_round_trend():
    pairs = [
        _pair(True, "unanimous_yes", "approved", ts="2026-06-10T04:00:00Z"),
        _pair(False, "split", "chair", ts="2026-06-10T04:00:00Z"),
        _pair(True, "unanimous_yes", "approved", ts="2026-06-12T05:00:00Z"),
    ]
    trend = cal.bucket_by_round(pairs)
    days = [d for d, _ in trend]
    assert days == ["2026-06-10", "2026-06-12"]  # sorted by day
    assert trend[0][1]["n"] == 2 and trend[0][1]["split_rate"] == 0.5
    assert trend[1][1]["n"] == 1 and trend[1][1]["split_rate"] == 0.0


def test_missing_round_ts_bucketed_unknown():
    p = _pair(True, "unanimous_yes", "approved")
    del p["round_ts"]
    trend = cal.bucket_by_round([p])
    assert trend[0][0] == "unknown"
