"""Rendering helper for the transforms insight sidecar."""

from __future__ import annotations

from typing import Literal

from ...core.plan import FilterClause
from .insight_panel_base import _BODY_STYLE, InsightPanelBase, PanelLine

_STATUS_DISABLED: Literal["disabled"] = "disabled"
_STATUS_UNAVAILABLE: Literal["unavailable"] = "unavailable"
_STATUS_READY: Literal["ready"] = "ready"


class TransformsInsightPanel(InsightPanelBase):
    """Text-only panel for active filters and sorts."""

    def __init__(self, *, width: int = 32) -> None:
        super().__init__(title="Transforms", width=width)
        self._status: Literal["disabled", "unavailable", "ready"] = _STATUS_READY
        self._status_message: str = ""
        self._filters: tuple[FilterClause, ...] = ()
        self._sorts: tuple[tuple[str, bool], ...] = ()

    def set_disabled(self, reason: str) -> None:
        self._status = _STATUS_DISABLED
        self._status_message = reason
        self._title = "Transforms"

    def set_unavailable(self, reason: str) -> None:
        self._status = _STATUS_UNAVAILABLE
        self._status_message = reason
        self._title = "Transforms"

    def set_transforms(
        self,
        *,
        filters: tuple[FilterClause, ...],
        sorts: tuple[tuple[str, bool], ...],
    ) -> None:
        self._status = _STATUS_READY
        self._status_message = ""
        self._filters = filters
        self._sorts = sorts
        count = len(filters) + len(sorts)
        self._title = f"Transforms ({count})" if count else "Transforms"

    def _render_body_lines(self) -> list[PanelLine]:
        status = self._status
        if status == _STATUS_DISABLED:
            return self._render_message_block(
                "Status",
                [
                    self._status_message or "Insight panel hidden.",
                    "Toggle with `i` or :insight.",
                ],
            )
        if status == _STATUS_UNAVAILABLE:
            return self._render_message_block(
                "Status",
                [self._status_message or "Insight unavailable for this view."],
            )

        lines: list[PanelLine] = []
        lines.extend(self._render_filters_section())
        lines.extend(self._render_sorts_section())
        return lines

    def _render_filters_section(self) -> list[PanelLine]:
        lines: list[PanelLine] = []
        self._append_section_title(lines, "Filters")
        if not self._filters:
            lines.append(self._plain_line("—", _BODY_STYLE))
            return lines
        for idx, clause in enumerate(self._filters, start=1):
            kind_label = "Expr: " if clause.kind == "expr" else "SQL: "
            text = f"{kind_label}{clause.text}"
            lines.extend(self._wrap_labeled_line(f"{idx}. ", text))
        return lines

    def _render_sorts_section(self) -> list[PanelLine]:
        lines: list[PanelLine] = []
        self._append_section_title(lines, "Sorts", pad_before=True)
        if not self._sorts:
            lines.append(self._plain_line("—", _BODY_STYLE))
            return lines
        for idx, (column, desc) in enumerate(self._sorts, start=1):
            direction = "desc" if desc else "asc"
            text = f"{column} {direction}"
            lines.extend(self._wrap_labeled_line(f"{idx}. ", text))
        return lines

    def _wrap_labeled_line(self, label: str, text: str) -> list[PanelLine]:
        indent = " " * len(label)
        wrapped = self._wrap_text(
            text,
            initial_indent=label,
            subsequent_indent=indent,
        )
        return [self._plain_line(line, _BODY_STYLE) for line in wrapped]


__all__ = ["TransformsInsightPanel"]
