import logging
from typing import Set

from PyQt6.QtCore import QObject, QTimer, QThread, pyqtSignal

from ipod_device import IPodDevice

logger = logging.getLogger(__name__)


class _DetectWorker(QThread):
    finished = pyqtSignal(object)

    def __init__(self, parent=None):
        super().__init__(parent)

    def run(self):
        try:
            devices = IPodDevice().detect_devices()
            self.finished.emit(devices)
        except Exception:
            logger.exception("Device detection failed")
            self.finished.emit([])


class DeviceMonitor(QObject):

    state_changed = pyqtSignal(list)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.timer = QTimer(self)
        self.timer.timeout.connect(self._poll)
        self._device_ids: Set[str] = set()
        self._poll_worker = None

    def start(self, interval_ms: int = 3000):
        self._device_ids.clear()
        self._poll()
        self.timer.start(interval_ms)

    def stop(self):
        self.timer.stop()
        if self._poll_worker:
            self._poll_worker.quit()
            self._poll_worker.wait()
            self._poll_worker = None
        self._device_ids.clear()

    def _poll(self):
        if self._poll_worker:
            try:
                if self._poll_worker.isRunning():
                    return
            except RuntimeError:
                self._poll_worker = None
        worker = _DetectWorker()
        worker.finished.connect(self._on_devices_detected)
        worker.start()
        self._poll_worker = worker

    def _on_devices_detected(self, devices):
        if self._poll_worker:
            self._poll_worker.quit()
            self._poll_worker.wait()
            self._poll_worker = None
        current_ids = {d["id"] for d in devices}
        if current_ids != self._device_ids:
            self._device_ids = current_ids
            self.state_changed.emit(devices)
