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

from __future__ import annotations

import threading
from pathlib import Path

import pytest
from PIL import Image

from mika_deid.analyzer import analyze_document
from mika_deid.gui import SUPPORTED_SOURCE_SUFFIXES, _format_duration
from mika_deid.loader import load_document
from mika_deid.ocr import OcrResult
from mika_deid.progress import OperationCancelled, ProgressUpdate


class FakeOcr:
    available = True
    selected_languages = ("rus", "eng")

    def recognize(self, _image, _page_index: int, *, cancel_signal=None) -> OcrResult:
        return OcrResult(tokens=[], mean_confidence=None, languages=self.selected_languages)


def _two_page_tiff(path: Path) -> None:
    first = Image.new("RGB", (900, 1100), "white")
    second = Image.new("RGB", (900, 1100), "white")
    first.save(path, save_all=True, append_images=[second], compression="tiff_deflate")


def test_loader_and_analyzer_report_page_progress_without_source_text(tmp_path: Path) -> None:
    source = tmp_path / "synthetic-progress.tiff"
    _two_page_tiff(source)
    updates: list[ProgressUpdate] = []

    document = load_document(source, progress_callback=updates.append)
    analysis = analyze_document(document, ocr=FakeOcr(), progress_callback=updates.append)

    assert len(analysis.document.pages) == 2
    assert [(item.current, item.total) for item in updates if item.stage == "render_complete"] == [(1, 2), (2, 2)]
    assert [(item.current, item.total) for item in updates if item.stage == "page_complete"] == [(1, 2), (2, 2)]
    assert updates[-1] == ProgressUpdate(stage="complete", current=2, total=2)
    assert all(source.name not in repr(item) for item in updates)


def test_cancelled_load_stops_before_opening_source(tmp_path: Path) -> None:
    source = tmp_path / "synthetic-cancel.png"
    Image.new("RGB", (100, 100), "white").save(source)
    cancelled = threading.Event()
    cancelled.set()

    with pytest.raises(OperationCancelled, match="отменена"):
        load_document(source, cancel_signal=cancelled)


def test_gui_progress_helpers_and_supported_formats_are_explicit() -> None:
    assert _format_duration(0) == "00:00"
    assert _format_duration(65) == "01:05"
    assert _format_duration(3661) == "1:01:01"
    assert ".zip" not in SUPPORTED_SOURCE_SUFFIXES
    assert {".pdf", ".jpg", ".png", ".tiff", ".heic"} <= SUPPORTED_SOURCE_SUFFIXES
