"""TUI 底部输入：多行 TextArea + ``/`` 命令行幽灵补全；单行 Input 保留供兼容。"""

from __future__ import annotations

from textual import events
from textual.binding import Binding
from textual.message import Message
from textual.suggester import Suggester
from textual.widgets import Input, TextArea


# 列表顺序 = 同前缀时 Tab/→ 采纳的优先级（不再按字符串总长最短，避免误优先 /task ai）
_COMPLETIONS: list[str] = [
    "/?",
    "/q",
    "/exit",
    "/quit",
    "/help",
    "/work ",
    "/chat ",
    "/chat stop",
    "/doc ",
    "/llm ",
    "/agent ",
    "/history ",
    "/history list",
    "/history clear",
    "/history copy ",
    "/history help",
    "/task ",
    "/task stop",
    "/task list",
    "/task clear",
    "/task help",
    "/task shell ",
    "/task ai ",
    "/task dummy ",
]

_POS: dict[str, int] = {c: i for i, c in enumerate(_COMPLETIONS)}


def pick_slash_completion(value: str) -> str | None:
    """
    返回比当前输入更长、且以前缀匹配的第一条补全（最短总长优先，其次列表顺序）。
    非 `/` 开头返回 None。
    """
    if not value.startswith("/"):
        return None
    vn = value.casefold()
    matches: list[str] = []
    for c in _COMPLETIONS:
        if len(c) <= len(vn):
            continue
        if c.casefold().startswith(vn):
            matches.append(c)
    if not matches:
        return None
    return min(matches, key=lambda c: _POS[c])


class SlashCommandSuggester(Suggester):
    """仅对以 ``/`` 开头的行给出幽灵补全；普通聊天不提示。"""

    def __init__(self) -> None:
        super().__init__(case_sensitive=False, use_cache=True)

    async def get_suggestion(self, value: str) -> str | None:
        # case_sensitive=False 时 value 已为 casefold
        if not value.startswith("/"):
            return None
        return pick_slash_completion(value)


class ChatInput(Input):
    """单行输入（遗留）：Tab / → 采纳幽灵补全。"""

    BINDINGS = [
        *Input.BINDINGS,
        Binding("tab", "accept_suggestion_tab", "补全", show=False),
    ]

    def action_accept_suggestion_tab(self) -> None:
        if self.cursor_at_end and self._suggestion:
            self.action_cursor_right()


class ChatTextArea(TextArea):
    """多行聊天输入：**Enter** 发送；**Shift+Enter** 换行。

    当前行若以 ``/`` 开头，显示与单行模式相同的幽灵补全，**→** 采纳（与 TextArea 默认一致）。
    """

    BINDINGS = TextArea.BINDINGS

    class Submitted(Message):
        """用户按 Enter 提交整段文本（可含多行）。"""

        def __init__(self, chat: "ChatTextArea", value: str) -> None:
            self.chat = chat
            self.value = value
            super().__init__()

        @property
        def control(self) -> "ChatTextArea":
            return self.chat

    def update_suggestion(self) -> None:
        """仅当光标在某行且该行以 ``/`` 开头时给出补全后缀（与 Input+Suggester 行为对齐）。"""
        row, _col = self.cursor_location
        lines = self.text.split("\n")
        if row < 0 or row >= len(lines):
            self.suggestion = ""
            return
        current_line = lines[row]
        if not current_line.startswith("/"):
            self.suggestion = ""
            return
        comp = pick_slash_completion(current_line)
        if comp and len(comp) > len(current_line):
            self.suggestion = comp[len(current_line) :]
        else:
            self.suggestion = ""

    async def _on_key(self, event: events.Key) -> None:
        """Enter 发送；Shift+Enter 插入换行（与常见 IM 一致）。"""
        if not self.read_only and event.key == "enter":
            if event.shift:
                await super()._on_key(event)
                return
            event.stop()
            event.prevent_default()
            self.action_submit_chat()
            return
        await super()._on_key(event)

    def action_submit_chat(self) -> None:
        raw = self.text
        if not raw.strip():
            return
        self.post_message(self.Submitted(self, raw))
        self.text = ""
        self.suggestion = ""
