"""任务管理器Widget

在TUI界面展示当前任务的各步骤及状态。
使用Textual的DataTable组件，避免自定义复杂实现。
"""

from typing import List, Dict, Optional

from textual.app import ComposeResult
from textual.containers import Container, Vertical
from textual.widgets import Label, DataTable, Static
from textual.message import Message
from rich.text import Text as RichText
import logging

logger = logging.getLogger("ketacli.textual")


class TaskManagerWidget(Container):
    """任务管理器主组件

    - 展示步骤列表：序号、标题、状态、迭代次数
    - 提供更新状态的API供逻辑层调用
    """

    DEFAULT_CSS = """
    TaskManagerWidget {
        height: 100%;
    }
    #task-sys-header {
        height: 3;
        background: $surface;
        color: $text;
        padding: 0 1;
        border-bottom: solid $secondary;
    }
    #task-system-prompt {
        height: 8;
        background: $boost;
        color: $text;
        border: heavy $secondary;
        padding: 0 1;
        overflow: auto;
    }
    #task-goal-header {
        height: 3;
        background: $surface;
        color: $text;
        padding: 0 1;
        border-top: solid $secondary;
    }
    #task-goal {
        height: 3;
        background: $panel;
        color: $text;
        padding: 0 1;
        border: solid $secondary;
        overflow: hidden;
    }
    #task-header {
        height: 3;
        background: $surface;
        color: $text;
        padding: 0 1;
        border-top: solid $secondary;
    }
    #task-table {
        height: 1fr;
        border: solid $secondary;
    }
    """

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self._table: Optional[DataTable] = None
        self._sys_static: Optional[Static] = None
        self._goal_static: Optional[Static] = None
        # 内部数据：index -> {title, status, iteration}
        self._rows: Dict[int, Dict] = {}
        self._op_col_index: int = 4

    class ReRunRequested(Message):
        def __init__(self, step_index: int):
            super().__init__()
            self.step_index = step_index

    def compose(self) -> ComposeResult:
        with Vertical():
            yield Label("🧩 系统提示词", id="task-sys-header")
            self._sys_static = Static("", id="task-system-prompt")
            yield self._sys_static
            yield Label("🎯 任务目标", id="task-goal-header")
            self._goal_static = Static("(未设置)", id="task-goal")
            yield self._goal_static
            yield Label("📋 任务状态", id="task-header")
            table = DataTable(id="task-table")
            table.add_columns("步骤", "标题", "状态", "迭代", "操作")
            self._table = table
            yield table
        logger.debug("[tm] compose 完成，表格与静态区域已创建")

    # 公共API
    def set_tasks(self, steps: List[str]) -> None:
        """设置任务步骤列表，默认状态为 pending"""
        if not self._table:
            return
        logger.debug(f"[tm] set_tasks 开始：steps={len(steps or [])}")
        self._table.clear()
        self._rows.clear()
        for i, s in enumerate(steps, start=1):
            title = (s or "").strip()
            row = {
                "title": title,
                "status": "pending",
                "iteration": 0,
            }
            self._rows[i] = row
            cells = self._styled_row_cells(i, title, row["status"], row["iteration"])
            self._table.add_row(*cells)
        logger.debug(f"[tm] set_tasks 完成：rows={len(self._rows)}")

        # 当设置了任务步骤且非空时，自动打开右侧任务侧栏
        sidebar = self.app.query_one("#task-sidebar")
        logger.debug(f"[tm] 侧栏类名（设置前）：{sidebar.classes}")
        if steps:
            if "hidden" in sidebar.classes:
                sidebar.remove_class("hidden")
                logger.debug("[tm] 侧栏显示：移除 hidden")
        else:
            if "hidden" not in sidebar.classes:
                sidebar.add_class("hidden")
                logger.debug("[tm] 侧栏隐藏：添加 hidden")
        logger.debug(f"[tm] 侧栏类名（设置后）：{sidebar.classes}")

    def update_status(self, index: int, status: str, iteration: Optional[int] = None) -> None:
        """更新某一步的状态与迭代次数"""
        if not self._table:
            return
        if index not in self._rows:
            return
        row = self._rows[index]
        row["status"] = status
        if iteration is not None:
            row["iteration"] = iteration
        # 更新整行样式与内容：行序号为 index-1
        try:
            styled_cells = self._styled_row_cells(index, row["title"], row["status"], row["iteration"])
            # 逐单元更新，确保整行背景一致
            for col, cell in enumerate(styled_cells):
                self._table.update_cell(index - 1, col, cell)
        except Exception:
            # 兼容不同版本的DataTable，若update_cell不可用则重绘整表
            self._redraw_table()

        # 任意状态更新时确保侧栏可见
        try:
            sidebar = self.app.query_one("#task-sidebar")
            if "hidden" in sidebar.classes:
                sidebar.remove_class("hidden")
        except Exception:
            pass

    def set_system_prompt(self, prompt: str) -> None:
        """在任务列表上方展示当前任务的系统提示词（可换行、可滚动）"""
        try:
            text = (prompt or "").strip()
        except Exception:
            text = ""
        logger.debug(f"[tm] set_system_prompt：len={len(text)}")
        if self._sys_static:
            # 不截断，允许通过 overflow 滚动查看完整内容
            self._sys_static.update(text)
        # 确保侧栏可见
        sidebar = self.app.query_one("#task-sidebar")
        if "hidden" in sidebar.classes:
            sidebar.remove_class("hidden")
            logger.debug("[tm] set_system_prompt：侧栏显示")
        logger.debug(f"[tm] set_system_prompt：侧栏类名={sidebar.classes}")

    def set_task_goal(self, goal: str) -> None:
        try:
            text = (goal or "").strip()
        except Exception:
            text = ""
        logger.debug(f"[tm] set_task_goal：len={len(text)} preview='{(text or '')[:80]}'")
        if self._goal_static:
            self._goal_static.update(text or "(未设置)")
        # 确保侧栏可见
        sidebar = self.app.query_one("#task-sidebar")
        if "hidden" in sidebar.classes:
            sidebar.remove_class("hidden")
            logger.debug("[tm] set_task_goal：侧栏显示")
        logger.debug(f"[tm] set_task_goal：侧栏类名={sidebar.classes}")

    def _redraw_table(self):
        if not self._table:
            return
        self._table.clear()
        for i in sorted(self._rows.keys()):
            row = self._rows[i]
            cells = self._styled_row_cells(i, row["title"], row["status"], row["iteration"]) 
            self._table.add_row(*cells)

    def _fmt_status(self, status: str) -> str:
        """状态文本（去除颜色标记，仅保留emoji）"""
        mapping = {
            "pending": "待执行 ⏳",
            "in_progress": "执行中 🔧",
            "completed": "已完成 ✅",
            "paused": "已暂停 ⏸️",
            "blocked": "被阻塞 🛑",
        }
        return mapping.get(status, status)

    def _fg_style_for_status(self, status: str) -> str:
        """根据状态返回整行文字颜色样式"""
        # 文字颜色：
        # - completed: 绿色
        # - in_progress: 黄色
        # - pending: 白色
        # 其他状态：合理颜色以便区分
        if status == "completed":
            return "green"
        if status == "in_progress":
            return "yellow"
        if status == "pending":
            return "white"
        if status == "blocked":
            return "red"
        if status == "paused":
            return "red"
        return ""

    def _styled_row_cells(self, i: int, title: str, status: str, iteration: int):
        """构造整行带文字颜色样式的 RichText 单元格"""
        fg = self._fg_style_for_status(status)
        # 每个单元格使用相同前景色，形成整行统一文字颜色
        step_cell = RichText(str(i), style=fg)
        title_cell = RichText(title, style=fg)
        status_cell = RichText(self._fmt_status(status), style=fg)
        iter_cell = RichText(str(iteration), style=fg)
        op_cell = RichText("↻ 重跑", style=fg)
        return (step_cell, title_cell, status_cell, iter_cell, op_cell)

    def on_data_table_cell_selected(self, event: DataTable.CellSelected) -> None:
        try:
            coord = getattr(event, "coordinate", None)
            if coord is None:
                return
            row_index = int(coord.row)
            col_index = int(coord.column)
        except Exception as e:
            logger.error(f"[tm] 点击事件坐标解析异常: {e}")
        try:
            if col_index != self._op_col_index:
                return
            step_index = row_index + 1
            if step_index in self._rows:
                self.post_message(self.ReRunRequested(step_index))
        except Exception as e:
            logger.error(f"[tm] 重跑按钮点击异常: {e}")
