"""
B3.6 visual verification script.

Steps:
  1. Re-translate the test PDF using a mock provider (cheap, no API cost).
  2. Render both the OLD broken PDF and the NEW (B3.6) PDF as PNGs.
  3. Inspect drawings: the blue "Avis important" box must still be present
     in the new PDF but was lost in the old PDF.
  4. Inspect title block: it must not overlap the next block ("Version du document...").
  5. Open both PNGs side-by-side so we can eyeball the difference.

Usage: python scripts/verify_b3_6_fix.py
"""
import sys
import os
from pathlib import Path
from unittest.mock import MagicMock

# Make repo root importable
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

import fitz  # PyMuPDF

REPO_ROOT = Path(__file__).resolve().parent.parent
OLD_PDF = REPO_ROOT / "sample_files" / "test_corpus" / "test_pdf_translated (1).pdf"
ORIG_PDF = REPO_ROOT / "sample_files" / "test_corpus" / "test_pdf.pdf"
NEW_PDF = REPO_ROOT / "sample_files" / "test_corpus" / "test_pdf_translated_fresh.pdf"
RENDER_DIR = REPO_ROOT / "scripts" / "_renders"
RENDER_DIR.mkdir(parents=True, exist_ok=True)


def _render_pdf_page(pdf_path: Path, page_num: int = 0, out_png: Path = None,
                     zoom: float = 1.5) -> Path:
    """Render a single PDF page as PNG."""
    doc = fitz.open(str(pdf_path))
    page = doc[page_num]
    mat = fitz.Matrix(zoom, zoom)
    pix = page.get_pixmap(matrix=mat)
    if out_png is None:
        out_png = RENDER_DIR / f"{pdf_path.stem}_p{page_num + 1}.png"
    pix.save(str(out_png))
    doc.close()
    return out_png


def _translate_with_mock(input_path: Path, output_path: Path) -> Path:
    """Translate using a mock provider that returns the French text we want."""
    from translators.pdf_translator import PDFTranslator

    translator = PDFTranslator()

    # Mock provider: a fake French translation that's longer than the English original
    # (this is the realistic case that triggered the overflow bug)
    def mock_translate(text, target_language, source_language):
        # Return a slightly longer French version to stress the layout
        if not text:
            return text
        # Replace common patterns with longer French to trigger overflow
        replacements = {
            "Technical Specification": "Spécification technique : Office Translator",
            "Document Version": "Version du document",
            "Table of Contents": "Table des matières",
            "1. Introduction": "1. Introduction",
            "2. Installation and Configuration": "2. Installation et configuration",
            "3. Translation Engine": "3. Moteur de traduction",
            "4. Format Preservation": "4. Préservation des formats",
            "5. Quality Assurance": "5. Assurance qualité",
            "6. Performance and Scaling": "6. Performances et mise à l'échelle",
            "7. API Reference": "7. Référence API",
            "8. Troubleshooting": "8. Résolution des problèmes",
            "Important Notice": "Avis important",
            "This is a preliminary document.": "Ceci est un document préliminaire.",
            "Subject to change without notice.": "Sujet à changement sans préavis.",
            "For the latest version of this document, visit:": "Pour la dernière version de ce document, visitez :",
            "http://docs.translator.example.com/v3": "http://docs.translator.example.com/v3",
        }
        result = text
        for eng, fr in replacements.items():
            result = result.replace(eng, fr)
        return result

    mock = MagicMock()
    mock.translate_batch = MagicMock(side_effect=lambda texts, tgt, src: [mock_translate(t, tgt, src) for t in texts])

    translator.set_provider(mock)
    translator.translate_file(
        input_path, output_path,
        target_language="fr",
        source_language="en",
    )
    return output_path


def _inspect_drawings(pdf_path: Path) -> dict:
    """Inspect page 1: count blue background drawings (the "Avis important" box)."""
    doc = fitz.open(str(pdf_path))
    page = doc[0]
    drawings = page.get_drawings()
    # The "Avis important" box has fill (0.85, 0.92, 1.0) — light blue
    blue_boxes = []
    for d in drawings:
        fill = d.get("fill")
        if fill is None:
            continue
        # Match light blue (R=0.85, G=0.92, B=1.0)
        if all(abs(fill[i] - target) < 0.05 for i, target in enumerate([0.85, 0.92, 1.0])):
            blue_boxes.append(d)
    doc.close()
    return {
        "total_drawings": len(drawings),
        "blue_boxes": len(blue_boxes),
        "blue_rects": [(round(d["rect"].x0, 1), round(d["rect"].y0, 1),
                       round(d["rect"].x1, 1), round(d["rect"].y1, 1))
                      for d in blue_boxes],
    }


def _inspect_title_overlap(pdf_path: Path) -> dict:
    """Check if the title block bottom overlaps the next block top."""
    doc = fitz.open(str(pdf_path))
    page = doc[0]
    text_dict = page.get_text("dict")

    # Find the title block (largest font on the page)
    title_block = None
    next_block = None
    sorted_blocks = sorted(
        [b for b in text_dict.get("blocks", []) if b.get("type") == 0],
        key=lambda b: -(
            max((s.get("size", 12) for line in b.get("lines", [])
                 for s in line.get("spans", [])), default=12)
        )
    )

    if sorted_blocks:
        title_block = sorted_blocks[0]
        title_text = " ".join(
            s.get("text", "")
            for line in title_block.get("lines", [])
            for s in line.get("spans", [])
        )
        title_bottom = title_block["bbox"][3]

        # Find the next block right below the title
        candidates = [
            b for b in text_dict.get("blocks", [])
            if b.get("type") == 0
            and b is not title_block
            and b["bbox"][1] >= title_bottom - 5
            and b["bbox"][1] <= title_bottom + 50
        ]
        if candidates:
            next_block = min(candidates, key=lambda b: b["bbox"][1])

    result = {
        "title": " ".join(
            s.get("text", "")
            for line in (title_block or {}).get("lines", [])
            for s in line.get("spans", [])
        )[:60],
        "title_bbox": title_block["bbox"] if title_block else None,
    }
    if next_block:
        next_text = " ".join(
            s.get("text", "")
            for line in next_block.get("lines", [])
            for s in line.get("spans", [])
        )[:60]
        result["next_text"] = next_text
        result["next_bbox"] = next_block["bbox"]
        result["overlap_px"] = round(title_block["bbox"][3] - next_block["bbox"][1], 2)
        result["overlaps"] = result["overlap_px"] > 2
    doc.close()
    return result


def main():
    print("=" * 60)
    print("B3.6 VERIFICATION — visual & structural")
    print("=" * 60)

    # 1. Translate the original with B3.6 fix
    print("\n[1] Re-translating test_pdf.pdf with B3.6 fix...")
    if not ORIG_PDF.exists():
        print(f"  ERROR: original PDF not found at {ORIG_PDF}")
        return 1
    _translate_with_mock(ORIG_PDF, NEW_PDF)
    print(f"  wrote {NEW_PDF.name}")

    # 2. Render both PDFs as PNG for visual comparison
    print("\n[2] Rendering PDFs to PNG...")
    old_png = _render_pdf_page(OLD_PDF)
    new_png = _render_pdf_page(NEW_PDF)
    orig_png = _render_pdf_page(ORIG_PDF)
    print(f"  OLD broken:   {old_png.relative_to(REPO_ROOT)}")
    print(f"  NEW (B3.6):   {new_png.relative_to(REPO_ROOT)}")
    print(f"  ORIGINAL ref: {orig_png.relative_to(REPO_ROOT)}")

    # 3. Inspect drawings - blue box preservation
    print("\n[3] Inspecting drawings (blue 'Avis important' box)...")
    for label, path in [("OLD", OLD_PDF), ("NEW (B3.6)", NEW_PDF), ("ORIGINAL", ORIG_PDF)]:
        info = _inspect_drawings(path)
        verdict = "[OK]" if info["blue_boxes"] >= 1 else "[FAIL]"
        print(f"  {verdict} {label:12} -> {info['blue_boxes']} blue box(es) of "
              f"{info['total_drawings']} total drawings")

    # 4. Inspect title overlap
    print("\n[4] Inspecting title-vs-next-block overlap...")
    for label, path in [("OLD", OLD_PDF), ("NEW (B3.6)", NEW_PDF)]:
        info = _inspect_title_overlap(path)
        if "overlaps" in info:
            verdict = "[FAIL OVERLAPS]" if info["overlaps"] else "[OK no overlap]"
            print(f"  {verdict} {label:12} -> title={info['title']!r:40} "
                  f"overlap_px={info['overlap_px']:+.1f}")
        else:
            print(f"  [?] {label:12} -> could not determine (insufficient blocks)")

    print("\n" + "=" * 60)
    print("Visual comparison rendered to:")
    print(f"  {old_png}")
    print(f"  {new_png}")
    print(f"  {orig_png}")
    print("=" * 60)
    return 0


if __name__ == "__main__":
    sys.exit(main())
