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

"""Самостоятельная страница архива Ticket."""

from __future__ import annotations

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QSizePolicy

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

from application import TaskApplicationService
from domain import ArchiveRecordSnapshot, TicketDocumentSnapshot
from ui.cards import TaskCardView
from .archive_view_helpers import (
    build_preview_lines,
    cycle_token_from_record,
    record_to_task_snapshot,
)


# -------------------------------------------------------------------------
# Страница архива
# -------------------------------------------------------------------------

class ArchivePage(SContainer):
    """Страница архива с карточками в стиле доски задач и панелью просмотра."""

    def __init__(self, application: TaskApplicationService, parent=None):
        super().__init__(width_percent=100, height_percent=100, parent=parent)
        self._application = application
        self._records: dict[str, ArchiveRecordSnapshot] = {}
        self._selected_record_key: str | None = None
        self._card_host: VContainer | None = None
        self._preview: TextInput | None = None
        self._empty_list_label: Label | None = None
        self._cards: dict[str, TaskCardView] = {}
        self._card_key_by_task_id: dict[int, str] = {}
        self._setup_ui()
        self._connect_signals()
        self._reload_records()

    # -- UI ----------------------------------------------------------------

    def _setup_ui(self) -> None:
        board_row = HContainer(
            margin=[0, 0, 0, 0],
            height_percent=100,
            spacing=16,
            style="TICKET_SURFACE_HOST",
            parent=self,
        )

        board_row.add_widget(self._build_list_column())
        board_row.add_widget(self._build_preview_column())

    def _build_list_column(self) -> SContainer:
        column = SContainer(spacing=12, parent=None)

        header = HContainer(
            height_percent=5.37,
            margin=0,
            spacing=16,
            content_fit=False,
            style="TICKET_BOARD_COLUMN_HEADER",
        )
        header.add_widget(
            Label("Архив задач", margin=[12, 0, 0, 0], style="TICKET_BOARD_COLUMN_TITLE"),
        )
        header.add_stretch()

        body = SContainer(
            margin=0,
            style="TICKET_REPORT_COLUMN_BODY",
        )

        scroll = ScrollContainer(
            margin=0,
            spacing=0,
            orientation="v",
            vertical_scroll_bar_policy="always_off",
            horizontal_scroll_bar_policy="always_off",
            style="SCROLL_CONTAINER",
            parent=body,
        )
        scroll.scroll_area.verticalScrollBar().setSingleStep(48)

        self._card_host = VContainer(
            spacing=12,
            content_fit=False,
            parent=scroll,
        )
        self._card_host.set_size_policy(
            QSizePolicy.Policy.Expanding,
            QSizePolicy.Policy.Fixed,
        )

        column.add_widget(header)
        column.add_widget(body)
        return column

    def _build_preview_column(self) -> SContainer:
        column = SContainer(spacing=12, width_percent=79.83, parent=None)

        header = HContainer(
            height_percent=5.37,
            margin=0,
            spacing=16,
            content_fit=False,
            style="TICKET_BOARD_COLUMN_HEADER",
        )
        header.add_widget(
            Label("Просмотр", margin=[12, 0, 0, 0], style="TICKET_BOARD_COLUMN_TITLE"),
        )
        header.add_stretch()

        body = SContainer(
            margin=0,
            style="TICKET_REPORT_PREVIEW_BODY",
        )
        preview_inner = VContainer(margin=0, spacing=0, parent=body)
        self._preview = TextInput(style="TICKET_REPORT_PREVIEW_AREA", multiline=True)
        self._preview.set_read_only(True)
        self._preview._input.setVerticalScrollBarPolicy(
            Qt.ScrollBarPolicy.ScrollBarAlwaysOff,
        )
        preview_inner.add_widget_with_stretch(self._preview, 1)

        column.add_widget(header)
        column.add_widget(body)
        return column

    # -- Signals -----------------------------------------------------------

    def _connect_signals(self) -> None:
        self._application.task_updated.connect(self._reload_records)
        self._application.task_removed.connect(self._reload_records)
        self._application.state_loaded.connect(self._reload_records)

    # -- Data refresh ------------------------------------------------------

    @staticmethod
    def _record_key(record: ArchiveRecordSnapshot) -> str:
        token = cycle_token_from_record(record)
        return f"{record.task_id}_{token}" if token else str(record.task_id)

    def _reload_records(self, *_args) -> None:
        records = self._application.list_archive_records()
        self._records = {self._record_key(r): r for r in records}
        self._rebuild_cards(records)

        if self._selected_record_key in self._records:
            self._select_record(self._selected_record_key, update_preview=True)
            return

        self._selected_record_key = None
        self._clear_preview()

    def _rebuild_cards(self, records: list[ArchiveRecordSnapshot]) -> None:
        if self._card_host is None:
            return

        for card in list(self._cards.values()):
            self._card_host.remove_widget(card)
            card.setParent(None)
        self._cards.clear()
        self._card_key_by_task_id.clear()

        if self._empty_list_label is not None:
            self._card_host.remove_widget(self._empty_list_label)
            self._empty_list_label.setParent(None)
            self._empty_list_label = None

        if not records:
            self._empty_list_label = Label(
                "Архивные задачи пока отсутствуют.",
                alignment="left",
                style="TICKET_REPORT_EMPTY_LABEL",
            )
            self._card_host.insert_widget(0, self._empty_list_label)
            return

        for index, record in enumerate(records):
            key = self._record_key(record)
            synthetic_task = record_to_task_snapshot(record)
            card = TaskCardView(synthetic_task)
            card.card_clicked.connect(self._on_card_clicked)
            self._cards[key] = card
            self._card_key_by_task_id[record.task_id] = key
            self._card_host.insert_widget(index, card)

    # -- Selection ---------------------------------------------------------

    def _select_record(self, key: str | None, update_preview: bool) -> None:
        normalized = key if key in self._records else None
        self._selected_record_key = normalized
        if not update_preview:
            return
        record = self._records.get(normalized) if normalized is not None else None
        if record is None:
            self._clear_preview()
            return
        self._render_record(record)

    def _render_record(self, record: ArchiveRecordSnapshot) -> None:
        if self._preview is None:
            return
        documents = self._load_cycle_documents(record)
        lines = build_preview_lines(record, documents)
        self._preview.set_text("\n".join(lines))

    def _load_cycle_documents(
        self, record: ArchiveRecordSnapshot,
    ) -> list[TicketDocumentSnapshot]:
        """Загрузить только документы текущего цикла задачи."""
        cycle_token = cycle_token_from_record(record)
        all_docs = self._application.list_documents()
        return [
            d for d in all_docs
            if d.task_id == record.task_id and cycle_token in d.document_id
        ]

    def _clear_preview(self) -> None:
        if self._preview is not None:
            self._preview.set_text("")

    def _on_card_clicked(self, card_id: object) -> None:
        if isinstance(card_id, int):
            key = self._card_key_by_task_id.get(card_id)
            if key is not None:
                self._select_record(key, update_preview=True)

    def showEvent(self, event) -> None:
        super().showEvent(event)
        self._reload_records()
