"""Verify that the synthetic PDFs actually reproduce the Set-of-Mark over-merge.

Runs the real grid locator (the agent the pipeline uses) over each synthetic
page and reports how many regions it returns. The defect is reproduced when the
locator returns FEWER regions than the number of stacked blocks — i.e. it fused
the blocks into one region. If it returns one region per block, the synthetic
still gives the locator enough separation to split and is not a valid fixture.

Requires the api backend (ANTHROPIC_AUTH_TOKEN in .env):
  QUBER_LLM_BACKEND=api uv run python experiments/que262/verify_overmerge.py
"""

from __future__ import annotations

import asyncio
import json
import os
import tempfile
from pathlib import Path

from quber.agents.grid_locator import get_grid_locator
from quber.core.extractors.set_of_mark.split import render_page


async def verify(pdf: Path) -> None:
    spec = json.loads(pdf.with_suffix(".boxes.json").read_text())
    expected = spec["count"]
    locator = get_grid_locator()
    with tempfile.TemporaryDirectory() as tmp:
        page_image, _w, _h = render_page(pdf, 1, 200, Path(tmp))
        located = await locator.locate(page_image, pdf, 1)

    print(
        f"\n{pdf.name}: {len(spec['boundaries'])} stacked blocks present; locator returned {len(located)} region(s)"
    )
    for t in located:
        region = tuple(round(v, 3) for v in t.region)
        print(f"    region ordinal={t.ordinal} title={t.title!r} box={region}")
    if len(located) < expected:
        print(f"    => OVER-MERGE REPRODUCED (fused {expected} blocks into {len(located)} region(s))")
    else:
        print(f"    => not fused; locator separated them ({len(located)} regions) — not a valid fixture yet")


async def main() -> None:
    if os.environ.get("QUBER_LLM_BACKEND") != "api":
        raise SystemExit("Set QUBER_LLM_BACKEND=api (real locator agent; no mock).")
    here = Path(__file__).parent
    for name in ("synthetic_2stack.pdf", "synthetic_3stack.pdf"):
        await verify(here / name)


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