import os
import sys
import linuxcnc

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel

from qtpyvcp.plugins import getPlugin
from qtpyvcp.utilities import logger
from qtpyvcp.utilities.runtime_ui_loader import load_ui as load_runtime_ui

# Same nesting depth as user_buttons/user_buttons/user_buttons.py:
# <config_root>/user_tabs/status_tab/status_tab.py, two levels below root.
_SHARED_WIDGETS_DIR = os.path.abspath(
    os.path.join(os.path.dirname(__file__), "..", "..", "shared_widgets")
)
if _SHARED_WIDGETS_DIR not in sys.path:
    sys.path.insert(0, _SHARED_WIDGETS_DIR)

from illuminated_label import IlluminatedLabelBinder

LOG = logger.getLogger(__name__)

STATUS = getPlugin('status')
TOOL_TABLE = getPlugin('tooltable')

INI_FILE = linuxcnc.ini(os.getenv('INI_FILE_NAME'))


def _load_ui(ui_path, parent):
    return load_runtime_ui(ui_path, parent)


def _adopt_ui_identity(widget, loaded_ui):
    """Copy the .ui root widget's name and dynamic properties onto widget.

    PySide6's QUiLoader nests a separate widget inside the parent it is given,
    unlike PyQt's uic.loadUi(path, baseinstance), which made baseinstance the
    root widget. probe_basic reads this tab's objectName (used as the tab
    label, underscores shown as spaces) and its "sidebar" property off the
    UserTab instance, so put them back where it looks for them.
    """
    widget.setObjectName(loaded_ui.objectName())
    for prop_name in loaded_ui.dynamicPropertyNames():
        key = bytes(prop_name).decode()
        if key.startswith("_"):
            continue  # PySide6 bookkeeping, e.g. _PySideInvalidatePtr
        try:
            widget.setProperty(key, loaded_ui.property(key))
        except RuntimeError as exc:
            LOG.warning(f"Could not copy user tab property '{key}': {exc}")


class UserTab(QWidget):
    def __init__(self, parent=None):
        super(UserTab, self).__init__(parent)
        ui_file = os.path.splitext(os.path.basename(__file__))[0] + ".ui"
        ui_path = os.path.join(os.path.dirname(__file__), ui_file)
        self.ui = _load_ui(ui_path, self)
        _adopt_ui_identity(self, self.ui)

        # The wrapper widget (this instance) is what probe_basic actually
        # adds to the sidebar container. Without a layout, it has no size
        # hint of its own, so the container may give it zero usable space
        # even though self.ui (the real content) has a valid geometry.
        # Propagate a real size and wrap self.ui in a layout so the
        # container has something concrete to lay out.
        self.setMinimumSize(self.ui.minimumSize())
        self.setMaximumSize(self.ui.maximumSize())
        self.resize(self.ui.size())

        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.ui)

        self._bind_indicator_labels()

    def _bind_indicator_labels(self):
        # Any QLabel with an 'indicatorPinName' dynamic property (set from
        # Qt Designer's Property Editor, no Python needed) becomes an
        # illuminated indicator. 'indicatorStyle' (on-color) defaults to
        # "green", 'indicatorFlashStyle' (flash-color) defaults to "red" --
        # both are independent and can be mixed freely. Same pattern as
        # user_buttons.py.
        self._indicators = []
        for label in self.ui.findChildren(QLabel):
            pin_name = label.property("indicatorPinName")
            if not pin_name:
                continue
            style = label.property("indicatorStyle") or "green"
            flash_style = label.property("indicatorFlashStyle") or "red"
            font_size = label.property("indicatorFontSize") or 24
            self._indicators.append(
                IlluminatedLabelBinder(
                    label, str(pin_name), style=str(style),
                    flash_style=str(flash_style), font_size=int(font_size)
                )
            )
