# edited by glg
import pytest

import pypos.modules.scanner.services.scanner_runtime_service as scanner_runtime_module
from pypos.modules.scanner.services.scanner_runtime_service import ScannerRuntimeService

pytestmark = [pytest.mark.unit]


class _RawInputStub:
    def __init__(self, settings=None, log_warning=None, log_debug=None):
        _ = log_warning
        _ = log_debug
        self.settings = settings or {}
        self.started = False
        self.capture_enabled = False
        self.poll_value = None
        self.status_payload = {"active": False, "capture_enabled": False}

    def start(self):
        self.started = True
        self.status_payload["active"] = True
        return True

    def stop(self):
        self.started = False
        self.status_payload["active"] = False

    def apply_settings(self, settings):
        self.settings = dict(settings or {})

    def is_capture_enabled(self):
        return bool(self.capture_enabled)

    def poll_pending_barcode(self):
        return self.poll_value

    def get_status(self):
        payload = dict(self.status_payload)
        payload["capture_enabled"] = bool(self.capture_enabled)
        return payload


class _DetectorStub:
    def __init__(self, settings=None):
        self.settings = settings or {}
        self.enabled = True
        self.consume_payload = {"handled": False, "barcode": None}
        self.poll_value = None

    def apply_settings(self, settings):
        self.settings = dict(settings or {})

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

    def consume_qt_key_event(self, event):
        _ = event
        return dict(self.consume_payload)

    def poll_pending_barcode(self):
        return self.poll_value


class _GuardStub:
    def __init__(self, dedup_window_ms=180):
        self.window = int(dedup_window_ms or 180)
        self.allow = True

    def apply_window(self, dedup_window_ms):
        self.window = int(dedup_window_ms or 180)

    def should_accept(self, barcode, source):
        _ = barcode
        _ = source
        return bool(self.allow)


def _build_runtime(monkeypatch):
    monkeypatch.setattr(scanner_runtime_module, "RawInputScannerService", _RawInputStub)
    monkeypatch.setattr(scanner_runtime_module, "ScannerDetectorService", _DetectorStub)
    monkeypatch.setattr(scanner_runtime_module, "ScannerEventGuardService", _GuardStub)
    return ScannerRuntimeService({"enabled": True, "duplicate_guard_ms": 200})


def test_scanner_runtime_wedge_event_updates_activity(monkeypatch):
    svc = _build_runtime(monkeypatch)
    svc._rawinput.capture_enabled = False
    svc._detector.consume_payload = {"handled": True, "barcode": "899123"}

    out = svc.consume_qt_key_event(event=None)

    assert out == "899123"
    payload = svc.get_runtime_status()
    activity = payload.get("scanner_activity") or {}
    assert activity.get("last_scan_source") == "wedge_key"
    assert activity.get("last_scan_recent") is True


def test_scanner_runtime_rawinput_poll_path(monkeypatch):
    svc = _build_runtime(monkeypatch)
    svc._rawinput.capture_enabled = True
    svc._rawinput.poll_value = "899999"

    out = svc.poll_pending_barcode()

    assert out == "899999"
    payload = svc.get_runtime_status()
    activity = payload.get("scanner_activity") or {}
    assert activity.get("last_scan_source") == "rawinput_poll"


def test_scanner_runtime_guard_can_reject_event(monkeypatch):
    svc = _build_runtime(monkeypatch)
    svc._rawinput.capture_enabled = False
    svc._detector.consume_payload = {"handled": True, "barcode": "899123"}
    svc._guard.allow = False

    out = svc.consume_qt_key_event(event=None)

    assert out is None
