"""Test chandra-ocr-2 HTML parsing in VLM pipeline."""

from pathlib import Path

from docling_core.types.doc import DocItemLabel, DoclingDocument, Size

from docling.utils.chandra_utils import parse_chandra_html


def get_chandra_test_paths():
    """Get all chandra HTML test files."""
    directory = Path("./tests/data/html_chandra/sources/")
    return sorted(directory.glob("*.html"))


def test_chandra_simple_parsing():
    """Test chandra HTML parsing produces expected document structure."""
    path = Path("./tests/data/html_chandra/sources/chandra_simple.html")
    content = path.read_text()
    source = path.with_suffix(".source.txt").read_text()

    doc = parse_chandra_html(
        content=content,
        original_page_size=Size(width=612, height=792),
        page_no=1,
        filename="chandra_simple.html",
    )

    assert isinstance(doc, DoclingDocument)
    assert len(doc.texts) > 0, "Should have text elements"

    labels = [
        t.label.value if hasattr(t.label, "value") else str(t.label) for t in doc.texts
    ]
    assert "section_header" in labels, "Should have section headers"
    assert "caption" in labels, "Should have caption"
    assert "page_header" in labels, "Should have page header"

    assert "tests/data/pdf/2305.03393v1-pg9.pdf, page 1" in source
    assert len(doc.tables) > 0, "Should have table elements"

    for item in doc.texts:
        assert len(item.prov) > 0, "Text item should have provenance"
        bbox = item.prov[0].bbox
        assert bbox is not None, "Should have bbox"
        assert bbox.l >= 0 and bbox.t >= 0, "Bbox coords should be non-negative"


def test_chandra_multiblock_parsing():
    """Test chandra parsing with a saved figure prediction."""
    path = Path("./tests/data/html_chandra/sources/chandra_multiblock.html")
    content = path.read_text()
    source = path.with_suffix(".source.txt").read_text()

    doc = parse_chandra_html(
        content=content,
        original_page_size=Size(width=612, height=792),
        page_no=1,
        filename="chandra_multiblock.html",
    )

    labels = [
        t.label.value if hasattr(t.label, "value") else str(t.label) for t in doc.texts
    ]
    assert "section_header" in labels, "Should have section header"
    assert "caption" in labels, "Should have caption"
    assert "page_footer" in labels, "Should have page footer"

    assert "tests/data/pdf/picture_classification.pdf, page 1" in source
    assert len(doc.pictures) > 0, "Should have picture/image elements"


def test_chandra_bbox_normalization():
    """Test that chandra bboxes (normalized 0-1000) map to page coordinates."""
    content = '<div data-bbox="0 0 1000 1000" data-label="Text"><p>full page</p></div>'

    doc = parse_chandra_html(
        content=content,
        original_page_size=Size(width=612, height=792),
        page_no=1,
        filename="test.html",
    )

    assert len(doc.texts) == 1
    bbox = doc.texts[0].prov[0].bbox
    assert abs(bbox.r - 612) < 1, f"Right edge should map to page width, got {bbox.r}"
    assert abs(bbox.b - 792) < 1, f"Bottom edge should map to page height, got {bbox.b}"


def test_chandra_empty_content():
    """Test that empty/whitespace content returns empty doc."""
    for content in ["", "   ", "\n\t"]:
        doc = parse_chandra_html(
            content=content,
            original_page_size=Size(width=612, height=792),
            page_no=1,
            filename="empty.html",
        )
        assert isinstance(doc, DoclingDocument)
        assert len(doc.texts) == 0


def test_chandra_malformed_divs():
    """Test graceful handling of divs with missing or bad attributes."""
    content = (
        '<div data-label="Text"><p>no bbox</p></div>'
        '<div data-bbox="0 0 500 500"><p>no label</p></div>'
        '<div data-bbox="bad coords" data-label="Text"><p>bad</p></div>'
        '<div data-bbox="0 0 500" data-label="Text"><p>incomplete</p></div>'
    )
    doc = parse_chandra_html(
        content=content,
        original_page_size=Size(width=612, height=792),
        page_no=1,
        filename="malformed.html",
    )
    assert isinstance(doc, DoclingDocument)
    assert len(doc.texts) == 0


def test_chandra_unknown_label_fallback():
    """Test that unknown labels fall back to TEXT."""
    content = '<div data-bbox="100 100 200 200" data-label="UnknownType"><p>fallback</p></div>'
    doc = parse_chandra_html(
        content=content,
        original_page_size=Size(width=612, height=792),
        page_no=1,
        filename="unknown.html",
    )
    assert len(doc.texts) == 1
    labels = [
        t.label.value if hasattr(t.label, "value") else str(t.label) for t in doc.texts
    ]
    assert "text" in labels


def test_chandra_table_parsing():
    """Test that Table elements use HTML table parser."""
    content = (
        '<div data-bbox="50 50 500 300" data-label="Table">'
        "<table><tr><th>Header</th></tr><tr><td>Cell</td></tr></table>"
        "</div>"
    )
    doc = parse_chandra_html(
        content=content,
        original_page_size=Size(width=612, height=792),
        page_no=1,
        filename="table.html",
    )
    assert len(doc.tables) == 1


def test_chandra_list_group_prediction_sample():
    """Test a saved chandra prediction containing list groups."""
    path = Path("./tests/data/html_chandra/sources/chandra_list_group.html")
    content = path.read_text()
    source = path.with_suffix(".source.txt").read_text()

    doc = parse_chandra_html(
        content=content,
        original_page_size=Size(width=612, height=792),
        page_no=1,
        filename=path.name,
    )

    list_items = [item for item in doc.texts if item.label == DocItemLabel.LIST_ITEM]

    assert "tests/data/pdf/multi_page.pdf, page 1" in source
    assert len(list_items) == 4
    assert "IBM MT/ST" in list_items[0].text
    assert "Wang Laboratories" in list_items[1].text
    assert "WordStar" in list_items[2].text
    assert "Microsoft Word" in list_items[3].text


def test_chandra_all_files_parse():
    """Ensure all chandra test files parse without errors."""
    for path in get_chandra_test_paths():
        content = path.read_text()
        doc = parse_chandra_html(
            content=content,
            original_page_size=Size(width=612, height=792),
            page_no=1,
            filename=path.name,
        )
        assert isinstance(doc, DoclingDocument), f"Failed to parse {path.name}"
        assert len(doc.texts) + len(doc.tables) + len(doc.pictures) > 0, (
            f"No elements parsed from {path.name}"
        )
