# edited by glg
from pypos.modules.scanner.services.scanner_diagnostic_service import ScannerDiagnosticService
from pypos.modules.scanner.services.scanner_pairing_service import ScannerPairingService
from pypos.modules.scanner.services.scanner_runtime_service import ScannerRuntimeService
from pypos.modules.scanner.services.scanner_settings_service import ScannerSettingsService


class ScannerController:
    def __init__(self):
        self.settings_service = ScannerSettingsService()
        self.pairing_service = ScannerPairingService()
        self.diagnostic_service = ScannerDiagnosticService()
        self._settings = self.settings_service.load() or {}
        self.runtime_service = ScannerRuntimeService(self._settings)
        self.runtime_service.start()

    def dispose(self):
        self.runtime_service.stop()

    def load_settings(self):
        self._settings = self.settings_service.load() or {}
        return dict(self._settings)

    def save_settings(self, payload):
        saved = self.settings_service.save(payload) or {}
        self._settings = dict(saved)
        self.runtime_service.apply_settings(self._settings)
        return dict(self._settings)

    def reload_settings(self, payload=None):
        if isinstance(payload, dict):
            self._settings = dict(payload)
            self.runtime_service.apply_settings(self._settings)
            return dict(self._settings)
        self._settings = self.settings_service.load() or {}
        self.runtime_service.apply_settings(self._settings)
        return dict(self._settings)

    def consume_qt_key_event(self, event):
        return self.runtime_service.consume_qt_key_event(event)

    def poll_pending_barcode(self):
        return self.runtime_service.poll_pending_barcode()

    def accept_manual_barcode(self, barcode):
        return self.runtime_service.accept_manual_barcode(barcode)

    def get_runtime_status(self):
        payload = self.runtime_service.get_runtime_status() or {}
        if "settings" not in payload or not isinstance(payload.get("settings"), dict):
            payload["settings"] = dict(self._settings or {})
        return payload

    def run_diagnostic(self):
        settings = self.load_settings()
        runtime = self.get_runtime_status()
        return self.diagnostic_service.run(settings, runtime=runtime)

    def get_discovered_devices(self):
        discovered = self.runtime_service.get_discovered_devices()
        return self.pairing_service.normalize_discovered_devices(discovered)

    def pair_device(self, selected_device, replace=False):
        current = self.load_settings()
        payload = self.pairing_service.pair_device(current, selected_device, replace=replace)
        if not payload:
            return None
        return self.save_settings(payload)
