"""
Background worker for running engine bridge calls off the Qt main thread.
"""

from .qt_compat import QObject, QThread, pyqtSignal


class BridgeWorkerSignals(QObject):
    """Signals emitted by BridgeWorker."""
    finished = pyqtSignal(object)   # emits the return value of the callable
    error = pyqtSignal(str)         # emits the error message string
    progress = pyqtSignal(str)      # emits a human-readable status message


class BridgeWorker(QThread):
    """
    Generic worker that runs a callable in a background QThread.

    Signals (via ``worker.signals``):
        finished(object): Emits the return value of the callable.
        error(str): Emits the error message string.
        progress(str): Emits a human-readable progress status message.

    Usage::

        worker = BridgeWorker(bridge.get_model_info, str(model_path))
        worker.signals.finished.connect(on_success)
        worker.signals.error.connect(on_error)
        worker.signals.progress.connect(on_progress)
        worker.start()
    """

    def __init__(self, fn, *args, **kwargs):
        """
        Args:
            fn: Callable to execute in background thread.
            *args: Positional arguments forwarded to fn.
            **kwargs: Keyword arguments forwarded to fn.
        """
        super().__init__()
        self.fn = fn
        self.args = args
        self.kwargs = kwargs
        self.signals = BridgeWorkerSignals()

    def progress_callback(self, current: int, total: int, percentage: int):
        """Callback suitable for passing to bridge methods. Emits progress signal."""
        message = f"Processing row {current:,} of {total:,} ({percentage}%)"
        self.signals.progress.emit(message)

    def run(self):
        """Execute the callable and emit finished or error."""
        try:
            result = self.fn(*self.args, **self.kwargs)
            self.signals.finished.emit(result)
        except Exception as exc:
            self.signals.error.emit(str(exc))
