"""Фоновые потоки (QThread) для длительных операций, чтобы не блокировать GUI."""
from __future__ import annotations

from threading import Event
from typing import List, Sequence

from PySide6.QtCore import QThread, Signal

from app.config import ScanReport, ScanSettings, SearchResult
from app.scanning.scanner import DocumentScanner
from app.fileops.file_operations import (
    CopyMapping, copy_found_files, secure_delete_files, secure_move_files,
)


class ScanWorker(QThread):
    progress = Signal(int, int, str)
    result_found = Signal(object)          # SearchResult
    log_message = Signal(str, str)         # level, message
    finished_ok = Signal(object)           # ScanReport

    def __init__(self, settings: ScanSettings, parent=None):
        super().__init__(parent)
        self.settings = settings
        self.cancel_event = Event()
        self._scanner = DocumentScanner()

    def cancel(self) -> None:
        self.cancel_event.set()

    def run(self) -> None:
        report: ScanReport = self._scanner.run(
            self.settings,
            cancel_event=self.cancel_event,
            on_progress=lambda cur, total, msg: self.progress.emit(cur, total, msg),
            on_result=lambda res: self.result_found.emit(res),
            on_log=lambda level, msg: self.log_message.emit(level, msg),
        )
        self.finished_ok.emit(report)


class CopyWorker(QThread):
    finished_ok = Signal(list)  # List[CopyMapping]
    failed = Signal(str)

    def __init__(self, unique_paths: Sequence[str], destination: str, parent=None):
        super().__init__(parent)
        self.unique_paths = list(unique_paths)
        self.destination = destination

    def run(self) -> None:
        try:
            mappings = copy_found_files(self.unique_paths, self.destination)
            self.finished_ok.emit(mappings)
        except Exception as exc:  # noqa: BLE001
            self.failed.emit(str(exc))


class SecureOpWorker(QThread):
    finished_ok = Signal(int)
    failed = Signal(str)

    def __init__(self, mode: str, paths: Sequence[str], destination: str = "", passes: int = 3, parent=None):
        super().__init__(parent)
        self.mode = mode  # "delete" | "move"
        self.paths = list(paths)
        self.destination = destination
        self.passes = passes

    def run(self) -> None:
        try:
            if self.mode == "delete":
                count = secure_delete_files(self.paths, self.passes)
            else:
                count = secure_move_files(self.paths, self.destination, self.passes)
            self.finished_ok.emit(count)
        except Exception as exc:  # noqa: BLE001
            self.failed.emit(str(exc))
