"""Quickstart command for Skyvern CLI."""

import asyncio
import subprocess
from pathlib import Path

import typer
from rich.panel import Panel
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.prompt import Confirm

# Import console after skyvern.cli to ensure proper initialization
from skyvern.cli.console import console
from skyvern.cli.init_command import init_env  # init is used directly
from skyvern.cli.llm_setup import setup_llm_providers
from skyvern.cli.utils import start_services

quickstart_app = typer.Typer(help="Quickstart command to set up and run Skyvern with one command.")


def check_docker() -> bool:
    """Check if Docker is installed and running."""
    try:
        result = subprocess.run(
            ["docker", "info"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
        )
        return result.returncode == 0
    except (FileNotFoundError, subprocess.SubprocessError):
        return False


def check_docker_compose_file() -> bool:
    """Check if docker-compose.yml exists in the current directory."""
    return Path("docker-compose.yml").exists() or Path("docker-compose.yaml").exists()


def check_postgres_container_conflict() -> bool:
    """Check if postgresql-container exists and is using port 5432."""
    try:
        result = subprocess.run(
            ["docker", "ps", "-a", "--filter", "name=postgresql-container", "--format", "{{.Names}}"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
        )
        return "postgresql-container" in result.stdout
    except (FileNotFoundError, subprocess.SubprocessError):
        return False


def run_docker_compose_setup() -> None:
    """Run the Docker Compose setup for Skyvern."""
    console.print("\n[bold blue]Setting up Skyvern with Docker Compose...[/bold blue]")

    # Check for postgres container conflict
    if check_postgres_container_conflict():
        console.print(
            Panel(
                "[bold yellow]Warning: Existing PostgreSQL container detected![/bold yellow]\n\n"
                "A container named 'postgresql-container' already exists, which may conflict\n"
                "with the PostgreSQL service in Docker Compose (both use port 5432).\n\n"
                "To avoid conflicts, remove the existing container first:\n"
                "[cyan]docker rm -f postgresql-container[/cyan]",
                border_style="yellow",
            )
        )
        proceed = Confirm.ask("Do you want to continue anyway?", default=False)
        if not proceed:
            console.print("[yellow]Aborting Docker Compose setup. Please remove the container and try again.[/yellow]")
            raise typer.Exit(0)

    # Configure LLM provider
    console.print("\n[bold blue]Step 1: Configure LLM Provider[/bold blue]")
    setup_llm_providers()

    # Run docker compose up
    console.print("\n[bold blue]Step 2: Starting Docker Compose...[/bold blue]")
    with Progress(
        SpinnerColumn(), TextColumn("[progress.description]{task.description}"), transient=True, console=console
    ) as progress:
        progress.add_task("[bold blue]Starting Docker containers...", total=None)
        try:
            subprocess.run(
                ["docker", "compose", "up", "-d"],
                check=True,
                capture_output=True,
                text=True,
            )
            console.print("✅ [green]Docker Compose started successfully.[/green]")
        except subprocess.CalledProcessError as e:
            console.print(f"[bold red]Error starting Docker Compose: {e.stderr}[/bold red]")
            raise typer.Exit(1)

    console.print(
        Panel(
            "[bold green]Skyvern is now running![/bold green]\n\n"
            "Navigate to [link]http://localhost:8080[/link] to start using the UI.\n\n"
            "To stop Skyvern, run: [cyan]docker compose down[/cyan]",
            border_style="green",
        )
    )


@quickstart_app.callback(invoke_without_command=True)
def quickstart(
    ctx: typer.Context,
    no_postgres: bool = typer.Option(False, "--no-postgres", help="Skip starting PostgreSQL container"),
    database_string: str = typer.Option(
        "",
        "--database-string",
        help="Custom database connection string (e.g., postgresql+psycopg://user:password@host:port/dbname). When provided, skips Docker PostgreSQL setup.",
    ),
    skip_browser_install: bool = typer.Option(
        False, "--skip-browser-install", help="Skip Chromium browser installation"
    ),
    server_only: bool = typer.Option(False, "--server-only", help="Only start the server, not the UI"),
    docker_compose: bool = typer.Option(False, "--docker-compose", help="Use Docker Compose for full setup"),
) -> None:
    """Quickstart command to set up and run Skyvern with one command."""
    # Check Docker
    with console.status("Checking Docker installation...") as status:
        docker_available = check_docker()
        if docker_available:
            status.update("✅ Docker is installed and running")
        else:
            if not database_string:
                console.print(
                    Panel(
                        "[bold red]Docker is not installed or not running.[/bold red]\n"
                        "Please install Docker and start it before running quickstart.\n"
                        "Get Docker from: [link]https://www.docker.com/get-started[/link]",
                        border_style="red",
                    )
                )
                raise typer.Exit(1)

    # Run initialization
    console.print(Panel("[bold green]🚀 Starting Skyvern Quickstart[/bold green]", border_style="green"))

    # Check if Docker Compose option was explicitly requested or offer choice
    docker_compose_available = check_docker_compose_file()

    if docker_compose:
        if not docker_compose_available:
            console.print(
                Panel(
                    "[bold red]docker-compose.yml not found in current directory.[/bold red]\n"
                    "Please clone the Skyvern repository first:\n"
                    "[cyan]git clone https://github.com/skyvern-ai/skyvern.git && cd skyvern[/cyan]",
                    border_style="red",
                )
            )
            raise typer.Exit(1)
        run_docker_compose_setup()
        return

    # If Docker Compose file exists, offer the choice
    if docker_compose_available and docker_available and not database_string:
        console.print("\n[bold blue]Setup Method[/bold blue]")
        console.print("Docker Compose file detected. Choose your setup method:\n")
        console.print("  [cyan]1.[/cyan] [green]Docker Compose (Recommended)[/green] - Full containerized setup")
        console.print("  [cyan]2.[/cyan] pip install - Local Python setup with Docker for PostgreSQL only\n")

        use_docker_compose = Confirm.ask(
            "Would you like to use Docker Compose for the full setup?",
            default=True,
        )

        if use_docker_compose:
            run_docker_compose_setup()
            return

    try:
        # Initialize Skyvern (pip install path)
        console.print("\n[bold blue]Initializing Skyvern...[/bold blue]")
        run_local = init_env(no_postgres=no_postgres, database_string=database_string)

        # Skip browser installation if requested
        if not skip_browser_install:
            with Progress(
                SpinnerColumn(), TextColumn("[progress.description]{task.description}"), transient=True, console=console
            ) as progress:
                progress.add_task("[bold blue]Installing Chromium browser...", total=None)
                try:
                    subprocess.run(["playwright", "install", "chromium"], check=True, capture_output=True, text=True)
                    console.print("✅ [green]Chromium installation complete.[/green]")
                except subprocess.CalledProcessError as e:
                    console.print(f"[yellow]Warning: Failed to install Chromium: {e.stderr}[/yellow]")
        else:
            console.print("⏭️ [yellow]Skipping Chromium installation as requested.[/yellow]")

        # Start services
        if run_local:
            start_now = typer.confirm("\nDo you want to start Skyvern services now?", default=True)
            if start_now:
                console.print("\n[bold blue]Starting Skyvern services...[/bold blue]")
                asyncio.run(start_services(server_only=server_only))
            else:
                console.print(
                    "\n[yellow]Skipping service startup. You can start services later with 'skyvern run all'[/yellow]"
                )

    except KeyboardInterrupt:
        console.print("\n[bold yellow]Quickstart process interrupted by user.[/bold yellow]")
        raise typer.Exit(0)
    except Exception as e:
        console.print(f"[bold red]Error during quickstart: {str(e)}[/bold red]")
        raise typer.Exit(1)
