from pathlib import Path

from pdf_to_md_local import cli
from pdf_to_md_local.converter import ConversionCancelled, download_filename, normalize_markdown, raise_if_cancelled, write_quality_report
from pdf_to_md_local.models import ConversionResult


def test_normalize_markdown_adds_metadata_and_page_boundary():
    markdown = normalize_markdown("Example.pdf", ["Xin chào", "Trang hai"], ["manual_review_required"])

    assert markdown.startswith("---\nsource_file: Example.pdf\n")
    assert "## Page 1" in markdown
    assert "Xin chào" in markdown
    assert "manual_review_required" in markdown


def test_write_quality_report_creates_json(tmp_path):
    path = write_quality_report(tmp_path, {"status": "ok", "page_count": 1})

    assert Path(path).exists()
    assert Path(path).read_text(encoding="utf-8").startswith("{\n")


def test_cli_configures_stdout_as_utf8(monkeypatch):
    class FakeStdout:
        def __init__(self):
            self.kwargs = None

        def reconfigure(self, **kwargs):
            self.kwargs = kwargs

    fake = FakeStdout()
    monkeypatch.setattr(cli.sys, "stdout", fake)

    cli.configure_stdout_utf8()

    assert fake.kwargs == {"encoding": "utf-8"}


def test_download_filename_uses_pdf_stem():
    assert download_filename("Sở Nông nghiệp và MT.pdf") == "Sở Nông nghiệp và MT for AI.md"


def test_conversion_result_serializes_markdown_download_payload():
    result = ConversionResult(
        "ok",
        "job123",
        "local_ocr",
        "C:/out/Example for AI.md",
        "C:/out/report.json",
        "C:/out/log.json",
        [],
        {"status": "ok"},
        markdown="## Page 1\n\nXin chào",
        markdown_filename="Example for AI.md",
    )

    data = result.to_dict()

    assert data["markdown"] == "## Page 1\n\nXin chào"
    assert data["markdown_filename"] == "Example for AI.md"


def test_raise_if_cancelled_raises_conversion_cancelled():
    class Cancelled:
        def is_set(self):
            return True

    try:
        raise_if_cancelled(Cancelled())
    except ConversionCancelled as exc:
        assert "cancelled" in str(exc).lower()
    else:
        raise AssertionError("Expected ConversionCancelled")
