"""Setup wizard for initial configuration - Kimi CLI style."""

from __future__ import annotations

import asyncio
from typing import TYPE_CHECKING

from prompt_toolkit import PromptSession
from rich.panel import Panel
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.prompt import IntPrompt, Prompt

from ..ui import console
from ..utils.logger import Logger

if TYPE_CHECKING:
    from ..core.auth_manager import AuthManager
    from ..core.skill_registry import SkillRegistry
    from ..providers.provider_manager import ProviderManager


class SetupWizard:
    """Wizard for initial setup - Async style like Kimi CLI."""

    def __init__(
        self,
        provider_manager: ProviderManager,
        auth_manager: AuthManager,
        skill_registry: SkillRegistry,
    ) -> None:
        self.provider_manager = provider_manager
        self.auth_manager = auth_manager
        self.skill_registry = skill_registry

    def run(self) -> bool:
        """Run the setup wizard. Returns True if successful."""
        return asyncio.run(self._run_async())

    async def _run_async(self) -> bool:
        """Async setup flow."""
        self._print_welcome()

        # Step 1: Provider setup
        provider_result = await self._setup_provider()
        if not provider_result:
            return False

        # Step 2: Agent registration
        if not await self._setup_agent():
            return False

        # Step 3: Initialize skills
        try:
            self.skill_registry.initialize()
        except Exception as e:
            Logger.error("Failed to initialize skills", e)
            console.print(
                "[yellow]Warning: Could not load skills. Some features may not work.[/yellow]"
            )

        console.print("\n[bold green]✓ Setup complete! You're ready to go.[/bold green]\n")
        return True

    def _print_welcome(self) -> None:
        """Print welcome banner."""
        console.print(
            Panel(
                "[bold blue]Welcome to ReplyMarketing CLI[/bold blue]\n"
                "[dim]AI-powered marketing assistant for Reply Cash[/dim]",
                border_style="blue",
            )
        )
        console.print("\n[dim]Let's get you set up with an AI provider and register your agent.[/dim]\n")

    async def _setup_provider(self) -> str | None:
        """Setup AI provider.

        Returns:
            Provider name if successful, None otherwise.
        """
        console.print("[bold cyan]Step 1/2: AI Provider Setup[/bold cyan]\n")
        console.print("[dim]Detecting available providers...[/dim]\n")

        # Detect providers
        providers = self.provider_manager.detect_all_providers()
        available = [p for p in providers if p.available]

        if not available:
            console.print("[red]No AI providers detected.[/red]")
            console.print("\n[dim]Please install one of the following:[/dim]")
            console.print("  • Kimi CLI: [yellow]pip install kimi-cli[/yellow]")
            console.print("  • Or set an API key: [yellow]OPENAI_API_KEY[/yellow], [yellow]ANTHROPIC_API_KEY[/yellow], etc.")
            return None

        # Display options with numbers
        console.print("[bold]Available providers:[/bold]\n")
        for i, p in enumerate(available, 1):
            info = ""
            if p.version:
                info = f" ({p.version})"
            elif p.model:
                info = f" - {p.model}"
            elif p.api_key_source and p.api_key_source.startswith("env:"):
                info = f" [{p.api_key_source}]"

            marker = ">" if i == 1 else " "
            console.print(f"  {marker} {i}. {p.name}{info}")

        console.print()

        # Get selection using rich prompt
        choices = [str(i) for i in range(1, len(available) + 1)]
        try:
            choice = IntPrompt.ask(
                "Select provider (enter number)",
                choices=choices,
                default=1,
            )
        except (EOFError, KeyboardInterrupt):
            console.print("\n[yellow]Setup cancelled.[/yellow]")
            return None

        selected = available[choice - 1]

        # Configure provider
        config: dict = {}

        if selected.type == "api" and not selected.api_key_source:
            # Need API key - use password prompt
            session = PromptSession[str]()
            try:
                api_key = await session.prompt_async(
                    f" Enter API key for {selected.name}: ",
                    is_password=True,
                )
            except (EOFError, KeyboardInterrupt):
                console.print("\n[yellow]Setup cancelled.[/yellow]")
                return None

            if not api_key.strip():
                console.print("[red]API key is required.[/red]")
                return None
            config["apiKey"] = api_key.strip()

        # Test and save
        console.print(f"\n[dim]Testing connection to {selected.name}...[/dim]")
        try:
            with Progress(
                SpinnerColumn(),
                TextColumn("[progress.description]{task.description}"),
                transient=True,
            ) as progress:
                progress.add_task("Connecting...", total=None)
                self.provider_manager.set_provider(selected.name, config)

            console.print(f"[green]✓ Connected to {selected.name}[/green]\n")
            return selected.name

        except Exception as e:
            console.print(f"[red]✗ Connection failed: {e}[/red]")
            return None

    async def _setup_agent(self) -> bool:
        """Setup agent registration.

        Returns:
            True if successful or already registered.
        """
        console.print("[bold cyan]Step 2/2: Agent Registration[/bold cyan]\n")

        # Check if already registered
        if self.auth_manager.has_valid_credentials():
            console.print(f"[green]✓ Already registered as:[/green] {self.auth_manager.get_agent_name()}")
            return True

        console.print("[dim]No credentials found. Let's register your marketing agent.[/dim]\n")

        # Get agent name using prompt_toolkit
        session = PromptSession[str]()
        try:
            agent_name = await session.prompt_async(
                " Enter agent name: ",
                default="My Marketing Agent",
            )
        except (EOFError, KeyboardInterrupt):
            console.print("\n[yellow]Setup cancelled.[/yellow]")
            return False

        if not agent_name.strip():
            console.print("[red]Agent name is required.[/red]")
            return False

        # Get purpose (optional)
        try:
            purpose = await session.prompt_async(
                " Purpose (optional): ",
                default="content-marketing",
            )
        except (EOFError, KeyboardInterrupt):
            purpose = "content-marketing"

        # Register
        console.print(f"\n[dim]Registering agent '{agent_name}'...[/dim]")
        try:
            with Progress(
                SpinnerColumn(),
                TextColumn("[progress.description]{task.description}"),
                transient=True,
            ) as progress:
                progress.add_task("Registering...", total=None)
                self.auth_manager.register_agent(agent_name, {"purpose": purpose})

            console.print(f"[green]✓ Agent registered: {agent_name}[/green]\n")
            return True

        except Exception as e:
            console.print(f"[red]✗ Registration failed: {e}[/red]")
            return False
