# -*- coding: utf-8 -*-
# hub/ticket/ui/ticket_selection_list.py

"""Контейнерный список выбора Ticket на локальной GUI-библиотеке."""

from __future__ import annotations

from dataclasses import dataclass

from PySide6.QtCore import Qt, Signal

from gui.components import Label, VSpring
from gui.containers import ScrollContainer, SContainer, VContainer


@dataclass(frozen=True, slots=True)
class TicketSelectionEntry:
    """Описывает одну запись в контейнерном списке Ticket."""

    entry_id: object
    title: str
    subtitle: str = ""


class _TicketSelectionItem(SContainer):
    """Визуальный элемент выбора записи Ticket."""

    clicked = Signal(object)
    activated = Signal(object)

    def __init__(
        self,
        entry: TicketSelectionEntry,
        parent=None,
    ):
        super().__init__(
            margin=0,
            spacing=2,
            content_fit=True,
            parent=parent,
            style="TICKET_LIST_ITEM",
            active_style="TICKET_LIST_ITEM_SELECTED",
            is_active=False,
        )
        self._entry = entry
        self.setCursor(Qt.CursorShape.PointingHandCursor)
        self._setup_ui()

    @property
    def entry_id(self) -> object:
        return self._entry.entry_id

    def set_selected(self, selected: bool) -> None:
        self.style(is_active=selected)

    def mousePressEvent(self, event) -> None:
        if event.button() == Qt.MouseButton.LeftButton:
            self.clicked.emit(self._entry.entry_id)
        super().mousePressEvent(event)

    def mouseDoubleClickEvent(self, event) -> None:
        if event.button() == Qt.MouseButton.LeftButton:
            self.clicked.emit(self._entry.entry_id)
            self.activated.emit(self._entry.entry_id)
        super().mouseDoubleClickEvent(event)

    def _setup_ui(self) -> None:
        # Body элемента списка: вертикальный блок title/subtitle внутри кликабельной записи.
        body = VContainer(margin=10, spacing=2, parent=self)
        body.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)
        title_label = Label(
            self._entry.title,
            alignment="left",
            style="TICKET_LIST_TITLE",
        )
        title_label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)
        body.add_widget(title_label)

        if self._entry.subtitle:
            subtitle_label = Label(
                self._entry.subtitle,
                alignment="left",
                style="TICKET_LIST_SUBTITLE",
            )
            subtitle_label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)
            body.add_widget(subtitle_label)


class TicketSelectionList(SContainer):
    """Переиспользуемый список выбора на контейнерах и локальных компонентах."""

    selection_changed = Signal(object)
    item_activated = Signal(object)

    def __init__(self, parent=None):
        super().__init__(spacing=0, parent=parent)
        self._items: dict[object, _TicketSelectionItem] = {}
        self._current_entry_id: object | None = None
        self._items_host: VContainer | None = None
        self._setup_ui()

    def set_entries(self, entries: list[TicketSelectionEntry]) -> None:
        previous_entry_id = self._current_entry_id
        self.clear_entries()
        for entry in entries:
            self._add_entry(entry)
        if not self._items:
            self._current_entry_id = None
            self.selection_changed.emit(None)
            return
        target_entry_id = previous_entry_id if previous_entry_id in self._items else entries[0].entry_id
        self.set_current_entry(target_entry_id)

    def clear_entries(self) -> None:
        if self._items_host is None:
            self._items.clear()
            self._current_entry_id = None
            return
        for item in list(self._items.values()):
            self._items_host.remove_widget(item)
            item.setParent(None)
        self._items.clear()
        self._current_entry_id = None

    def current_entry_id(self) -> object | None:
        return self._current_entry_id

    def has_selection(self) -> bool:
        return self._current_entry_id is not None

    def set_current_entry(self, entry_id: object | None) -> None:
        normalized_entry_id = entry_id if entry_id in self._items else None
        if normalized_entry_id == self._current_entry_id:
            return
        self._current_entry_id = normalized_entry_id
        for item_entry_id, item in self._items.items():
            item.set_selected(item_entry_id == normalized_entry_id)
        self.selection_changed.emit(normalized_entry_id)

    def _setup_ui(self) -> None:
        # Scroll-контейнер списка: внешняя прокручиваемая оболочка всех записей TicketSelectionList.
        scroll = ScrollContainer(
            margin=0,
            content_margins=[0, 0, 0, 0],
            spacing=6,
            orientation="v",
            vertical_scroll_bar_policy="as_needed",
            horizontal_scroll_bar_policy="always_off",
            style="SCROLL_CONTAINER",
            parent=self,
        )
        # Items-host: вертикальный стек элементов списка с нижней пружиной для прилипания вверх.
        self._items_host = VContainer(spacing=6, parent=scroll)
        self._items_host.add_widget(VSpring())

    def _add_entry(self, entry: TicketSelectionEntry) -> None:
        if self._items_host is None:
            return
        item = _TicketSelectionItem(entry)
        item.clicked.connect(self._on_item_clicked)
        item.activated.connect(self._on_item_activated)
        self._items[entry.entry_id] = item
        self._items_host.insert_widget(len(self._items) - 1, item)

    def _on_item_clicked(self, entry_id: object) -> None:
        self.set_current_entry(entry_id)

    def _on_item_activated(self, entry_id: object) -> None:
        if entry_id != self._current_entry_id:
            self.set_current_entry(entry_id)
        self.item_activated.emit(entry_id)
