# -*- coding: utf-8 -*-
# gui/containers/s_container.py
"""Универсальный контейнер с процентным масштабированием по обеим осям.

Orientation ("v" | "h") определяет направление стэкирования потомков.
По умолчанию "v" — вертикальный стэк (самый частый паттерн).

При width_percent=None ось X — Expanding.
При height_percent=None ось Y — Expanding.
Таким образом:
    SContainer()                              → растягивается по обеим осям
    SContainer(width_percent=30)              → ≡ VContainer (фикс. ширина, свободная высота)
    SContainer(height_percent=20)             → ≡ HContainer (фикс. высота, свободная ширина)
    SContainer(width_percent=30, height_percent=50) → обе оси фиксированы
"""

from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QLayout, QWidget
from .percent_sized_widget import PercentSizedWidget
from .content_host import ContentHost


class SContainer(PercentSizedWidget):
    """Универсальный контейнер с процентным масштабированием."""

    def __init__(
        self,
        width_percent: int | float | None = None,
        height_percent: int | float | None = None,
        margin: int | tuple[int, int, int, int] = 0,
        spacing: int = 0,
        orientation: str = "v",
        content_width_percent: int | None = None,
        content_height_percent: int | None = None,
        content_width: int | None = None,
        content_height: int | None = None,
        content_fit: bool = True,
        content_driven: bool = False,
        parent: QWidget | None = None,
        style: str | None = None,
        active_style: str | None = None,
        is_active: bool | None = None,
    ):
        super().__init__(width_percent, height_percent, parent, content_driven=content_driven)
        self._init_stylable()
        self._auto_add_children = True

        # Внешний layout — единственный, без промежуточного QGridLayout.
        if orientation == "h":
            self._layout: QLayout = QHBoxLayout(self)
        else:
            self._layout: QLayout = QVBoxLayout(self)
        self._layout.setSpacing(0)

        if isinstance(margin, (list, tuple)) and len(margin) == 4:
            self._layout.setContentsMargins(*margin)
        else:
            self._layout.setContentsMargins(margin, margin, margin, margin)

        self._content_host = ContentHost(
            width_percent=content_width_percent,
            height_percent=content_height_percent,
            orientation=orientation,
            margin=0,
            spacing=spacing,
            parent=self,
        )
        self._content_host.set_content_fit(content_fit)

        if content_width is not None or content_height is not None:
            w = content_width if content_width is not None else self._content_host.sizeHint().width()
            h = content_height if content_height is not None else self._content_host.sizeHint().height()
            self._content_host.set_fixed_size(w, h)

        self._layout.addWidget(self._content_host)

        if style is not None or active_style is not None or is_active is not None:
            self._apply_style(style_key=style, active_key=active_style, is_active=is_active)

    # ── публичный API ──

    def add_widget(self, widget: QWidget, alignment=None) -> None:
        """Добавляет виджет в layout контейнера."""
        self._content_host.add_widget(widget)

    def insert_widget(self, index: int, widget: QWidget) -> None:
        """Вставляет виджет в layout контента по индексу."""
        self._content_host.insert_widget(index, widget)

    def remove_widget(self, widget: QWidget) -> None:
        """Удаляет виджет из layout контента."""
        self._content_host.remove_widget(widget)

    def add_widget_with_stretch(self, widget: QWidget, stretch: int, alignment=None) -> None:
        self._content_host.add_widget_with_stretch(widget, stretch)

    def add_stretch(self, stretch: int = 1) -> None:
        self._content_host.add_stretch(stretch)

    def invalidate_layout(self) -> None:
        self._content_host.get_layout().invalidate()

    def get_layout(self) -> QLayout:
        return self._layout

    def set_margins(self, margin: int | tuple[int, int, int, int]) -> None:
        if isinstance(margin, (list, tuple)) and len(margin) == 4:
            self._layout.setContentsMargins(*margin)
        else:
            self._layout.setContentsMargins(margin, margin, margin, margin)

    def set_spacing(self, spacing: int) -> None:
        self._content_host.get_layout().setSpacing(spacing)

    def set_alignment(self, alignment: str) -> None:
        raise NotImplementedError("Qt alignment for containers is disabled; use content springs.")

    def set_widget_alignment(self, widget: QWidget, alignment: str) -> None:
        raise NotImplementedError("Qt alignment for containers is disabled; use content springs.")

    def get_available_size_for_content(self) -> tuple[int, int]:
        """Полезная внутренняя область (без учёта margin)."""
        margins = self._layout.contentsMargins()
        w = self.width() - margins.left() - margins.right()
        h = self.height() - margins.top() - margins.bottom()
        return max(0, w), max(0, h)




# ---------------------------------------------------------------------------
# Module workflow notes
# ---------------------------------------------------------------------------
#
# 1) Назначение модуля:
#    Универсальный контейнер с процентным масштабированием по обеим осям.
#    Ориентация ("v"|"h") определяет направление стэкирования потомков.
#    Является базовым классом для VContainer и HContainer.
#    Эквивалентности: SContainer(w%=30) ≡ VContainer(w%=30),
#    SContainer(h%=20) ≡ HContainer(h%=20).
#
# 2) Зависимости модуля:
#    Импорты: QVBoxLayout, QHBoxLayout, QLayout, QWidget (PySide6)
#    Хост/базовый класс: StylableMixin + PercentSizedWidget (MRO)
#    Внутренние: ContentHost (content_host.py), StylableMixin (stylable_mixin.py)
#    Внешние библиотеки: PySide6
#
# 3) Экспорт:
#    Класс SContainer — универсальный контейнер.
#    Методы: add_widget(), add_widget_with_stretch(), add_stretch(),
#            invalidate_layout(), get_layout(), set_margins(),
#            set_spacing(), set_alignment(), set_widget_alignment(),
#            get_available_size_for_content()
#
# 4) Состояние (поля):
#    _layout            : QVBoxLayout|QHBoxLayout — внешний layout.
#    _content_host      : ContentHost — промежуточный хост для потомков.
#    _auto_add_children : bool = True — дочерние виджеты авто-добавляются.
#
# 5) Последовательность действий и вызовов:
#    __init__(params) -> super().__init__(w%, h%, parent)
#      -> _init_stylable() -> создание QVBoxLayout/QHBoxLayout по orientation
#      -> setSpacing(0) на _layout -> setContentsMargins(margin)
#      -> создание ContentHost(orientation, spacing)
#      -> _content_host.set_content_fit(content_fit)
#      -> set_fixed_size(content_width, content_height) если заданы
#      -> _layout.addWidget(_content_host)
#      -> _apply_style() если style задан
#    add_widget(w) -> _content_host.add_widget(w)
#    set_spacing(s) -> _content_host.get_layout().setSpacing(s)
#
# 6) Побочные эффекты:
#    _auto_add_children = True — дочерние PercentSizedWidget авто-добавляются.
#    set_alignment() и set_widget_alignment() бросают NotImplementedError.
#    _apply_style() устанавливает stylesheet.
#    Подписка на theme_bus через StylableMixin.
#
# 7) Границы ответственности:
#    НЕ поддерживает spring-based alignment (в отличие от GridContainer).
#    НЕ содержит сетку — только линейный layout.
#    НЕ управляет scroll — это ScrollContainer.
#
# 8) Обработка ошибок:
#    set_alignment() → NotImplementedError.
#    set_widget_alignment() → NotImplementedError.
#    Для обоих: «Qt alignment for containers is disabled; use content springs.»
#
# 9) Инварианты и контракты:
#    - orientation ∈ {"v", "h"}, иначе умолчание — вертикальный.
#    - При w%=None → ось X = Expanding; при h%=None → ось Y = Expanding.
#    - spacing внешнего _layout всегда 0 (spacing применяется к ContentHost).
#    - alignment параметр в __init__ — deprecated, игнорируется.
#
# 10) Правило сопровождения:
#     Новая логика должна быть совместима с VContainer/HContainer —
#     они наследуют SContainer. Не вводить логику, специфичную только
#     для одной ориентации. Spacing: внешний layout = 0, внутренний
#     (ContentHost) = spacing параметр.
