"""Install screen — agent-first design with background installer."""

from __future__ import annotations

import asyncio

from textual.app import ComposeResult
from textual.screen import Screen
from textual.widgets import Header, Footer, Static

from easyclaw_tui.state import InstallState, StepStatus
from easyclaw_tui.widgets.chat_panel import AgentChatPanel
from easyclaw_tui.install_runner import run_install_steps, get_logs_for_step
from easyclaw_tui.agent.config import AgentConfig
from easyclaw_tui.agent.tui_bridge import AgentWorker
from easyclaw_tui.messages import (
    InstallStepStarted,
    InstallStepCompleted,
    InstallFinished,
    AgentResponse,
    AgentToolCall,
    AgentThinking,
    AgentReady,
    UserConfirmRequest,
    ChatSubmitted,
)


class InstallScreen(Screen):
    """Agent-first install screen — Agent Johnny 5 is the primary UI."""

    BINDINGS = [("q", "quit_app", "Quit")]

    def __init__(self, state: InstallState) -> None:
        super().__init__()
        self.state = state
        self._agent_worker: AgentWorker | None = None
        self._install_complete = False

    def compose(self) -> ComposeResult:
        yield Header()
        yield Static(
            " Step 0/15: Starting install...",
            id="install-status-bar",
        )
        yield AgentChatPanel()
        yield Footer()

    @property
    def chat(self) -> AgentChatPanel:
        return self.query_one(AgentChatPanel)

    def _update_status_bar(self, step_num: int, name: str, status: str) -> None:
        """Update the status bar with current step progress."""
        filled = "=" * step_num
        arrow = ">"
        empty = " " * (15 - step_num)
        bar = self.query_one("#install-status-bar", Static)
        bar.update(f" Step {step_num}/15: {name} [{filled}{arrow}{empty}] {status}")

    async def on_mount(self) -> None:
        # Initialize agent
        config = AgentConfig.load()
        config.resolve_keys(
            cli_api_key=self.state.api_key,
            cli_or_key=self.state.openrouter_key,
        )
        config.save()

        self._agent_worker = AgentWorker(
            config=config,
            post_message=self.post_message,
            install_mode=True,
        )
        agent_ok = self._agent_worker.initialize()

        # Start agent processing loop
        self.run_worker(self._agent_worker.run(), exclusive=False)

        # Post initial greeting
        if agent_ok:
            self.chat.add_bot_message(
                "Hey! I'm Johnny 5, your AI admin for OpenClaw. "
                "I'm installing everything for you right now — feel free to ask me "
                "anything while we wait. I'll keep you posted on each step."
            )
        else:
            self.chat.add_system_message(
                "Agent Johnny 5 unavailable — no OpenRouter API key. "
                "Install is proceeding automatically."
            )

        # Start background install
        self.run_worker(self._run_install(), exclusive=False)

    async def _run_install(self) -> None:
        """Background install — runs all 15 steps and posts messages."""
        await run_install_steps(
            state=self.state,
            post_message=self.post_message,
        )

    # ─── Install Event Handlers ───────────────────────────

    def on_install_step_started(self, event: InstallStepStarted) -> None:
        """A step just started."""
        self._update_status_bar(event.step_num, event.name, "Running...")

    def on_install_step_completed(self, event: InstallStepCompleted) -> None:
        """A step finished."""
        if event.result.success:
            self._update_status_bar(event.step_num, event.name, "Done")
            # Compact one-liner in chat
            self.chat.add_install_update(
                f"  \u2713 Step {event.step_num}/15: {event.name} \u2014 OK"
            )
        elif event.result.skipped:
            self._update_status_bar(event.step_num, event.name, "Skipped")
            self.chat.add_install_update(
                f"  \u2014 Step {event.step_num}/15: {event.name} \u2014 Skipped"
            )
        else:
            self._update_status_bar(event.step_num, event.name, "FAILED")
            # Show failure prominently
            self.chat.add_install_update(
                f"[bold red]  \u2717 Step {event.step_num}/15: {event.name} "
                f"\u2014 FAILED: {event.result.message}[/bold red]"
            )
            # Auto-diagnose via agent
            if self._agent_worker and self._agent_worker.is_available:
                logs = get_logs_for_step(event.step_num)
                diag_prompt = (
                    f"[INSTALL ALERT] Step {event.step_num} ({event.name}) just failed.\n"
                    f"Error: {event.result.message}\n"
                    f"Recent logs:\n{logs}\n\n"
                    f"Diagnose this issue and suggest a fix."
                )
                asyncio.create_task(
                    self._agent_worker.send_message(diag_prompt, is_system=True)
                )

    def on_install_finished(self, event: InstallFinished) -> None:
        """All steps done."""
        self._install_complete = True
        if event.all_passed:
            self._update_status_bar(15, "Complete", "\u2714 Done!")
            self.chat.add_install_update(
                "\n[bold green]\u2714 Installation complete![/bold green] "
                "OpenClaw is ready. Ask me anything about your setup, "
                "or type [bold]exit[/bold] to quit."
            )
        else:
            self._update_status_bar(15, "Complete", "\u26a0 Issues")
            self.chat.add_install_update(
                "\n[bold yellow]\u26a0 Installation finished with some issues.[/bold yellow] "
                "Ask me to diagnose any problems, or type [bold]exit[/bold] to quit."
            )

    # ─── Agent Event Handlers ─────────────────────────────

    def on_agent_response(self, event: AgentResponse) -> None:
        """Agent produced a response."""
        self.chat.add_bot_message(event.text)

    def on_agent_tool_call(self, event: AgentToolCall) -> None:
        """Agent called a tool — show inline indicator."""
        self.chat.add_tool_indicator(event.name, event.args)

    def on_agent_thinking(self, event: AgentThinking) -> None:
        """Agent is processing."""
        self.chat.show_thinking()

    def on_agent_ready(self, event: AgentReady) -> None:
        """Agent finished processing."""
        pass  # Could re-enable input if we disabled it

    def on_user_confirm_request(self, event: UserConfirmRequest) -> None:
        """Agent's ask_user tool needs user input."""
        self.chat.show_confirm(
            event.question, event.response_event, event.response_holder
        )

    # ─── Chat Event Handler ───────────────────────────────

    def on_chat_submitted(self, event: ChatSubmitted) -> None:
        """User typed a message — route to agent."""
        text = event.text.strip()

        # Handle exit command
        if text.lower() in ("exit", "quit"):
            self.app.exit(result="user_exit")
            return

        # Send to agent
        if self._agent_worker and self._agent_worker.is_available:
            asyncio.create_task(self._agent_worker.send_message(text))
        else:
            self.chat.add_system_message(
                "Agent unavailable — no OpenRouter key configured."
            )

    def action_quit_app(self) -> None:
        """Handle q key press."""
        self.app.exit(result="user_exit")
