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

"""Dialog-экран подробностей задачи Ticket в ecco-геометрии."""

from __future__ import annotations

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

from application.ticket_application_api import TicketApplicationApi
from domain import TicketTaskSnapshot
from ui.cards.task_card_pixmap_factory import (
    build_placeholder_avatar_pixmap,
    load_avatar_pixmap,
)
from .task_details_actions import TaskDetailsActions
from .task_details_view_data import (
    build_employee_view_data,
    build_task_stage_rows,
    build_task_summary_rows,
    can_archive_task,
    can_refuse_task,
)
from .task_stage_action_row import TaskStageActionRow


class TaskDetailsDialog(Dialog):
    """Диалог подробностей задачи и доступных действий по этапам."""

    _SUMMARY_TITLES = (
        "Учреждение",
        "Оборудование",
        "Кабинет",
        "Назначение",
    )
    _STAGE_ORDER = (
        "specialist",
        "diagnostic",
        "repair",
        "acceptance",
    )

    def __init__(
        self,
        application: TicketApplicationApi,
        task_id: int,
        parent=None,
    ):
        self._application = application
        self._task_id = task_id
        self._task: TicketTaskSnapshot | None = None
        self._actions = TaskDetailsActions(application)
        self._summary_value_labels: dict[str, Label] = {}
        self._stage_rows: dict[str, TaskStageActionRow] = {}
        self._employee_avatar_label: Label | None = None
        self._employee_name_label: Label | None = None
        self._employee_role_label: Label | None = None
        self._refuse_button: Button | None = None
        super().__init__(
            title="Подробности",
            width=360,
            height=600,
            modal=True,
            parent=parent,
        )
        self._setup_ui()
        self._connect_signals()
        self._reload_task()

    def _setup_ui(self) -> None:
        # Root-контейнер окна: раскладывает summary, этапы, сотрудника и footer по вертикали.
        root = VContainer(margin=[24, 20, 24, 20], spacing=20)
        self.add_widget(root)
        root.add_widget(self._build_summary_section())
        root.add_widget(Label("", style="TICKET_DETAILS_DIVIDER"))
        root.add_widget(self._build_stages_section())
        root.add_widget(self._build_employee_section())
        root.add_stretch()
        root.add_widget(self._build_footer_section())

    def _build_summary_section(self) -> VContainer:
        # Summary-section: верхняя сводка по задаче с основными идентификационными полями.
        summary = VContainer(spacing=12, content_fit=True)
        for title in self._SUMMARY_TITLES:
            summary.add_widget(self._build_summary_row(title))
        return summary

    def _build_summary_row(self, title: str) -> HContainer:
        # Summary-row: одна горизонтальная строка конкретного поля в блоке сводки.
        row = HContainer(spacing=10, content_fit=True)
        title_label = Label(
            f"{title}:",
            alignment="left",
            style="TICKET_DETAILS_SUMMARY_TITLE",
        )
        value_label = Label(
            "",
            alignment="left",
            style="TICKET_DETAILS_SUMMARY_VALUE",
        )
        self._summary_value_labels[title] = value_label
        row.add_widget(title_label)
        row.add_widget_with_stretch(value_label, 1)
        return row

    def _build_stages_section(self) -> VContainer:
        # Stages-section: блок со списком шагов выполнения и доступных действий по ним.
        section = VContainer(spacing=12, content_fit=True)
        section.add_widget(
            Label(
                "Этапы выполнения заявки",
                alignment="left",
                style="TICKET_DETAILS_SECTION_TITLE",
            )
        )
        # Stage-list: стек интерактивных строк этапов внутри секции stages.
        stage_list = VContainer(spacing=12, content_fit=True)
        for stage_key in self._STAGE_ORDER:
            stage_row = TaskStageActionRow(stage_key)
            stage_row.clicked.connect(self._on_stage_clicked)
            self._stage_rows[stage_key] = stage_row
            stage_list.add_widget(stage_row)
        section.add_widget(stage_list)
        return section

    def _build_employee_section(self) -> VContainer:
        # Employee-section: отдельный блок ответственного сотрудника и его служебной информации.
        section = VContainer(spacing=12, content_fit=True)
        section.add_widget(
            Label(
                "Ответственный сотрудник",
                alignment="left",
                style="TICKET_DETAILS_SECTION_TITLE",
            )
        )

        # Employee-row: горизонтальная строка карточки сотрудника с аватаром и текстом.
        employee_row = HContainer(spacing=16, content_fit=True)
        self._employee_avatar_label = Label("", style="TICKET_TASK_CARD_AVATAR_IMAGE")
        self._employee_avatar_label.set_fixed_size(64, 64)
        self._employee_name_label = Label(
            "",
            alignment="left",
            style="TICKET_DETAILS_EMPLOYEE_NAME",
        )
        self._employee_role_label = Label(
            "",
            alignment="left",
            style="TICKET_DETAILS_EMPLOYEE_ROLE",
        )

        # Info-column: вертикальный столбец имени и должности рядом с аватаром.
        info_column = VContainer(spacing=2, content_fit=True)
        info_column.add_widget(self._employee_name_label)
        info_column.add_widget(self._employee_role_label)

        employee_row.add_widget(self._employee_avatar_label)
        employee_row.add_widget_with_stretch(info_column, 1)
        section.add_widget(employee_row)
        return section

    def _build_footer_section(self) -> HContainer:
        # Footer-row: нижняя линия действий с центрированными кнопками.
        footer = HContainer(spacing=12, content_fit=True)
        self._refuse_button = Button(
            "Отказать в обслуживании",
            style="TICKET_DETAILS_REFUSE_BUTTON",
            content_fit=True,
        )
        self._archive_button = Button(
            "В архив",
            style="TICKET_DETAILS_REFUSE_BUTTON",
            content_fit=True,
        )
        footer.add_stretch()
        footer.add_widget(self._refuse_button)
        footer.add_widget(self._archive_button)
        footer.add_stretch()
        return footer

    def _connect_signals(self) -> None:
        self._application.task_updated.connect(self._on_task_updated)
        self._application.task_removed.connect(self._on_task_removed)
        if self._refuse_button is not None:
            self._refuse_button.clicked.connect(self._on_refuse_clicked)
        if self._archive_button is not None:
            self._archive_button.clicked.connect(self._on_archive_clicked)

    def _reload_task(self) -> None:
        task = self._application.get_task(self._task_id)
        if task is None:
            self.reject()
            return
        self._task = task
        self._update_view(task)

    def _update_view(self, task: TicketTaskSnapshot) -> None:
        for title, value in build_task_summary_rows(task):
            label = self._summary_value_labels.get(title)
            if label is not None:
                label.set_text(value)
                label.set_tooltip(value)

        for stage_view in build_task_stage_rows(task):
            stage_row = self._stage_rows.get(stage_view.key)
            if stage_row is not None:
                stage_row.configure(
                    text=stage_view.text,
                    icon_path=stage_view.icon_path,
                    emphasized=stage_view.emphasized,
                    clickable=stage_view.clickable,
                )

        self._update_employee_section(task)
        if self._refuse_button is not None:
            self._refuse_button.set_visible(can_refuse_task(task))
        if self._archive_button is not None:
            self._archive_button.set_visible(can_archive_task(task))

    def _update_employee_section(self, task: TicketTaskSnapshot) -> None:
        employee_data = build_employee_view_data(task)
        if self._employee_name_label is not None:
            self._employee_name_label.set_text(employee_data["name"])
        if self._employee_role_label is not None:
            role_text = employee_data["position"].strip()
            self._employee_role_label.set_text(role_text)
            self._employee_role_label.set_visible(bool(role_text))
        if self._employee_avatar_label is None:
            return

        avatar_pixmap = load_avatar_pixmap(
            employee_data["photo_path"],
            64,
            64,
            padding=2,
        )
        if avatar_pixmap is None:
            avatar_pixmap = build_placeholder_avatar_pixmap(64)
        self._employee_avatar_label.set_pixmap(avatar_pixmap)

    def _on_task_updated(self, task: TicketTaskSnapshot) -> None:
        if task.task_id != self._task_id:
            return
        self._task = task
        self._update_view(task)

    def _on_task_removed(self, task_id: int) -> None:
        if task_id == self._task_id:
            self.reject()

    def _on_stage_clicked(self, stage_key: str) -> None:
        if self._task is None:
            return
        if stage_key == "specialist":
            self._actions.assign_specialist(self._task, self)
            return
        if stage_key == "diagnostic":
            self._actions.sign_diagnostic(self._task, self)
            return
        if stage_key == "repair":
            self._actions.sign_repair(self._task, self)
            return
        if stage_key == "acceptance":
            self._actions.sign_acceptance(self._task, self)

    def _on_refuse_clicked(self) -> None:
        if self._task is None:
            return
        snapshot = self._actions.refuse_task(self._task, self)
        if snapshot is not None:
            self.accept()

    def _on_archive_clicked(self) -> None:
        if self._task is None:
            return
        snapshot = self._actions.archive_task(self._task, self)
        if snapshot is not None:
            self.accept()
