import os

from PySide6.QtCore import Qt
from PySide6.QtGui import QPainter, QPixmap
from PySide6.QtWidgets import QLabel

from pypos.core.utils.path_utils import get_app_data_resource_dir
from pypos.core.utils.ui_image_asset_utils import load_best_scaled_pixmap
from pypos.core.utils.ui_scale_runtime import register_ui_scale_listener, scale_ui_px
from pypos.modules.scanner.services.scanner_status_service import ScannerStatusService


class ScannerStatusCircle(QLabel):
    def __init__(self, parent=None, box_size=None, icon_size=None):
        super().__init__(parent)
        logo_dir = os.path.join(get_app_data_resource_dir(), "icons")
        self.icon_on_path = os.path.join(logo_dir, "icon-scanner-on.PNG")
        self.icon_off_path = os.path.join(logo_dir, "icon-scanner-off.PNG")

        try:
            parsed_box_size = int(box_size) if box_size is not None else 28
        except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError):
            parsed_box_size = 28
        try:
            parsed_icon_size = int(icon_size) if icon_size is not None else 20
        except (TypeError, ValueError, KeyError, AttributeError, RuntimeError, OSError, LookupError, ArithmeticError, ImportError):
            parsed_icon_size = 20

        if parsed_box_size < 1:
            parsed_box_size = 28
        if parsed_icon_size < 1:
            parsed_icon_size = 20
        if parsed_icon_size > parsed_box_size:
            parsed_icon_size = parsed_box_size

        self._base_box_size = parsed_box_size
        self._base_icon_size = parsed_icon_size
        self._box_size = 0
        self._icon_size = 0
        self._scanner_on = False
        self._status_service = ScannerStatusService()
        self._apply_scaled_metrics()
        self.setAlignment(Qt.AlignCenter)
        register_ui_scale_listener(self._on_runtime_scale_changed)
        self.update_status({})

    def update_status(self, runtime_status):
        status = self._status_service.resolve(runtime_status)
        self._scanner_on = bool(status.get("on", False))
        self._update_icon(self._scanner_on)
        self.setToolTip(str(status.get("tooltip") or "Scanner status"))

    def _update_icon(self, scanner_on):
        self._apply_scaled_metrics()
        icon_path = self.icon_on_path if bool(scanner_on) else self.icon_off_path
        scaled = load_best_scaled_pixmap(
            icon_path,
            self._icon_size,
            self._icon_size,
            keep_aspect=True,
            smooth=True,
            prefer_svg=True,
        )
        if scaled.isNull():
            self.setText("?")
            return

        final_pixmap = QPixmap(self._box_size, self._box_size)
        final_pixmap.fill(Qt.transparent)

        painter = QPainter(final_pixmap)
        x_offset = (self._box_size - scaled.width()) // 2
        y_offset = (self._box_size - scaled.height()) // 2
        painter.drawPixmap(x_offset, y_offset, scaled)
        painter.end()
        self.setPixmap(final_pixmap)

    # edited by glg
    # Gunakan base-size agar render ikon scanner tetap proporsional di resolusi berbeda.
    def _apply_scaled_metrics(self):
        scaled_box = max(1, int(scale_ui_px(self._base_box_size)))
        scaled_icon = max(1, int(scale_ui_px(self._base_icon_size)))
        if scaled_icon > scaled_box:
            scaled_icon = scaled_box
        if scaled_box == self._box_size and scaled_icon == self._icon_size:
            return
        self._box_size = scaled_box
        self._icon_size = scaled_icon
        self.setFixedSize(int(self._base_box_size), int(self._base_box_size))

    # edited by glg
    def _on_runtime_scale_changed(self, _scale):
        self._update_icon(self._scanner_on)
