# edited by glg
import time

from PySide6.QtCore import Qt


class ScannerDetectorService:
    def __init__(self, settings=None):
        self._enabled = False
        self._max_inter_char_ms = 50
        self._min_length = 5
        self._require_enter_suffix = True
        self._buffer = []
        self._last_char_ms = None
        self.apply_settings(settings or {})

    def apply_settings(self, settings):
        cfg = settings if isinstance(settings, dict) else {}
        self._enabled = bool(cfg.get("enabled", False))
        self._max_inter_char_ms = max(1, int(cfg.get("max_inter_char_ms", 50) or 50))
        self._min_length = max(1, int(cfg.get("min_length", 5) or 5))
        self._require_enter_suffix = bool(cfg.get("require_enter_suffix", True))
        self.reset()

    def is_enabled(self):
        return bool(self._enabled)

    def reset(self):
        self._buffer = []
        self._last_char_ms = None

    def _current_ms(self):
        return int(time.perf_counter() * 1000)

    def _consume_barcode(self):
        barcode = "".join(self._buffer).strip()
        self.reset()
        if len(barcode) < self._min_length:
            return None
        return barcode

    def poll_pending_barcode(self):
        if not self.is_enabled() or self._require_enter_suffix:
            return None
        if len(self._buffer) < self._min_length or self._last_char_ms is None:
            return None
        now_ms = self._current_ms()
        if (now_ms - self._last_char_ms) <= self._max_inter_char_ms:
            return None
        return self._consume_barcode()

    def consume_qt_key_event(self, event):
        if not self.is_enabled():
            return {"handled": False, "barcode": None}
        if event is None:
            return {"handled": False, "barcode": None}

        modifiers = event.modifiers()
        allowed_modifiers = Qt.NoModifier | Qt.KeypadModifier | Qt.ShiftModifier
        if modifiers & ~allowed_modifiers:
            return {"handled": False, "barcode": None}

        key = event.key()
        text = str(event.text() or "")
        is_enter = key in (Qt.Key_Return, Qt.Key_Enter)

        if is_enter:
            barcode = self._consume_barcode()
            if barcode:
                return {"handled": True, "barcode": barcode}
            return {"handled": False, "barcode": None}

        if len(text) == 1 and text.isprintable():
            now_ms = self._current_ms()
            if self._last_char_ms is not None and (now_ms - self._last_char_ms) > self._max_inter_char_ms:
                if not self._require_enter_suffix:
                    barcode = "".join(self._buffer).strip()
                    if len(barcode) >= self._min_length:
                        self._buffer = [str(text)]
                        self._last_char_ms = now_ms
                        return {"handled": True, "barcode": barcode}
                self._buffer = []
            self._buffer.append(str(text))
            self._last_char_ms = now_ms
            if not self._require_enter_suffix:
                if len(self._buffer) >= 64:
                    barcode = self._consume_barcode()
                    if barcode:
                        return {"handled": True, "barcode": barcode}
        return {"handled": False, "barcode": None}
