# Copyright (C) 2026 NPO NT
# SPDX-License-Identifier: AGPL-3.0-only

from __future__ import annotations

import hashlib
from pathlib import Path

from PIL import Image, ImageDraw, ImageFont
from pypdf import PdfReader

from mika_deid.analyzer import analyze_document
from mika_deid.loader import load_document
from mika_deid.models import Action, Box, Finding, Severity
from mika_deid.ocr import TesseractOcr
from mika_deid.sanitizer import _page_boxes, build_raster_pdf
from mika_deid.verifier import verify_raster_pdf


def sha256(path: Path) -> str:
    return hashlib.sha256(path.read_bytes()).hexdigest()


def test_raster_output_copies_no_source_pdf_objects(tmp_path: Path) -> None:
    source = tmp_path / "synthetic-source.png"
    image = Image.new("RGB", (1600, 1100), "white")
    draw = ImageDraw.Draw(image)
    draw.text((100, 100), "Patient: John Smith", fill="black", font=ImageFont.load_default(size=32))
    draw.text((100, 180), "Diagnosis: synthetic clinical content", fill="black", font=ImageFont.load_default(size=28))
    image.save(source, metadata="sensitive")
    before = sha256(source)
    document = load_document(source)
    finding = Finding(
        finding_id="manual-test",
        page_index=0,
        category="person_name",
        box=Box(90, 85, 560, 155),
        action=Action.REDACT,
        severity=Severity.CRITICAL,
        confidence=100,
        source="test",
        reason="synthetic",
    )
    output = tmp_path / "clean.pdf"
    build_raster_pdf(document, [finding], output)
    assert sha256(source) == before
    reader = PdfReader(output, strict=True)
    assert len(reader.pages) == 1
    assert not reader.get_fields()
    assert not (reader.pages[0].extract_text() or "").strip()
    assert "synthetic-source" not in str(reader.metadata)


def test_full_verifier_accepts_clean_blank_output(tmp_path: Path) -> None:
    source = tmp_path / "blank.png"
    Image.new("RGB", (1200, 1600), "white").save(source)
    document = load_document(source)
    finding = Finding(
        finding_id="manual-test",
        page_index=0,
        category="manual",
        box=Box(10, 10, 40, 40),
        action=Action.REDACT,
        severity=Severity.CRITICAL,
        confidence=100,
        source="test",
        reason="synthetic",
    )
    output = tmp_path / "blank-clean.pdf"
    build_raster_pdf(document, [finding], output)
    ocr = TesseractOcr()
    result = verify_raster_pdf(output, expected_page_count=1, ocr=ocr)
    assert result.passed, result.issues


def test_review_date_is_not_redacted_until_user_explicitly_selects_it() -> None:
    finding = Finding(
        finding_id="synthetic-clinical-date",
        page_index=0,
        category="event_date",
        box=Box(100, 100, 250, 140),
        action=Action.REVIEW,
        severity=Severity.MEDIUM,
        confidence=90,
        source="test",
        reason="synthetic clinical date",
        selected=False,
    )

    assert _page_boxes([finding], 0) == []
    finding.selected = True
    assert _page_boxes([finding], 0) == [finding.box]


def test_analysis_report_does_not_include_source_name_or_hash(tmp_path: Path) -> None:
    source = tmp_path / "patient-name-should-not-export.png"
    Image.new("RGB", (1200, 1600), "white").save(source)
    analysis = analyze_document(load_document(source), ocr=TesseractOcr())
    report = analysis.public_dict()
    serialized = str(report)
    assert source.name not in serialized
    assert analysis.document.source_sha256 not in serialized
