"""antiqa init — interactive project setup wizard."""

from __future__ import annotations

import subprocess
import sys
from pathlib import Path

import typer
from rich.console import Console
from rich.panel import Panel
from rich.prompt import Confirm, Prompt
from rich.table import Table

from antiqa.config.manager import config_exists, save_config
from antiqa.config.schema import (
    BROWSER_TYPES,
    LLM_PROVIDERS,
    AntiQAConfig,
    BrowserConfig,
    JiraConfig,
    LLMConfig,
)

console = Console()


def _ask_llm() -> LLMConfig:
    """Prompt user for LLM provider and model selection."""
    console.print("\n[bold cyan]LLM Configuration[/bold cyan]")

    table = Table(show_header=True, header_style="bold magenta")
    table.add_column("#", style="dim", width=4)
    table.add_column("Provider")
    table.add_column("Default Models")
    for i, (name, models) in enumerate(LLM_PROVIDERS.items(), 1):
        table.add_row(str(i), name, ", ".join(models[:3]))
    console.print(table)

    providers = list(LLM_PROVIDERS.keys())
    choice = Prompt.ask(
        "Select LLM provider",
        choices=[str(i) for i in range(1, len(providers) + 1)],
        default="1",
    )
    provider = providers[int(choice) - 1]

    default_models = LLM_PROVIDERS[provider]
    console.print(f"\nAvailable models for [bold]{provider}[/bold]: {', '.join(default_models)}")
    model = Prompt.ask("Model to use", default=default_models[0])

    if provider == "ollama":
        console.print("[dim]Ollama runs locally — no API key needed.[/dim]")
        return LLMConfig(provider=provider, model=model, api_key="", api_key_env="")

    api_key = Prompt.ask(
        f"Enter your {provider} API key",
        password=True,
    )

    return LLMConfig(provider=provider, model=model, api_key=api_key, api_key_env="")


def _ask_jira() -> JiraConfig:
    """Prompt user for Jira configuration."""
    console.print("\n[bold cyan]Jira Configuration[/bold cyan]")

    base_url = Prompt.ask("Jira base URL", default="https://yourteam.atlassian.net")
    project_key = Prompt.ask("Jira project key (e.g. PROJ)")
    email = Prompt.ask("Jira account email")
    api_token = Prompt.ask(
        "Enter your Jira API token",
        password=True,
    )

    return JiraConfig(
        base_url=base_url.rstrip("/"),
        project_key=project_key.upper(),
        email=email,
        api_token=api_token,
        api_key_env="",
    )


def _ask_browser() -> BrowserConfig:
    """Prompt user for browser preferences."""
    console.print("\n[bold cyan]Browser Configuration[/bold cyan]")

    browser_type = Prompt.ask(
        "Browser engine",
        choices=BROWSER_TYPES,
        default="chromium",
    )
    headless = Confirm.ask("Run in headless mode?", default=False)

    return BrowserConfig(type=browser_type, headless=headless)


def _ask_app_url() -> str:
    """Prompt user for the target application URL."""
    console.print("\n[bold cyan]Application Under Test[/bold cyan]")
    url = Prompt.ask("Application URL to test", default="http://localhost:3000")
    return url.rstrip("/")


def run_init() -> None:
    """Run the full interactive init wizard."""
    console.print(
        Panel(
            "[bold green]AntiQA Setup Wizard[/bold green]\n"
            "Configure your AI-powered QA automation.",
            expand=False,
        )
    )

    if config_exists():
        overwrite = Confirm.ask(
            "[yellow]antiqa.json already exists. Overwrite?[/yellow]",
            default=False,
        )
        if not overwrite:
            console.print("[dim]Init cancelled.[/dim]")
            raise typer.Exit()

    app_url = _ask_app_url()
    llm = _ask_llm()
    jira = _ask_jira()
    browser = _ask_browser()

    config = AntiQAConfig(
        app_url=app_url,
        llm=llm,
        jira=jira,
        browser=browser,
    )

    path = save_config(config)

    Path(config.flows_dir).mkdir(parents=True, exist_ok=True)
    Path(config.logs_dir).mkdir(parents=True, exist_ok=True)

    _install_playwright_browsers(config.browser.type)

    # Auto-crawl the application
    _auto_crawl(config)

    console.print()
    console.print(Panel(
        f"[bold green]Project initialized![/bold green]\n\n"
        f"  Config saved to: [cyan]{path}[/cyan]\n"
        f"  Flows directory: [cyan]{config.flows_dir}[/cyan]\n"
        f"  Logs directory:  [cyan]{config.logs_dir}[/cyan]\n\n"
        f"[dim]Next step:\n"
        f"  Run [bold]antiqa run JIRA-123[/bold] to test a ticket[/dim]",
        expand=False,
    ))


def _auto_crawl(config: AntiQAConfig) -> None:
    """Crawl the target app automatically during init."""
    console.print(f"\n[bold cyan]Crawling {config.app_url}...[/bold cyan]")
    console.print("[dim]Discovering routes and building navigation graph[/dim]")

    try:
        from antiqa.crawler.crawler import Crawler, DEFAULT_GRAPH_PATH

        crawler = Crawler(
            base_url=config.app_url,
            browser_config=config.browser,
            max_pages=50,
            max_depth=5,
        )

        visited = 0

        def _on_page(url: str, vis: int, queued: int) -> None:
            nonlocal visited
            visited = vis
            console.print(f"  [dim]{vis}.[/dim] {url}")

        crawler.on_page = _on_page
        graph = crawler.crawl_and_save(output_path=DEFAULT_GRAPH_PATH)

        console.print(
            f"\n[green]Crawl complete:[/green] "
            f"{graph.page_count} page(s), {graph.edge_count} transition(s)"
        )

        # Auto-generate starter flows from the graph
        from antiqa.flows.generator import FlowGenerator

        generator = FlowGenerator(
            graph=graph,
            app_url=config.app_url,
            flows_dir=config.flows_dir,
        )
        generated = generator.generate_all(overwrite=False)
        if generated:
            console.print(
                f"[green]Auto-generated {len(generated)} starter flow(s):[/green]"
            )
            for p in generated:
                console.print(f"  [cyan]{p}[/cyan]")

    except Exception as exc:
        console.print(
            f"[yellow]Could not auto-crawl the app: {exc}[/yellow]\n"
            f"[dim]Make sure {config.app_url} is running.\n"
            f"You can crawl later with: [bold]antiqa crawl[/bold][/dim]"
        )


def _install_playwright_browsers(browser_type: str) -> None:
    """Install the Playwright browser binary chosen by the user."""
    console.print(f"\n[bold cyan]Installing Playwright {browser_type} browser...[/bold cyan]")
    try:
        result = subprocess.run(
            [sys.executable, "-m", "playwright", "install", browser_type],
            capture_output=True,
            text=True,
            check=False,
        )
        if result.returncode == 0:
            console.print(f"[green]Playwright {browser_type} installed successfully.[/green]")
        else:
            console.print(
                f"[yellow]Playwright browser install returned warnings:[/yellow]\n"
                f"{result.stderr.strip()}"
            )
            console.print(
                f"[dim]You can install manually: "
                f"python -m playwright install {browser_type}[/dim]"
            )
    except Exception as exc:
        console.print(
            f"[yellow]Could not auto-install Playwright browser: {exc}[/yellow]\n"
            f"[dim]Run manually: python -m playwright install {browser_type}[/dim]"
        )
