"""Evidence that production grid_locator now emits the QUE-245-decision boxes.

Runs the wired production PydanticAIGridLocator (anatomy prompt, 36-row grid,
6pt pad, declash) over the corpus and compares its boxes to the spike's pad6
reference (declash(pad6(raw model output)) from compare_finishings). Reports
per-page table-count agreement and IoU, and writes a production-boxed PDF per
document for visual confirmation against finish_pad6.pdf.
"""

from __future__ import annotations

import asyncio
import json
import tempfile
from pathlib import Path

import fitz

from experiments.que245.compare_finishings import _located_from, apply_finishing
from experiments.que245.score import match
from quber.agents.grid_locator import PydanticAIGridLocator

RENDER = Path("experiments/que245/render")
CACHE = Path("experiments/que245/results/raw_located.json")
DOCS = [
    Path("documents/BHE_991.pdf"),
    Path("documents/Q2FY25-Visa-Operational-Performance-Data-FINAL.pdf"),
    Path("documents/TMUS_Q225_991.pdf"),
]


async def main():
    raw = json.loads(CACHE.read_text())
    loc = PydanticAIGridLocator()  # production defaults = QUE-245 decision
    print(f"production locator: rows={loc.rows} cols={loc.cols} model={loc.model}")

    total_pages = match_count = 0
    ious = []
    for pdf in DOCS:
        doc = fitz.open(str(pdf))
        out = fitz.open()
        print(f"\n{pdf.stem}")
        for pno in range(doc.page_count):
            page = doc[pno]
            w, h = page.rect.width, page.rect.height
            with tempfile.TemporaryDirectory() as t:
                ip = Path(t) / "p.png"
                page.get_pixmap(dpi=200).save(str(ip))
                prod = await loc.locate(ip, pdf, pno + 1)
            prod_boxes = [tt.region for tt in prod]

            from quber.agents.completeness import page_words
            _, _, words = page_words(pdf, pno + 1)
            ref_loc = apply_finishing("pad6", _located_from(raw.get(f"{pdf.stem}|{pno+1}", [])), words, w, h)
            ref_boxes = [tt.region for tt in ref_loc]

            total_pages += 1
            cm = len(prod_boxes) == len(ref_boxes)
            match_count += int(cm)
            page_ious = [v for _, pj, v in match(ref_boxes, prod_boxes) if pj is not None]
            ious.extend(page_ious)
            mean_iou = sum(page_ious) / len(page_ious) if page_ious else (1.0 if not ref_boxes else 0.0)
            print(f"  p{pno+1}: prod={len(prod_boxes)} ref={len(ref_boxes)} "
                  f"{'OK ' if cm else 'DIFF'} meanIoU={mean_iou:.2f}")

            col = (0.0, 0.32, 0.92)
            for tt in prod:
                x0, y0, x1, y1 = tt.region
                rect = fitz.Rect(min(x0, x1) * w, min(y0, y1) * h, max(x0, x1) * w, max(y0, y1) * h)
                page.draw_rect(rect, color=col, width=1.4)
                page.insert_text((rect.x0 + 2, max(8, rect.y0 - 3)), f"{tt.ordinal}: {tt.title}", fontsize=6, color=col)
            out.insert_pdf(doc, from_page=pno, to_page=pno)
        outp = RENDER / f"production_{pdf.stem[:24]}.pdf"
        out.save(str(outp))
        print(f"  saved {outp}")

    macro = sum(ious) / len(ious) if ious else 0.0
    print(f"\n=== count-agreement: {match_count}/{total_pages} pages | matched-box IoU vs pad6 ref: {macro:.3f} ===")


if __name__ == "__main__":
    asyncio.run(main())
