# -*- coding: utf-8 -*-
# dispatch/null_hardware_gateway.py

"""Пустой реализатор `TicketHardwareGateway` для приложения Dispatch.

Назначение модуля:
    В составе Dispatch модуль работы с COM-портом отключён по требованию
    приложения. Application-сервис Ticket по архитектурному контракту
    обязан получать на вход реализацию `TicketHardwareGateway` и
    обращаться к ней при старте, остановке и обновлении состояний кнопок.

    Данный класс предоставляет канонически совместимую, но полностью
    бездействующую реализацию шлюза:
    - `start` / `stop` ничего не делают;
    - `set_observer` принимает наблюдателя и сразу публикует ему
      нейтральный статус подключения;
    - методы управления состояниями кнопок принимают вызовы и
      молча игнорируют их;
    - `get_status` всегда возвращает «отключён».

Архитектурные ограничения:
    - Реализация полностью независима от каталога `gui/`.
    - Никакой предметной логики Ticket здесь не содержится: класс
      исключительно закрывает контракт `TicketHardwareGateway`.
"""

from __future__ import annotations

from typing import Any, Mapping

from PySide6.QtCore import QObject

from domain import TicketConnectionStatus, TicketHardwareStatus
from services import TicketHardwareObserver


class NullHardwareGateway(QObject):
    """Бездействующий шлюз: закрывает контракт `TicketHardwareGateway`."""

    def __init__(self, parent: QObject | None = None):
        super().__init__(parent)
        self._observer: TicketHardwareObserver | None = None
        self._status = TicketHardwareStatus(
            connection_status=TicketConnectionStatus.DISCONNECTED,
            message="hardware module is disabled in Dispatch",
            buttons_initialized=False,
            button_count=0,
        )

    # ── управление жизненным циклом ──

    def start(self) -> None:
        """Обозначить факт «запуска» без обращения к внешнему оборудованию."""
        if self._observer is not None:
            self._observer.on_gateway_status(self._status)

    def stop(self) -> None:
        """Завершить работу: ничего не освобождаем, состояние уже нейтральное."""
        return

    # ── подписка наблюдателя ──

    def set_observer(self, observer: TicketHardwareObserver | None) -> None:
        """Назначить получателя событий и сразу опубликовать текущий статус."""
        self._observer = observer
        if observer is not None:
            observer.on_gateway_status(self._status)

    def get_status(self) -> TicketHardwareStatus:
        """Вернуть постоянно-нейтральный статус шлюза."""
        return self._status

    # ── управление состояниями кнопок ──

    def set_button_state(self, button_id: int, state_code: int) -> None:
        """Принять обновление состояния кнопки и проигнорировать его."""
        return

    def remove_button_state(self, button_id: int) -> None:
        """Принять снятие состояния кнопки и проигнорировать его."""
        return

    def reset_button_states(self) -> None:
        """Сбросить «состояния»: для null-шлюза это операция без эффекта."""
        return

    # ── совместимость с возможными внешними действиями ──

    def emit_external_action(self, raw_action: Mapping[str, Any]) -> None:
        """Доставить внешнее действие наблюдателю, если он назначен.

        Метод оставлен для возможной интеграции внешних источников событий
        в будущем; в текущем составе Dispatch не вызывается.
        """
        if self._observer is not None:
            self._observer.on_task_action(raw_action)
