"""
Interactive first-run onboarding for PenBot.

`penbot onboard` walks a new user through:
  1. Environment file creation (.env)
  2. API key configuration and validation
  3. Playwright browser installation
  4. Optional first-target wizard launch
"""

import os
import shutil
import subprocess
import sys
from pathlib import Path

from rich.console import Console
from rich.panel import Panel
from rich.prompt import Confirm, Prompt
from rich import print as rprint

console = Console()

ENV_FILE = Path(".env")
ENV_EXAMPLE = Path(".env.example")


def run_onboard(args):
    """Entry point for `penbot onboard`."""
    console.clear()
    console.print(
        Panel.fit(
            "[bold cyan]Welcome to PenBot[/bold cyan]\n"
            "[dim]AI Chatbot Security Testing Framework[/dim]\n\n"
            "This wizard will get your environment ready in ~2 minutes.",
            border_style="cyan",
            padding=(1, 4),
        )
    )

    steps_done = 0
    steps_total = 4

    # ------------------------------------------------------------------
    # Step 1: .env file
    # ------------------------------------------------------------------
    console.print(f"\n[bold]Step {steps_done + 1}/{steps_total}  Environment File[/bold]")

    if ENV_FILE.exists():
        rprint("  [green].env already exists[/green] — skipping creation.")
    elif ENV_EXAMPLE.exists():
        rprint("  Creating [cyan].env[/cyan] from [cyan].env.example[/cyan] ...")
        shutil.copy(ENV_EXAMPLE, ENV_FILE)
        rprint("  [green]Done.[/green]")
    else:
        rprint("  No .env.example found. Creating a minimal .env ...")
        _write_minimal_env()
        rprint("  [green]Done.[/green]")
    steps_done += 1

    # ------------------------------------------------------------------
    # Step 2: API keys
    # ------------------------------------------------------------------
    console.print(f"\n[bold]Step {steps_done + 1}/{steps_total}  API Keys[/bold]")

    anthropic_ok = _check_key("ANTHROPIC_API_KEY", "Anthropic (Claude)")
    openai_ok = _check_key("OPENAI_API_KEY", "OpenAI")

    if not anthropic_ok and not openai_ok:
        rprint("\n  [yellow]No LLM API key detected.[/yellow]")
        rprint("  PenBot needs at least one to function.")

        if Confirm.ask("  Would you like to enter an Anthropic API key now?", default=True):
            key = Prompt.ask("  Anthropic API key (sk-ant-...)")
            _set_env_value("ANTHROPIC_API_KEY", key)
            rprint("  [green]Saved to .env[/green]")
        elif Confirm.ask("  Would you like to enter an OpenAI API key instead?", default=True):
            key = Prompt.ask("  OpenAI API key (sk-...)")
            _set_env_value("OPENAI_API_KEY", key)
            rprint("  [green]Saved to .env[/green]")
        else:
            rprint("  [dim]Skipped — you can add keys to .env later.[/dim]")
    else:
        if anthropic_ok and openai_ok:
            rprint("  [green]Both Anthropic and OpenAI keys detected.[/green]")
        elif anthropic_ok:
            rprint("  [green]Anthropic key detected.[/green]  [dim](OpenAI optional)[/dim]")
        else:
            rprint("  [green]OpenAI key detected.[/green]  [dim](Anthropic optional)[/dim]")

    # Optional: Tavily
    tavily_ok = bool(os.getenv("TAVILY_API_KEY") or _read_env_value("TAVILY_API_KEY"))
    if not tavily_ok:
        rprint(
            "\n  [dim]Tavily API key not found (optional — enables reconnaissance search).[/dim]"
        )
        if Confirm.ask("  Add a Tavily key?", default=False):
            key = Prompt.ask("  Tavily API key (tvly-...)")
            _set_env_value("TAVILY_API_KEY", key)
            rprint("  [green]Saved to .env[/green]")
    else:
        rprint("  [green]Tavily key detected.[/green]")

    steps_done += 1

    # ------------------------------------------------------------------
    # Step 3: Playwright browsers
    # ------------------------------------------------------------------
    console.print(f"\n[bold]Step {steps_done + 1}/{steps_total}  Playwright Browsers[/bold]")

    pw_installed = _check_playwright_browsers()
    if pw_installed:
        rprint("  [green]Playwright browsers already installed.[/green]")
    else:
        rprint("  Playwright browsers not found.")
        if Confirm.ask("  Install Chromium now? (required for web-UI testing)", default=True):
            _install_playwright()
        else:
            rprint("  [dim]Skipped — run 'playwright install chromium' later if needed.[/dim]")
    steps_done += 1

    # ------------------------------------------------------------------
    # Step 4: First target
    # ------------------------------------------------------------------
    console.print(f"\n[bold]Step {steps_done + 1}/{steps_total}  Your First Target[/bold]")

    configs_exist = (
        list(Path("configs/clients").glob("*.yaml")) if Path("configs/clients").exists() else []
    )
    real_configs = [c for c in configs_exist if c.name != "_TEMPLATE_FULL.yaml"]

    if real_configs:
        rprint(
            f"  Found {len(real_configs)} existing config(s): {', '.join(c.stem for c in real_configs)}"
        )
        rprint("  [dim]You can create more with 'penbot wizard'.[/dim]")
    else:
        rprint("  No target configs found yet.")
        if Confirm.ask("  Launch the target wizard now?", default=True):
            console.print()
            from src.cli.wizard import run_wizard
            import asyncio

            asyncio.run(run_wizard(args))
            steps_done += 1
            _print_summary()
            return

    steps_done += 1
    _print_summary()


def _print_summary():
    console.print(
        Panel.fit(
            "[bold green]Setup Complete![/bold green]\n\n"
            "  [cyan]penbot doctor[/cyan]    — verify everything is working\n"
            "  [cyan]penbot wizard[/cyan]    — configure a new target\n"
            "  [cyan]penbot test --config configs/clients/<name>.yaml[/cyan]  — run a test\n"
            "  [cyan]penbot dashboard[/cyan] — start the Mission Control UI",
            border_style="green",
            padding=(1, 2),
        )
    )


# ------------------------------------------------------------------
# Helpers
# ------------------------------------------------------------------


def _check_key(env_name: str, label: str) -> bool:
    """Check if an API key is set in env or .env file."""
    val = os.getenv(env_name) or _read_env_value(env_name)
    if val and not val.endswith("your-key-here"):
        return True
    return False


def _read_env_value(key: str) -> str:
    """Read a value from the .env file (simple parser)."""
    if not ENV_FILE.exists():
        return ""
    for line in ENV_FILE.read_text(encoding="utf-8").splitlines():
        line = line.strip()
        if line.startswith("#") or "=" not in line:
            continue
        k, _, v = line.partition("=")
        if k.strip() == key:
            return v.strip().strip('"').strip("'")
    return ""


def _set_env_value(key: str, value: str) -> None:
    """Set a value in the .env file, replacing if it already exists."""
    if not ENV_FILE.exists():
        ENV_FILE.write_text(f"{key}={value}\n", encoding="utf-8")
        return

    lines = ENV_FILE.read_text(encoding="utf-8").splitlines()
    found = False
    new_lines = []
    for line in lines:
        stripped = line.strip()
        if stripped.startswith(f"{key}=") or stripped.startswith(f"{key} ="):
            new_lines.append(f"{key}={value}")
            found = True
        else:
            new_lines.append(line)
    if not found:
        new_lines.append(f"{key}={value}")
    ENV_FILE.write_text("\n".join(new_lines) + "\n", encoding="utf-8")


def _write_minimal_env():
    """Create a minimal .env when no example is available."""
    content = (
        "# PenBot Environment — generated by 'penbot onboard'\n"
        "ANTHROPIC_API_KEY=\n"
        "OPENAI_API_KEY=\n"
        "TAVILY_API_KEY=\n"
        "LLM_MODEL=claude-sonnet-4-5-20250929\n"
        "ENVIRONMENT=development\n"
        "LOG_LEVEL=INFO\n"
    )
    ENV_FILE.write_text(content, encoding="utf-8")


def _check_playwright_browsers() -> bool:
    """Return True if Playwright Chromium is already installed."""
    try:
        subprocess.run(
            [sys.executable, "-m", "playwright", "install", "--dry-run"],
            capture_output=True,
            text=True,
            timeout=15,
        )
        from playwright._impl._driver import compute_driver_executable

        driver_exec = compute_driver_executable()
        return Path(driver_exec).exists()
    except Exception:
        # Simpler fallback: check if the playwright module is importable
        # and if the browser executable directory has content
        try:
            import playwright

            pw_dir = Path(playwright.__file__).parent / "driver" / "package" / ".local-browsers"
            if pw_dir.exists() and any(pw_dir.iterdir()):
                return True
        except Exception:
            pass
        return False


def _install_playwright():
    """Run `playwright install chromium`."""
    rprint("  Installing Chromium (this may take a minute)...")
    try:
        result = subprocess.run(
            [sys.executable, "-m", "playwright", "install", "chromium"],
            capture_output=True,
            text=True,
            timeout=300,
        )
        if result.returncode == 0:
            rprint("  [green]Chromium installed successfully.[/green]")
        else:
            rprint(f"  [red]Installation failed:[/red] {result.stderr.strip()}")
            rprint("  Try manually: [cyan]playwright install chromium[/cyan]")
    except FileNotFoundError:
        rprint(
            "  [red]Playwright not found.[/red] Install with: [cyan]pip install playwright[/cyan]"
        )
    except subprocess.TimeoutExpired:
        rprint(
            "  [yellow]Installation timed out.[/yellow] Try manually: [cyan]playwright install chromium[/cyan]"
        )
