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

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

from __future__ import annotations

from PySide6.QtCore import Qt, Signal
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 TicketDocumentSnapshot


# -------------------------------------------------------------------------
# Карточка отчёта (по образцу TaskCardView)
# -------------------------------------------------------------------------

class _ReportCardView(SContainer):
    """Карточка отчёта: заголовок, дата+учреждение, аппарат+кабинет."""

    card_clicked = Signal(str)

    def __init__(self, document: TicketDocumentSnapshot, parent=None):
        super().__init__(
            width_percent=100,
            margin=0,
            content_fit=True,
            parent=parent,
        )
        self._document_id = document.document_id
        self._title_label: Label | None = None
        self._subtitle_label: Label | None = None
        self._meta_label: Label | None = None
        self._selected = False
        self._height_sync_in_progress = False
        self.setObjectName("ticket_report_card")
        self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
        self.setCursor(Qt.CursorShape.PointingHandCursor)
        self.set_size_policy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
        self._setup_ui()
        self._fill(document)

    @property
    def document_id(self) -> str:
        return self._document_id

    def set_selected(self, selected: bool) -> None:
        self._selected = selected
        self._apply_root_style()

    def _setup_ui(self) -> None:
        content = SContainer(
            width_percent=100,
            height_percent=100,
            margin=8,
            spacing=0,
            style="TICKET_REPORT_CARD_CONTENT",
            parent=self,
        )
        text_column = VContainer(
            width_percent=100,
            spacing=2,
            parent=content,
        )

        self._title_label = Label("", alignment="left", parent=text_column)
        self._subtitle_label = Label("", alignment="left", parent=text_column)
        self._meta_label = Label("", alignment="left", parent=text_column)

    def _fill(self, document: TicketDocumentSnapshot) -> None:
        title = document.title or "Отчёт"
        created_at = document.created_at.strftime("%d.%m.%Y %H:%M")
        facility = document.payload.get("facility") or document.location or ""
        # Убрать название аппарата в скобках (дублирует 3-ю строку)
        if "(" in facility:
            facility = facility[:facility.index("(")].strip()
        device = document.payload.get("device") or ""
        cabinet = document.payload.get("cabinet") or ""

        subtitle_parts = [p for p in (created_at, facility) if p]
        meta_parts = [p for p in (device, cabinet) if p]

        if self._title_label is not None:
            self._title_label.set_text(title)
        if self._subtitle_label is not None:
            self._subtitle_label.set_text(" , ".join(subtitle_parts))
        if self._meta_label is not None:
            self._meta_label.set_text(" - ".join(meta_parts))

        self._apply_root_style()
        self._apply_text_styles()

    def _apply_root_style(self) -> None:
        if self._selected:
            self.style("TICKET_REPORT_CARD_ROOT_SELECTED")
        else:
            self.style("TICKET_REPORT_CARD_ROOT")

    def _apply_text_styles(self) -> None:
        if self._title_label is not None:
            self._title_label.style("TICKET_REPORT_CARD_TITLE")
        if self._subtitle_label is not None:
            self._subtitle_label.style("TICKET_REPORT_CARD_SUBTITLE")
        if self._meta_label is not None:
            self._meta_label.style("TICKET_REPORT_CARD_META")

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

    def resizeEvent(self, event) -> None:
        super().resizeEvent(event)
        self._sync_card_height()

    def _sync_card_height(self) -> None:
        if self._height_sync_in_progress or self.width() <= 0:
            return
        target_height = max(1, round(self.width() / 2.745))
        if self.height() == target_height:
            return
        self._height_sync_in_progress = True
        self.setFixedHeight(target_height)
        self._height_sync_in_progress = False


# -------------------------------------------------------------------------
# Страница отчётов
# -------------------------------------------------------------------------

class ReportsPage(SContainer):
    """Страница отчётов, полностью локализованная внутри собственного класса."""

    def __init__(self, application: TaskApplicationService, parent=None):
        super().__init__(width_percent=100, height_percent=100, parent=parent)
        self._application = application
        self._documents: dict[str, TicketDocumentSnapshot] = {}
        self._selected_document_id: 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, _ReportCardView] = {}
        self._setup_ui()
        self._connect_signals()
        self._apply_initial_state()
        self._reload_documents()

    # -- 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 (как в _TicketBoardColumn, но без счётчика)
        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
        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
        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 — preview
        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)
        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_documents)
        self._application.state_loaded.connect(self._reload_documents)

    def _apply_initial_state(self) -> None:
        self._clear_preview()

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

    def _reload_documents(self, *_args) -> None:
        ordered_documents = self._application.list_documents("report")
        self._documents = {
            document.document_id: document
            for document in ordered_documents
        }
        self._rebuild_cards(ordered_documents)

        if self._selected_document_id in self._documents:
            self._select_document(self._selected_document_id, update_preview=True)
            return

        self._selected_document_id = None
        self._update_card_selection()
        self._clear_preview()

    def _rebuild_cards(self, documents: list[TicketDocumentSnapshot]) -> 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()

        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 documents:
            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, document in enumerate(documents):
            card = _ReportCardView(document)
            card.card_clicked.connect(self._on_card_clicked)
            self._cards[document.document_id] = card
            self._card_host.insert_widget(index, card)

        self._update_card_selection()

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

    def _select_document(self, document_id: str | None, update_preview: bool) -> None:
        normalized = document_id if document_id in self._documents else None
        self._selected_document_id = normalized
        self._update_card_selection()

        if not update_preview:
            return

        document = self._current_document()
        if document is None:
            self._clear_preview()
            return
        self._render_document(document)

    def _update_card_selection(self) -> None:
        for doc_id, card in self._cards.items():
            card.set_selected(doc_id == self._selected_document_id)

    def _current_document(self) -> TicketDocumentSnapshot | None:
        if self._selected_document_id is None:
            return None
        return self._documents.get(self._selected_document_id)

    def _render_document(self, document: TicketDocumentSnapshot) -> None:
        if self._preview is None:
            return
        self._preview.set_text(document.content or document.summary or document.title)

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

    def _on_card_clicked(self, document_id: str) -> None:
        self._select_document(document_id, update_preview=True)

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