"""TUI components for task tracking and status display."""

from __future__ import annotations

from dataclasses import dataclass
from enum import Enum
from typing import TYPE_CHECKING

from rich.console import Console, Group
from rich.panel import Panel
from rich.text import Text

if TYPE_CHECKING:
    from ..events import EventBus

console = Console()


class TaskStatus(Enum):
    """Task status enum matching TodoWrite format."""

    PENDING = "pending"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"


@dataclass
class Task:
    """A single task item."""

    content: str
    status: TaskStatus = TaskStatus.PENDING
    active_form: str = ""

    def to_dict(self) -> dict[str, str]:
        """Convert to TodoWrite format dict."""
        return {
            "content": self.content,
            "status": self.status.value,
            "activeForm": self.active_form,
        }

    @classmethod
    def from_dict(cls, data: dict[str, str]) -> Task:
        """Create from TodoWrite format dict."""
        return cls(
            content=data.get("content", ""),
            status=TaskStatus(data.get("status", "pending")),
            active_form=data.get("activeForm", ""),
        )


class TaskTracker:
    """Pure task data management - no display logic.

    Responsibilities:
    - Store and manage task list
    - Emit events when tasks change
    - Provide task statistics
    """

    def __init__(self, event_bus: EventBus):
        self._tasks: list[Task] = []
        self._event_bus = event_bus

    @property
    def tasks(self) -> list[Task]:
        """Get copy of task list."""
        return self._tasks.copy()

    def update_from_todowrite(self, todos: list[dict[str, str]]) -> bool:
        """Update tasks from TodoWrite tool output.

        Args:
            todos: List of todo items from TodoWrite

        Returns:
            True if tasks changed, False otherwise
        """
        from ..events import EventType, TaskEvent

        new_tasks = [Task.from_dict(t) for t in todos]
        changed = self._tasks != new_tasks
        self._tasks = new_tasks

        if changed:
            # Publish event for UI components
            self._event_bus.publish_sync(TaskEvent(EventType.TASK_LIST_UPDATED, todos))

        return changed

    def get_stats(self) -> dict[str, int]:
        """Get task statistics.

        Returns:
            Dict with total, pending, in_progress, completed counts
        """
        return {
            "total": len(self._tasks),
            "pending": sum(1 for t in self._tasks if t.status == TaskStatus.PENDING),
            "in_progress": sum(
                1 for t in self._tasks if t.status == TaskStatus.IN_PROGRESS
            ),
            "completed": sum(
                1 for t in self._tasks if t.status == TaskStatus.COMPLETED
            ),
        }

    def get_current_task(self) -> Task | None:
        """Get the currently in-progress task.

        Returns:
            Current task or None if no task is in progress
        """
        for task in self._tasks:
            if task.status == TaskStatus.IN_PROGRESS:
                return task
        return None


class TaskListDisplay:
    """Displays task list as a separate UI component.

    Shows all tasks with their status icons in a panel.
    This is a UI-only component with no business logic.
    """

    def __init__(self, event_bus: EventBus):
        self._event_bus = event_bus

    def render(self, tasks: list[Task]) -> Panel:
        """Render task list as a Rich Panel.

        Args:
            tasks: List of tasks to display

        Returns:
            Rich Panel containing the task list
        """
        if not tasks:
            return Panel(
                Text("Waiting for tasks...", style="dim"),
                title="[bold]Tasks[/bold]",
                border_style="blue",
            )

        stats = {
            "total": len(tasks),
            "completed": sum(1 for t in tasks if t.status == TaskStatus.COMPLETED),
            "in_progress": sum(1 for t in tasks if t.status == TaskStatus.IN_PROGRESS),
            "pending": sum(1 for t in tasks if t.status == TaskStatus.PENDING),
        }

        # Build task lines
        lines = []
        for task in tasks:
            if task.status == TaskStatus.COMPLETED:
                icon, color = "✓", "green"
            elif task.status == TaskStatus.IN_PROGRESS:
                icon, color = "⋯", "yellow"
            else:
                icon, color = "○", "dim"

            text = (
                task.active_form
                if task.status == TaskStatus.IN_PROGRESS and task.active_form
                else task.content
            )
            lines.append(f"[{color}]{icon}[/{color}] {text}")

        # Create panel with task list
        content = "\n".join(lines)
        title = f"[bold]Tasks[/bold] [{stats['completed']}/{stats['total']}]"

        return Panel(
            content,
            title=title,
            border_style="blue",
        )

    def get_renderable(self, tasks: list[Task]) -> Group:
        """Get renderable object for live display.

        Args:
            tasks: List of tasks to display

        Returns:
            Rich Group containing the task panel
        """
        return Group(self.render(tasks))


class StatusDisplay:
    """Handles status message display (current action).

    Shows what the agent is currently doing.
    This is a UI-only component with no business logic.
    """

    def __init__(self, event_bus: EventBus):
        self._event_bus = event_bus

    def format_status_message(self, message: str) -> str:
        """Format a simple status message.

        Args:
            message: Status message to format

        Returns:
            Formatted status message
        """
        return message

    def format_tool_message(self, tool_name: str, tool_input: dict) -> str:
        """Format a human-readable message for a tool call.

        Args:
            tool_name: Name of the tool being called
            tool_input: Input parameters for the tool

        Returns:
            Human-readable action description
        """
        if tool_name == "Read":
            path = tool_input.get("file_path", "")
            filename = path.split("/")[-1] if "/" in path else path
            return f"Reading {filename}"
        elif tool_name == "Write":
            path = tool_input.get("file_path", "")
            filename = path.split("/")[-1] if "/" in path else path
            return f"Writing {filename}"
        elif "list_modules" in tool_name:
            return "Listing project modules"
        elif "get_module_info" in tool_name:
            module = tool_input.get("module_path", "")
            return f"Analyzing module {module}"
        elif "get_function_signature" in tool_name:
            func = tool_input.get("function_name", "")
            return f"Getting signature of {func}"
        elif "get_class_hierarchy" in tool_name:
            cls = tool_input.get("class_name", "")
            return f"Analyzing class {cls}"
        elif "get_imports" in tool_name:
            module = tool_input.get("module_path", "")
            return f"Analyzing imports of {module}"
        elif "get_function_calls" in tool_name:
            func = tool_input.get("function_name", "")
            return f"Tracing calls from {func}"
        elif "get_callers" in tool_name:
            func = tool_input.get("function_name", "")
            return f"Finding callers of {func}"
        else:
            # Clean up tool name for display
            clean_name = tool_name.replace("mcp__nanowiki-analyzer__", "")
            return f"Using {clean_name}"

    def print_summary(self, tasks: list[Task]) -> None:
        """Print final task summary to console.

        Args:
            tasks: List of tasks to summarize
        """
        if not tasks:
            return

        stats = {
            "total": len(tasks),
            "completed": sum(1 for t in tasks if t.status == TaskStatus.COMPLETED),
            "in_progress": sum(1 for t in tasks if t.status == TaskStatus.IN_PROGRESS),
            "pending": sum(1 for t in tasks if t.status == TaskStatus.PENDING),
        }

        console.print(
            f"\n[bold]Task Progress:[/bold] "
            f"{stats['completed']}/{stats['total']} completed, "
            f"{stats['in_progress']} in progress, "
            f"{stats['pending']} pending"
        )

        for i, task in enumerate(tasks, 1):
            if task.status == TaskStatus.COMPLETED:
                icon, color = "✓", "green"
            elif task.status == TaskStatus.IN_PROGRESS:
                icon, color = "⋯", "yellow"
            else:
                icon, color = "○", "dim"

            text = (
                task.active_form
                if task.status == TaskStatus.IN_PROGRESS and task.active_form
                else task.content
            )
            console.print(f"  {i}. [{color}]{icon}[/{color}] {text}")
