"""
Report generation for Clew-Bench experiment results.

Produces both human-readable text reports and machine-readable JSON.
"""

from __future__ import annotations

import json
from pathlib import Path

from .models import ExperimentResult

# ADR-006 success thresholds
COMPRESSION_TARGET = 10.0  # 10x token compression
HALLUCINATION_TARGET = 0.05  # <5% hallucination rate
REFACTOR_TARGET = 1.0  # 100% refactor success


def _format_token_usage(result: ExperimentResult) -> list[str]:
    lines = ["TOKEN USAGE", "-" * 40]
    lines.append(f"  Control (RAG):  {result.control.total_input_tokens:>10,} input tokens")
    lines.append(f"  Test (Clew):    {result.test.total_input_tokens:>10,} input tokens")

    if result.test.total_input_tokens > 0:
        ratio = result.compression_ratio
        pct = result.compression_pct
        status = "PASS" if ratio >= COMPRESSION_TARGET else "FAIL"
        lines.append(f"  Compression:    {ratio:>10.1f}x ({pct:.1f}% fewer tokens)  [{status}]")
        lines.append(f"  Target:         {COMPRESSION_TARGET:.0f}x")
    else:
        lines.append("  Compression:    N/A (no test tokens)")
    lines.append("")
    return lines


def _format_context_bloat(result: ExperimentResult) -> list[str]:
    lines = ["CONTEXT BLOAT CURVE (tokens per ticket)", "-" * 40]
    control_ctx = result.control.context_tokens_per_ticket
    test_ctx = result.test.context_tokens_per_ticket
    for i, (c, t) in enumerate(zip(control_ctx, test_ctx, strict=False)):
        # Handle case where ticket_results might be empty or mismatched length (though strictly shouldn't be)
        ticket_id = result.control.ticket_results[i].ticket_id if i < len(result.control.ticket_results) else f"T-{i}"
        lines.append(f"  {ticket_id}:  RAG={c:>6,}  Clew={t:>6,}")
    lines.append("")
    return lines


def _format_quality_scores(result: ExperimentResult) -> list[str]:
    lines = ["QUALITY SCORES (avg 1-5)", "-" * 40]
    lines.append(f"  Control (RAG):  {result.control.mean_quality:>6.2f}")
    lines.append(f"  Test (Clew):    {result.test.mean_quality:>6.2f}")
    lines.append("")
    return lines


def _format_hallucination_rate(result: ExperimentResult) -> list[str]:
    lines = ["HALLUCINATION RATE", "-" * 40]
    c_rate = result.control.hallucination_rate
    t_rate = result.test.hallucination_rate
    t_status = "PASS" if t_rate <= HALLUCINATION_TARGET else "FAIL"
    lines.append(f"  Control (RAG):  {result.control.hallucination_count} total ({c_rate:.1%})")
    lines.append(f"  Test (Clew):    {result.test.hallucination_count} total ({t_rate:.1%})  [{t_status}]")
    lines.append(f"  Target:         <{HALLUCINATION_TARGET:.0%}")
    lines.append("")
    return lines


def _format_refactor_success(result: ExperimentResult) -> list[str]:
    lines = ["REFACTOR SUCCESS (trap tickets)", "-" * 40]
    c_total = result.control.refactor_total
    t_total = result.test.refactor_total

    if t_total > 0:
        t_rate_r = result.test.refactor_successes / t_total  # noqa: F841
        r_status = "PASS" if result.test.refactor_successes / t_total >= REFACTOR_TARGET else "FAIL"
    else:
        r_status = "N/A"

    lines.append(f"  Control (RAG):  {result.control.refactor_successes}/{c_total}")
    lines.append(f"  Test (Clew):    {result.test.refactor_successes}/{t_total}  [{r_status}]")
    lines.append("  Target:         100%")
    lines.append("")
    return lines


def _format_verdict(result: ExperimentResult) -> list[str]:
    sep = "=" * 60
    lines = [sep]

    compression_pass = result.compression_ratio >= COMPRESSION_TARGET if result.test.total_input_tokens > 0 else False
    hallucination_pass = result.test.hallucination_rate <= HALLUCINATION_TARGET
    refactor_pass = (
        (result.test.refactor_successes / result.test.refactor_total >= REFACTOR_TARGET)
        if result.test.refactor_total > 0
        else True
    )

    if compression_pass and hallucination_pass and refactor_pass:
        lines.append("VERDICT: ALL TARGETS MET -- Phase 3 investment validated.")
    else:
        lines.append("VERDICT: TARGETS NOT MET -- Review before Phase 3.")
        if not compression_pass:
            lines.append(f"  - Compression {result.compression_ratio:.1f}x < {COMPRESSION_TARGET:.0f}x target")
        if not hallucination_pass:
            lines.append(
                f"  - Hallucination rate {result.test.hallucination_rate:.1%} > {HALLUCINATION_TARGET:.0%} target"
            )
        if not refactor_pass:
            lines.append(
                f"  - Refactor success {result.test.refactor_successes}/{result.test.refactor_total} < 100% target"
            )

    lines.append(sep)
    return lines


def format_text_report(result: ExperimentResult) -> str:
    """Generate a human-readable text report."""
    sep = "=" * 60
    lines: list[str] = [
        sep,
        "CLEW-BENCH RESULTS",
        sep,
        f"Workload: {result.workload_id}",
        f"Trial:    {result.trial_number}",
        "",
    ]

    lines.extend(_format_token_usage(result))
    lines.extend(_format_context_bloat(result))
    lines.extend(_format_quality_scores(result))
    lines.extend(_format_hallucination_rate(result))
    lines.extend(_format_refactor_success(result))
    lines.extend(_format_verdict(result))

    return "\n".join(lines)


def write_json_report(result: ExperimentResult, path: str | Path) -> None:
    """Write experiment results to a JSON file."""
    path = Path(path)
    path.parent.mkdir(parents=True, exist_ok=True)
    with open(path, "w") as f:
        json.dump(result.to_dict(), f, indent=2)


def write_text_report(result: ExperimentResult, path: str | Path) -> None:
    """Write experiment results to a text file."""
    path = Path(path)
    path.parent.mkdir(parents=True, exist_ok=True)
    with open(path, "w") as f:
        f.write(format_text_report(result))
