import json
import sys
from collections import Counter
from pathlib import Path


SCRIPT_DIR = Path(__file__).resolve().parent
if str(SCRIPT_DIR) not in sys.path:
    sys.path.insert(0, str(SCRIPT_DIR))

from run_selector_demo import recommend  # noqa: E402


REPORT_NAME = "Round04_blind_routing_evaluation_report_2026-06-18.md"


def read_json(path):
    return json.loads(Path(path).read_text(encoding="utf-8"))


def load_blind_inputs(root):
    return read_json(root / "selector" / "round04_blind_inputs.json")


def selected_model_ids(result):
    return [item["model_id"] for item in result.get("selected_models", [])]


def rejected_model_ids(result):
    return [item["model_id"] for item in result.get("rejected_models", [])]


def evaluate_blind_input(root, item):
    selector_result = recommend(root, item["input_text"])
    return {
        "input_id": item["input_id"],
        "category_for_owner_review": item["category_for_owner_review"],
        "control_case_type": item.get("control_case_type"),
        "input_text": item["input_text"],
        "why_included": item.get("why_included", ""),
        "selected_models": selected_model_ids(selector_result),
        "rejected_models": rejected_model_ids(selector_result),
        "no_call": selector_result.get("no_call"),
        "routing_notes": selector_result.get("routing_notes", ""),
        "selected_model_details": selector_result.get("selected_models", []),
        "rejected_model_details": selector_result.get("rejected_models", []),
    }


def format_model_details(details):
    if not details:
        return ["  - none"]
    lines = []
    for detail in details:
        lines.append(
            f"  - `{detail['model_id']}` score={detail['score']} decision={detail['decision']}"
        )
        if detail.get("reasons"):
            lines.append("    - reasons: " + "; ".join(detail["reasons"]))
        if detail.get("penalties"):
            lines.append("    - penalties: " + "; ".join(detail["penalties"]))
    return lines


def render_report(input_set, results):
    selected_counter = Counter()
    category_counter = Counter()
    no_call_count = 0
    for result in results:
        category_counter[result["category_for_owner_review"]] += 1
        if result["no_call"]:
            no_call_count += 1
        if not result["selected_models"]:
            selected_counter["none"] += 1
        for model_id in result["selected_models"]:
            selected_counter[model_id] += 1

    lines = [
        "# Round 04 Blind Routing Evaluation Report",
        "",
        "Date: 2026-06-18",
        "",
        f"Blind input set: `{input_set['blind_input_set_id']}`",
        "",
        "Expected routing labels: `not included before first blind run`",
        "",
        "This report records current selector routing only. It does not score correctness, does not generate final answers, does not modify selector rules, and does not upgrade model status.",
        "",
        "## Scope",
        "",
        "- Round 04 target: test routing stability on new inputs.",
        "- Runtime surface: current rule-based selector plus model-level QPI / IA gates.",
        "- QPI contract status: represented here by QPI selection and routing details; no full QPI answer generation is performed.",
        "- IA status: represented here by selector selection / rejection only; no Intellectual Archaeology answer generation is performed.",
        "",
        "## Summary",
        "",
        f"Inputs evaluated: {len(results)}",
        f"No-call results: {no_call_count}",
        "",
        "### Selected Model Distribution",
        "",
    ]

    for key, count in sorted(selected_counter.items()):
        lines.append(f"- `{key}`: {count}")

    lines.extend([
        "",
        "### Coverage Categories",
        "",
    ])
    for key, count in sorted(category_counter.items()):
        lines.append(f"- `{key}`: {count}")

    lines.extend([
        "",
        "## Case Results",
        "",
    ])

    for result in results:
        lines.extend([
            f"### {result['input_id']}",
            "",
            f"- category_for_owner_review: `{result['category_for_owner_review']}`",
        ])
        if result.get("control_case_type"):
            lines.append(f"- control_case_type: `{result['control_case_type']}`")
        lines.extend([
            f"- input_text: `{result['input_text']}`",
            f"- selected_models: `{result['selected_models']}`",
            f"- rejected_models: `{result['rejected_models']}`",
            f"- no_call: `{result['no_call']}`",
            f"- routing_notes: {result['routing_notes']}",
            "",
            "Selected model details:",
        ])
        lines.extend(format_model_details(result["selected_model_details"]))
        lines.extend(["", "Rejected model details:"])
        lines.extend(format_model_details(result["rejected_model_details"]))
        lines.append("")

    lines.extend([
        "## Review Reminder",
        "",
        "This is the first blind routing output. Failure labels, expected routing, and rule changes should be added only after owner / GPT / CCRA review of these observed results.",
        "",
    ])

    return "\n".join(lines)


def write_report(root, input_set, results):
    report_path = root / "reports" / REPORT_NAME
    report_path.write_text(render_report(input_set, results), encoding="utf-8")
    return report_path


def main():
    root = Path(__file__).resolve().parents[1]
    input_set = load_blind_inputs(root)
    results = [
        evaluate_blind_input(root, item)
        for item in input_set.get("inputs", [])
    ]
    report_path = write_report(root, input_set, results)
    print(f"round04 blind routing report written to {report_path}")
    print(f"inputs evaluated: {len(results)}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
