"""Geometry and provenance behavior of the OCR grounding well.

The engine itself is exercised by the QUE-324 measurement runs, not here;
these tests pin the pure logic a consumer depends on: pixel-to-point
conversion, region scoping by overlap, and page lookup.
"""

from __future__ import annotations

import pytest

from quber.core.ocr import DocumentWell, OcrFragment, PageWell


def fragment(fid: str, bbox: tuple[float, float, float, float]) -> OcrFragment:
    return OcrFragment(id=fid, page=1, text=fid, bbox=bbox, confidence=0.9)


def test_fragments_in_box_selects_by_overlap() -> None:
    well = PageWell(
        page=1,
        image="page.png",
        dpi=300,
        width=612,
        height=792,
        fragments=[
            fragment("inside", (100, 100, 150, 120)),
            fragment("outside", (400, 400, 450, 420)),
            fragment("straddling-mostly-in", (140, 100, 210, 120)),
            fragment("straddling-mostly-out", (190, 100, 400, 120)),
        ],
    )
    region = (90, 90, 200, 200)
    got = [f.id for f in well.fragments_in_box(region)]
    assert got == ["inside", "straddling-mostly-in"]
    assert [f.id for f in well.fragments_in_box(region, min_overlap=0.01)] == [
        "inside",
        "straddling-mostly-in",
        "straddling-mostly-out",
    ]


def test_document_well_page_lookup() -> None:
    page = PageWell(page=7, image="p7.png", dpi=None, width=1700, height=2200, fragments=[])
    doc = DocumentWell(source="deck.pdf", engine="rapidocr", pages=[page])
    assert doc.page(7) is page
    with pytest.raises(KeyError):
        doc.page(8)


def test_bbox_units_follow_dpi() -> None:
    # A 300 DPI render of a letter page is 2550x3300 px; the well stores
    # points, so a fragment spanning the full width must come out at 612 pt.
    # read_image applies scale = 72/dpi; this pins the conversion factor.
    from quber.core.ocr.well import POINTS_PER_INCH

    assert POINTS_PER_INCH / 300 * 2550 == pytest.approx(612)
    assert POINTS_PER_INCH / 300 * 3300 == pytest.approx(792)
