"""Welcome screen widget for the chat interface.

Displays quick access to frequently used agents and recent sessions,
allowing users to start chatting with minimal friction.
"""

from datetime import datetime, timezone
from typing import TYPE_CHECKING, Any
from uuid import UUID

from textual import on, work
from textual.app import ComposeResult
from textual.binding import Binding
from textual.containers import Vertical
from textual.widget import Widget
from textual.widgets import OptionList, Static
from textual.widgets.option_list import Option

from alloy_runtime_sdk.api_client.client import ApiClient
from alloy_runtime_types.dtos.agents import AgentSummary
from alloy_runtime_types.dtos.sessions import SessionSummary

from cli.tui.chat.messages import AgentQuickSelected, RecentSessionSelected

if TYPE_CHECKING:
    from cli.tui.app import AlloyRuntimeApp


class WelcomeScreen(Widget):
    """Welcome screen with quick access to agents and recent sessions.

    Features:
        - Shows top agents by usage (named session count)
        - Shows recent named sessions for quick resumption
        - Number keys (1-9) for instant agent selection
        - Keyboard navigation with arrow keys

    Posts Messages:
        - AgentQuickSelected: When user selects an agent
        - RecentSessionSelected: When user selects a recent session
    """

    app: "AlloyRuntimeApp"

    BINDINGS = [
        Binding("1", "select_agent(0)", "Agent 1", show=False),
        Binding("2", "select_agent(1)", "Agent 2", show=False),
        Binding("3", "select_agent(2)", "Agent 3", show=False),
        Binding("4", "select_agent(3)", "Agent 4", show=False),
        Binding("5", "select_agent(4)", "Agent 5", show=False),
        Binding("6", "select_agent(5)", "Agent 6", show=False),
        Binding("7", "select_agent(6)", "Agent 7", show=False),
        Binding("8", "select_agent(7)", "Agent 8", show=False),
        Binding("9", "select_agent(8)", "Agent 9", show=False),
    ]

    DEFAULT_CSS = """
    WelcomeScreen {
        width: 100%;
        height: auto;
        padding: 1 2;
    }
    
    WelcomeScreen #welcome-title {
        text-align: center;
        text-style: bold;
        margin-bottom: 1;
    }
    
    WelcomeScreen .section-title {
        margin-top: 1;
        margin-bottom: 0;
        text-style: bold;
        color: $accent;
    }
    
    WelcomeScreen .section-divider {
        color: $text-muted;
        margin-bottom: 0;
    }
    
    WelcomeScreen #agents-list {
        height: auto;
        max-height: 12;
        margin-bottom: 1;
        background: transparent;
        border: none;
    }
    
    WelcomeScreen #sessions-list {
        height: auto;
        max-height: 6;
        margin-bottom: 1;
        background: transparent;
        border: none;
    }
    
    WelcomeScreen .empty-hint {
        color: $text-muted;
        text-style: italic;
        padding: 0 1;
    }
    
    WelcomeScreen #footer-hints {
        margin-top: 1;
        color: $text-muted;
    }
    """

    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        self._agents: list[AgentSummary] = []
        self._sessions: list[SessionSummary] = []
        self._loading = True

    def compose(self) -> ComposeResult:
        with Vertical():
            yield Static("Welcome to Alloy Runtime", id="welcome-title")

            yield Static("Quick Start", classes="section-title")
            yield Static("─" * 40, classes="section-divider")
            yield OptionList(id="agents-list")

            yield Static("Recent Sessions", classes="section-title")
            yield Static("─" * 40, classes="section-divider")
            yield OptionList(id="sessions-list")

            yield Static(
                "[dim][Ctrl+N][/] New session  [dim]/[/] Search sessions  [dim][?][/] Help",
                id="footer-hints",
            )

    def on_mount(self) -> None:
        """Load agents and sessions when mounted."""
        self._load_data()

    @work(exclusive=True)
    async def _load_data(self) -> None:
        """Load frequently used agents and recent sessions."""
        try:
            client = await self._get_client()

            # Load agents sorted by usage (last 90 days)
            agents_response = await client.list_agents(
                sort_by="usage",
                usage_days=90,
                limit=7,
            )
            self._agents = list(agents_response.agents)

            # Load recent named sessions
            sessions_response = await client.list_sessions(
                named_only=True,
                limit=5,
            )
            self._sessions = list(sessions_response.sessions)

            self._loading = False
            self._update_agents_list()
            self._update_sessions_list()

        except Exception as e:
            self._loading = False
            self._show_error(str(e))

    async def _get_client(self) -> ApiClient:
        """Get the shared server client."""
        return await self.app.store.get_client()

    def _update_agents_list(self) -> None:
        """Update the agents option list."""
        agents_list = self.query_one("#agents-list", OptionList)
        agents_list.clear_options()

        if not self._agents:
            agents_list.add_option(
                Option(
                    "[dim italic]No agents yet. Press Ctrl+N to start.[/]",
                    disabled=True,
                )
            )
            return

        for i, agent in enumerate(self._agents):
            # Format: [1] Agent Name (N chats) - description
            number = i + 1
            usage_text = ""
            if agent.usage_count is not None and agent.usage_count > 0:
                usage_text = f" ({agent.usage_count} chat{'s' if agent.usage_count != 1 else ''})"

            desc_text = ""
            if agent.description:
                desc_text = f" [dim]- {agent.description}[/]"

            label = (
                f"[bold cyan][{number}][/] {agent.name}[dim]{usage_text}[/]{desc_text}"
            )
            agents_list.add_option(Option(label, id=str(agent.id)))

    def _update_sessions_list(self) -> None:
        """Update the sessions option list."""
        sessions_list = self.query_one("#sessions-list", OptionList)
        sessions_list.clear_options()

        if not self._sessions:
            sessions_list.add_option(
                Option(
                    "[dim italic]No recent sessions[/]",
                    disabled=True,
                )
            )
            return

        for session in self._sessions:
            # Format: Session Name - time ago
            name = session.name or "Untitled"

            time_ago = self._format_time_ago(session.last_activity_at)
            label = f"  {name} [dim]{time_ago}[/]"
            sessions_list.add_option(Option(label, id=str(session.id)))

    def _format_time_ago(self, dt: datetime) -> str:
        """Format datetime as human-readable time ago."""
        now = datetime.now(timezone.utc)
        if dt.tzinfo is None:
            dt = dt.replace(tzinfo=timezone.utc)

        delta = now - dt
        seconds = delta.total_seconds()

        if seconds < 60:
            return "just now"
        elif seconds < 3600:
            mins = int(seconds / 60)
            return f"{mins}m ago"
        elif seconds < 86400:
            hours = int(seconds / 3600)
            return f"{hours}h ago"
        elif seconds < 604800:
            days = int(seconds / 86400)
            return f"{days}d ago"
        else:
            weeks = int(seconds / 604800)
            return f"{weeks}w ago"

    def _show_error(self, error: str) -> None:
        """Show error in the agents list."""
        agents_list = self.query_one("#agents-list", OptionList)
        agents_list.clear_options()
        agents_list.add_option(Option(f"[red]Error loading: {error}[/]", disabled=True))

    def action_select_agent(self, index: int) -> None:
        """Select an agent by number key (0-indexed)."""
        if index < len(self._agents):
            agent = self._agents[index]
            self.post_message(AgentQuickSelected(agent.id, agent.name))

    @on(OptionList.OptionSelected, "#agents-list")
    def on_agent_selected(self, event: OptionList.OptionSelected) -> None:
        """Handle agent selection from option list."""
        if event.option.id is None:
            return

        agent_id = UUID(event.option.id)
        # Find the agent name
        for agent in self._agents:
            if agent.id == agent_id:
                self.post_message(AgentQuickSelected(agent_id, agent.name))
                break

    @on(OptionList.OptionSelected, "#sessions-list")
    def on_session_selected(self, event: OptionList.OptionSelected) -> None:
        """Handle session selection from option list."""
        if event.option.id is None:
            return

        session_id = UUID(event.option.id)
        self.post_message(RecentSessionSelected(session_id))

    def refresh_data(self) -> None:
        """Refresh the agents and sessions data."""
        self._loading = True
        self._load_data()
