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

"""UI-диалог выбора специалиста Ticket."""

from __future__ import annotations

from collections.abc import Sequence

from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QMouseEvent

from gui.components import Button, Dialog, Label
from gui.containers import HContainer, ScrollContainer, SContainer, VContainer

from ui.cards.task_card_pixmap_factory import (
    build_placeholder_avatar_pixmap,
    load_avatar_pixmap,
)
from ui.task_view_formatters import (
    build_specialist_card_info,
    build_specialist_photo_path,
)


class _SpecialistRow(SContainer):
    """Строка выбора специалиста с фото, именем и должностью."""

    clicked = Signal(str)
    activated = Signal(str)

    def __init__(self, specialist_name: str, parent=None):
        super().__init__(
            margin=0,
            spacing=0,
            content_fit=True,
            parent=parent,
            style="TICKET_SPECIALIST_ITEM",
            active_style="TICKET_SPECIALIST_ITEM_SELECTED",
            is_active=False,
        )
        self._specialist_name = specialist_name
        self._info = build_specialist_card_info(specialist_name)
        self._name_label: Label | None = None
        self._role_label: Label | None = None
        self._avatar_label: Label | None = None
        self.setObjectName("ticket_specialist_row")
        self.setCursor(Qt.CursorShape.PointingHandCursor)
        self.set_min_height(88)
        self._setup_ui()

    @property
    def specialist_name(self) -> str:
        return self._specialist_name

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

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

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

    def _setup_ui(self) -> None:
        # Body-row карточки специалиста: фото слева и текстовый блок справа.
        body = HContainer(margin=[12, 10, 12, 10], spacing=16, content_fit=True, parent=self)
        body.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)

        self._avatar_label = Label("", style="TICKET_TASK_CARD_AVATAR_IMAGE")
        self._avatar_label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)
        self._avatar_label.set_fixed_size(72, 72)
        self._avatar_label.set_pixmap(self._build_avatar_pixmap())

        self._name_label = Label(
            self._specialist_name,
            alignment="left",
            style="TICKET_DETAILS_SECTION_TITLE",
        )
        self._name_label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)

        self._role_label = Label(
            self._info.get("position", "").strip() or "Специалист",
            alignment="left",
            style="TICKET_SPECIALIST_ROLE",
        )
        self._role_label.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)

        # Text-block специалиста: вертикальный контейнер имени и должности.
        text_block = VContainer(spacing=2, content_fit=True)
        text_block.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)
        text_block.add_widget(self._name_label)
        text_block.add_widget(self._role_label)

        body.add_widget(self._avatar_label)
        body.add_widget_with_stretch(text_block, 1)

    def _build_avatar_pixmap(self):
        photo_path = build_specialist_photo_path(
            self._specialist_name,
            self._info.get("photo", ""),
        )
        avatar = load_avatar_pixmap(photo_path, 72, 72, padding=2)
        if avatar is None:
            return build_placeholder_avatar_pixmap(72)
        return avatar


class SpecialistDialog(Dialog):
    """Диалог выбора специалиста без application-логики."""

    def __init__(
        self,
        specialists: Sequence[str],
        parent=None,
    ):
        self._specialists = [str(item).strip() for item in specialists if str(item).strip()]
        self._selected_specialist = ""
        self._rows: dict[str, _SpecialistRow] = {}
        self._cancel_button: Button | None = None
        self._submit_button: Button | None = None
        super().__init__(
            title="Выбор специалиста",
            width=540,
            height=740,
            modal=True,
            parent=parent,
        )
        self._setup_ui()
        self._connect_signals()
        self._refresh_submit_state()

    @property
    def selected_specialist(self) -> str:
        return self._selected_specialist

    def _setup_ui(self) -> None:
        # Root-контейнер диалога: подсказка, список специалистов и action-строка.
        main_container = VContainer(margin=[22, 20, 22, 20], spacing=16)
        self.add_widget(main_container)
        main_container.add_widget(
            Label(
                "Выберите специалиста для назначения на\nзадачу:",
                alignment="left",
                style="TICKET_SPECIALIST_HINT",
            )
        )
        main_container.add_widget_with_stretch(self._build_list(), 1)
        main_container.add_widget(self._build_actions())

    def _build_list(self) -> ScrollContainer:
        # Scroll-list специалистов: прокручиваемая область с вариантами назначения.
        scroll = ScrollContainer(
            spacing=12,
            orientation="v",
            content_margins=[0, 0, 0, 0],
            vertical_scroll_bar_policy="as_needed",
            horizontal_scroll_bar_policy="always_off",
            style="SCROLL_CONTAINER",
        )
        for specialist_name in self._specialists:
            row = _SpecialistRow(specialist_name)
            self._rows[specialist_name] = row
            scroll.add_widget(row)
        return scroll

    def _build_actions(self) -> HContainer:
        # Actions-row диалога: выравнивает кнопки отмены и подтверждения выбора.
        actions = HContainer(spacing=18, content_fit=True)
        actions.add_stretch()
        self._cancel_button = Button(
            "Отмена",
            style="TICKET_DOCUMENT_CANCEL_BUTTON",
            content_fit=True,
        )
        self._cancel_button.set_min_width(160)
        self._cancel_button.set_min_height(56)
        self._submit_button = Button(
            "Выбрать",
            style="TICKET_DOCUMENT_SUBMIT_BUTTON",
            content_fit=True,
        )
        self._submit_button.set_min_width(180)
        self._submit_button.set_min_height(56)
        actions.add_widget(self._cancel_button)
        actions.add_widget(self._submit_button)
        return actions

    def _connect_signals(self) -> None:
        for row in self._rows.values():
            row.clicked.connect(self._on_row_clicked)
            row.activated.connect(self._on_row_activated)
        if self._submit_button is not None:
            self._submit_button.clicked.connect(self._handle_accept)
        if self._cancel_button is not None:
            self._cancel_button.clicked.connect(self.reject)

    def _refresh_submit_state(self) -> None:
        if self._submit_button is not None:
            self._submit_button.set_enabled(bool(self._selected_specialist))

    def _set_selected_specialist(self, specialist_name: str) -> None:
        self._selected_specialist = specialist_name if specialist_name in self._rows else ""
        for row_name, row in self._rows.items():
            row.set_selected(row_name == self._selected_specialist)
        self._refresh_submit_state()

    def _handle_accept(self) -> None:
        if not self._selected_specialist:
            return
        self.accept()

    def _on_row_clicked(self, specialist_name: str) -> None:
        self._set_selected_specialist(specialist_name)

    def _on_row_activated(self, specialist_name: str) -> None:
        self._set_selected_specialist(specialist_name)
        self._handle_accept()
