# -*- coding: utf-8 -*-
# gui/components/tab_button.py

from PySide6.QtWidgets import QPushButton, QSizePolicy
from PySide6.QtCore import Slot
from gui.containers.s_container import SContainer
from gui.styles import APP_STYLES
from gui.theme_bus import theme_bus


class TabButton(SContainer):
    """Обёртка кнопки вкладки со стилями, зависящими от темы."""

    def __init__(self, text: str, index: int, **kwargs):
        width_percent = kwargs.get("width_percent", None)
        height_percent = kwargs.get("height_percent", None)
        margin = kwargs.get("margin", [0, 2, 0, 2])
        style = kwargs.get("style", None)
        active_style = kwargs.get("active_style", None)
        is_active = kwargs.get("is_active", None)
        content_fit = kwargs.get("content_fit", True)

        super().__init__(
            width_percent=width_percent,
            height_percent=height_percent,
            margin=margin,
            style=style,
            active_style=active_style,
            is_active=is_active,
            content_fit=content_fit,
        )

        self.index = index
        self._theme = "dark"

        self._button = QPushButton(text)
        self._button.setProperty("tab_index", index)

        super().add_widget(self._button)

        self._button.setSizePolicy(
            QSizePolicy.Policy.Expanding,
            QSizePolicy.Policy.Expanding
        )

        self._style_key_normal = style or "TAB_BUTTON_NORMAL"
        self._style_key_active = active_style or "TAB_BUTTON_ACTIVE"
        self._is_active = bool(is_active) if is_active is not None else False
        self.style()
        theme_bus.theme_changed.connect(self.set_theme)

    def style(
        self,
        style_key: str | None = None,
        active_key: str | None = None,
        is_active: bool | None = None,
    ):
        if style_key is not None:
            self._style_key_normal = style_key
            self._style_key_active = active_key or style_key
        if is_active is not None:
            self._is_active = bool(is_active)
        normal_key = self._style_key_normal
        active_key_to_use = self._style_key_active

        if self._theme == "light":
            themed_normal = f"{normal_key}_LIGHT"
            themed_active = f"{active_key_to_use}_LIGHT"
            if themed_normal in APP_STYLES:
                normal_key = themed_normal
            if themed_active in APP_STYLES:
                active_key_to_use = themed_active

        key = active_key_to_use if self._is_active else normal_key
        self._button.setStyleSheet(APP_STYLES.get(key, ""))

    @Slot(str)
    def set_theme(self, theme: str):
        theme = (theme or "").strip().lower()
        if theme not in ("dark", "light"):
            return
        if self._theme == theme:
            return
        self._theme = theme
        self.style()

    @property
    def clicked(self):
        return self._button.clicked

    def click(self):
        self._button.click()

    def set_text(self, text: str):
        self._button.setText(text)

    def get_text(self) -> str:
        return self._button.text()

    def set_enabled(self, enabled: bool) -> None:
        self._button.setEnabled(enabled)
        super().setEnabled(enabled)

    def set_tooltip(self, text: str) -> None:
        self._button.setToolTip(text)

    def set_min_width(self, width: int) -> None:
        self._button.setMinimumWidth(width)
        super().setMinimumWidth(width)

    def set_min_height(self, height: int) -> None:
        self._button.setMinimumHeight(height)
        super().setMinimumHeight(height)

    def set_max_width(self, width: int) -> None:
        self._button.setMaximumWidth(width)
        super().setMaximumWidth(width)

    def set_max_height(self, height: int) -> None:
        self._button.setMaximumHeight(height)
        super().setMaximumHeight(height)

    def set_fixed_size(self, width: int, height: int) -> None:
        self._button.setMinimumSize(width, height)
        self._button.setMaximumSize(width, height)
        super().setMinimumSize(width, height)
        super().setMaximumSize(width, height)

    def set_checkable(self, checkable: bool) -> None:
        self._button.setCheckable(checkable)

    def set_checked(self, checked: bool) -> None:
        self._button.setChecked(checked)

    def is_checked(self) -> bool:
        return self._button.isChecked()

    def set_size_policy(self, horizontal, vertical) -> None:
        self._button.setSizePolicy(horizontal, vertical)
        super().setSizePolicy(horizontal, vertical)

    def set_property(self, name: str, value) -> None:
        super().setProperty(name, value)
        self._button.setProperty(name, value)

    def add_widget(self, widget, alignment=None):
        raise NotImplementedError("TabButton can contain only one QPushButton")


# ---------------------------------------------------------------------------
# Module workflow notes
# ---------------------------------------------------------------------------
#
# 1) Назначение модуля:
#    Кнопка вкладки для TabWidget, реализованная как SContainer
#    с QPushButton внутри и стилями, зависящими от темы.
#    Поддерживает нормальное и активное состояние для визуализации
#    текущей вкладки.
#
# 2) Зависимости модуля:
#    Импорты: QPushButton, QSizePolicy (PySide6.QtWidgets),
#             Slot (PySide6.QtCore),
#             SContainer (gui.containers.s_container),
#             APP_STYLES (gui.styles),
#             theme_bus (gui.theme_bus)
#    Хост-класс / базовый класс: SContainer
#    Внешние библиотеки: PySide6 (обязательна)
#
# 3) Экспорт:
#    Класс TabButton — кнопка вкладки.
#    Методы: style(), set_theme(), click(), set_text(), get_text(),
#            set_enabled(), set_tooltip(), set_checkable(), set_checked(),
#            is_checked(), set_min/max_width/height(), set_fixed_size(),
#            set_size_policy(), set_property().
#    Свойство: clicked.
#
# 4) Состояние (поля):
#    index: int                  — номер вкладки
#    _theme: str                 — текущая тема
#    _button: QPushButton        — внутренняя кнопка
#    _style_key_normal: str      — ключ нормального стиля (TAB_BUTTON_NORMAL)
#    _style_key_active: str      — ключ активного стиля (TAB_BUTTON_ACTIVE)
#    _is_active: bool            — признак активной вкладки
#
# 5) Последовательность действий и вызовов:
#    __init__(text, index, **kwargs)
#      -> super().__init__(...)
#      -> QPushButton(text) -> setProperty("tab_index", index)
#      -> super().add_widget(_button) -> setSizePolicy(Expanding)
#      -> style() -> theme_bus.theme_changed.connect(set_theme)
#    style(style_key?, active_key?, is_active?)
#      -> для light-темы: проверить суффикс _LIGHT в APP_STYLES
#      -> выбрать active или normal ключ
#      -> _button.setStyleSheet(APP_STYLES[key])
#    Вызывается из TabWidget._apply_active_style(index)
#
# 6) Побочные эффекты:
#    - Устанавливает stylesheet на QPushButton.
#    - Подключается к theme_bus.theme_changed.
#
# 7) Границы ответственности:
#    Модуль НЕ управляет содержимым вкладок.
#    НЕ переключает страницы — это делает TabWidget.
#    add_widget() заблокирован.
#
# 8) Обработка ошибок:
#    add_widget() бросает NotImplementedError.
#    set_theme() молча игнорирует невалидные значения.
#
# 9) Инварианты и контракты:
#    - Контейнер содержит ровно одну QPushButton.
#    - _theme ∈ {"dark", "light"}.
#    - index совпадает с порядковым номером вкладки в TabWidget.
#
# 10) Правило сопровождения:
#     Стили TAB_BUTTON_NORMAL / TAB_BUTTON_ACTIVE должны быть
#     определены в APP_STYLES. Для light-темы — суффикс _LIGHT.
#     Не менять index после добавления в TabWidget (переиндексация
#     делается в TabWidget.remove_tab()).
