from __future__ import annotations

import logging
import threading

from PySide6.QtCore import Property, QObject, Qt, Signal, Slot

from pygui.backend.utils import slot_error_boundary, to_local_path
from pygui.backend.wafer.batch_export import BatchExportResult, export_batch

log = logging.getLogger(__name__)


class BatchExportController(QObject):
    busyChanged = Signal()
    exportFinished = Signal(str)

    _batchFinished = Signal(list)

    def __init__(self, parent: QObject | None = None) -> None:
        super().__init__(parent)
        self._busy = False
        self._batchFinished.connect(self._handle_batch_finished, Qt.ConnectionType.QueuedConnection)

    @Property(bool, notify=busyChanged)
    def busy(self) -> bool:
        return self._busy

    @Slot("QVariantList", str)
    def start(self, file_paths: list, output_dir: str) -> None:
        if self._busy:
            return
        self._busy = True
        self.busyChanged.emit()
        threading.Thread(
            target=self._worker,
            args=(list(file_paths), str(to_local_path(output_dir))),
            daemon=True,
        ).start()

    def _worker(self, file_paths: list[str], output_dir: str) -> None:
        try:
            results = export_batch(file_paths, output_dir)
        except Exception as exc:
            log.exception("Batch export worker crashed: %s", exc)
            results = []
        self._batchFinished.emit(results)

    @Slot(list)
    @slot_error_boundary
    def _handle_batch_finished(self, results: list[BatchExportResult]) -> None:
        try:
            total = len(results)
            succeeded = sum(1 for r in results if r.success)
            failed = total - succeeded
            summary = (
                f"Exported {succeeded}/{total} — {failed} failed"
                if failed
                else f"Exported {succeeded}/{total}"
            )
            self.exportFinished.emit(summary)
        finally:
            self._busy = False
            self.busyChanged.emit()
