"""Text-layer extraction, evidence bbox matching, and crop rendering."""

import os

import pytest

fitz = pytest.importorskip("pymupdf")

from backend import config
from backend.text_layer import (
    attach_text_layers,
    coverage_gaps,
    extract_text_layers,
    find_evidence_bbox,
    render_crop,
)

EVIDENCE = "(5) 2X6 STUD PACK @ 16 IN O.C."


def _make_pdf(path, pages):
    """pages: list of str ('' = effectively blank page)."""
    doc = fitz.open()
    for text in pages:
        page = doc.new_page(width=612, height=792)
        if text:
            page.insert_text((72, 72), text, fontsize=11)
    doc.save(str(path))
    doc.close()
    return str(path)


@pytest.fixture
def text_pdf(tmp_path):
    return _make_pdf(tmp_path / "set.pdf", [EVIDENCE, ""])


def test_extract_text_layers(text_pdf):
    layers = extract_text_layers(text_pdf)
    assert set(layers) == {1, 2}
    assert layers[1]["has_text_layer"] is True
    assert "2X6 STUD PACK" in layers[1]["text"]
    assert layers[1]["words"], "expected word-level bboxes"
    assert all("bbox" in w and len(w["bbox"]) == 4 for w in layers[1]["words"])


def test_blank_page_below_min_chars(text_pdf):
    layers = extract_text_layers(text_pdf)
    assert layers[2]["has_text_layer"] is False


def test_disabled_returns_empty(text_pdf, monkeypatch):
    monkeypatch.setattr(config, "TEXT_LAYER_ENABLED", False)
    assert extract_text_layers(text_pdf) == {}


def test_attach_text_layers(text_pdf, tmp_path):
    pages = [{"page_number": 1}, {"page_number": 2}]
    words = attach_text_layers(text_pdf, pages,
                               text_dir=str(tmp_path / "text"))
    assert pages[0]["text_layer"] and "STUD PACK" in pages[0]["text_layer"]
    assert pages[1]["text_layer"] is None
    assert words[1] and not words[2]
    assert os.path.isfile(tmp_path / "text" / "page-001.txt")
    assert not os.path.exists(tmp_path / "text" / "page-002.txt")


def test_find_evidence_bbox_exact(text_pdf):
    words = extract_text_layers(text_pdf)[1]["words"]
    bbox = find_evidence_bbox(words, EVIDENCE)
    assert bbox is not None
    assert bbox[2] > bbox[0] and bbox[3] > bbox[1]


def test_find_evidence_bbox_fuzzy(text_pdf):
    # Vision quotes imperfectly: wrong count token, rest exact.
    words = extract_text_layers(text_pdf)[1]["words"]
    bbox = find_evidence_bbox(words, "(2) 2X6 STUD PACK @ 16 IN O.C.")
    assert bbox is not None


def test_find_evidence_bbox_miss(text_pdf):
    words = extract_text_layers(text_pdf)[1]["words"]
    assert find_evidence_bbox(words, "PENTHOUSE EXHAUST FAN EF-9") is None
    assert find_evidence_bbox([], EVIDENCE) is None
    assert find_evidence_bbox(words, "") is None


def test_render_crop(text_pdf):
    words = extract_text_layers(text_pdf)[1]["words"]
    bbox = find_evidence_bbox(words, EVIDENCE)
    crop = render_crop(text_pdf, 1, bbox)
    assert crop is not None
    # Decodes as an image of plausible size (margin around the text line).
    doc = fitz.open(stream=crop, filetype="jpeg")
    pix = doc[0].get_pixmap()
    assert pix.width > 100 and pix.height > 20
    doc.close()


def test_render_crop_bad_page(text_pdf):
    assert render_crop(text_pdf, 99, (0, 0, 10, 10)) is None


def test_coverage_gaps():
    pages = [{"page_number": 1, "text_layer": "some real text"},
             {"page_number": 2, "text_layer": "more text"},
             {"page_number": 3, "text_layer": None}]
    sheets = [{"page_number": 1, "assertions": [{"id": "a"}]},
              {"page_number": 2, "assertions": []}]
    assert coverage_gaps(pages, sheets) == [2]
