#!/usr/bin/env python3
"""
CloneBox CLI - Interactive command-line interface for creating VMs.
"""

import argparse
import json
import os
import re
import sys
from typing import Optional
from datetime import datetime
from pathlib import Path

import questionary
import yaml
from questionary import Style
from rich.console import Console
from rich.panel import Panel
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.table import Table

from clonebox import __version__
from clonebox.cloner import SelectiveVMCloner, VMConfig
from clonebox.detector import SystemDetector

# Custom questionary style
custom_style = Style(
    [
        ("qmark", "fg:cyan bold"),
        ("question", "bold"),
        ("answer", "fg:green"),
        ("pointer", "fg:cyan bold"),
        ("highlighted", "fg:cyan bold"),
        ("selected", "fg:green"),
        ("separator", "fg:gray"),
        ("instruction", "fg:gray italic"),
    ]
)

console = Console()


def print_banner():
    """Print the CloneBox banner."""
    banner = """
╔═══════════════════════════════════════════════════════════════╗
║   ____  _                    ____                             ║
║  / ___|| |  ___   _ __   ___|  _ \\  ___ __  __                ║
║ | |    | | / _ \\ | '_ \\ / _ \\ |_) |/ _ \\\\ \\/ /                ║
║ | |___ | || (_) || | | |  __/  _ <| (_) |>  <                 ║
║  \\____||_| \\___/ |_| |_|\\___|_| \\_\\\\___//_/\\_\\                ║
║                                                               ║
║  Clone your workstation to an isolated VM                     ║
╚═══════════════════════════════════════════════════════════════╝
"""
    console.print(banner, style="cyan")
    console.print(f"  Version {__version__}\n", style="dim")


def interactive_mode():
    """Run the interactive VM creation wizard."""
    print_banner()

    console.print("[bold cyan]🔍 Detecting system state...[/]\n")

    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        console=console,
        transient=True,
    ) as progress:
        task = progress.add_task("Scanning services, apps, and paths...", total=None)
        detector = SystemDetector()
        snapshot = detector.detect_all()
        sys_info = detector.get_system_info()
        docker_containers = detector.detect_docker_containers()

    # Show system info
    console.print(
        Panel(
            f"[bold]Hostname:[/] {sys_info['hostname']}\n"
            f"[bold]User:[/] {sys_info['user']}\n"
            f"[bold]CPU:[/] {sys_info['cpu_count']} cores\n"
            f"[bold]RAM:[/] {sys_info['memory_available_gb']:.1f} / {sys_info['memory_total_gb']:.1f} GB available\n"
            f"[bold]Disk:[/] {sys_info['disk_free_gb']:.1f} / {sys_info['disk_total_gb']:.1f} GB free",
            title="[bold cyan]System Info[/]",
            border_style="cyan",
        )
    )

    console.print()

    # === VM Name ===
    vm_name = questionary.text("VM name:", default="clonebox-vm", style=custom_style).ask()

    if not vm_name:
        console.print("[red]Cancelled.[/]")
        return

    # === RAM ===
    max_ram = int(sys_info["memory_available_gb"] * 1024 * 0.75)  # 75% of available
    default_ram = min(4096, max_ram)

    ram_mb = questionary.text(
        f"RAM (MB) [max recommended: {max_ram}]:", default=str(default_ram), style=custom_style
    ).ask()
    ram_mb = int(ram_mb) if ram_mb else default_ram

    # === vCPUs ===
    max_vcpus = sys_info["cpu_count"]
    default_vcpus = max(2, max_vcpus // 2)

    vcpus = questionary.text(
        f"vCPUs [max: {max_vcpus}]:", default=str(default_vcpus), style=custom_style
    ).ask()
    vcpus = int(vcpus) if vcpus else default_vcpus

    # === Services Selection ===
    console.print("\n[bold cyan]📦 Select services to include in VM:[/]")

    service_choices = []
    for svc in snapshot.running_services:
        label = f"{svc.name} ({svc.status})"
        if svc.description:
            label += f" - {svc.description[:40]}"
        service_choices.append(questionary.Choice(label, value=svc.name))

    selected_services = []
    if service_choices:
        selected_services = (
            questionary.checkbox(
                "Services (space to select, enter to confirm):",
                choices=service_choices,
                style=custom_style,
            ).ask()
            or []
        )
    else:
        console.print("[dim]  No interesting services detected[/]")

    # === Applications/Processes Selection ===
    console.print("\n[bold cyan]🚀 Select applications to track:[/]")

    app_choices = []
    for app in snapshot.running_apps[:20]:  # Limit to top 20
        label = f"{app.name} (PID: {app.pid}, {app.memory_mb:.0f} MB)"
        if app.working_dir:
            label += f" @ {app.working_dir[:30]}"
        app_choices.append(questionary.Choice(label, value=app))

    selected_apps = []
    if app_choices:
        selected_apps = (
            questionary.checkbox(
                "Applications (will add their working dirs):",
                choices=app_choices,
                style=custom_style,
            ).ask()
            or []
        )
    else:
        console.print("[dim]  No interesting applications detected[/]")

    # === Docker Containers ===
    if docker_containers:
        console.print("\n[bold cyan]🐳 Docker containers detected:[/]")

        container_choices = [
            questionary.Choice(f"{c['name']} ({c['image']}) - {c['status']}", value=c["name"])
            for c in docker_containers
        ]

        selected_containers = (
            questionary.checkbox(
                "Containers (will share docker socket):",
                choices=container_choices,
                style=custom_style,
            ).ask()
            or []
        )

        # If any docker selected, add docker socket
        if selected_containers:
            if "docker" not in selected_services:
                selected_services.append("docker")

    # === Paths Selection ===
    console.print("\n[bold cyan]📁 Select paths to mount in VM:[/]")

    # Group paths by type
    path_groups = {}
    for p in snapshot.paths:
        if p.type not in path_groups:
            path_groups[p.type] = []
        path_groups[p.type].append(p)

    path_choices = []
    for ptype in ["project", "config", "data"]:
        if ptype in path_groups:
            for p in path_groups[ptype]:
                size_str = f"{p.size_mb:.0f} MB" if p.size_mb > 0 else "?"
                label = f"[{ptype}] {p.path} ({size_str})"
                if p.description:
                    label += f" - {p.description}"
                path_choices.append(questionary.Choice(label, value=p.path))

    selected_paths = []
    if path_choices:
        selected_paths = (
            questionary.checkbox(
                "Paths (will be bind-mounted read-write):", choices=path_choices, style=custom_style
            ).ask()
            or []
        )

    # Add working directories from selected applications
    for app in selected_apps:
        if app.working_dir and app.working_dir not in selected_paths:
            selected_paths.append(app.working_dir)

    # === Additional Packages ===
    console.print("\n[bold cyan]📦 Additional packages to install:[/]")

    common_packages = [
        "build-essential",
        "git",
        "curl",
        "wget",
        "vim",
        "htop",
        "python3",
        "python3-pip",
        "python3-venv",
        "nodejs",
        "npm",
        "docker.io",
        "docker-compose",
        "nginx",
        "postgresql",
        "redis",
    ]

    pkg_choices = [questionary.Choice(pkg, value=pkg) for pkg in common_packages]

    selected_packages = (
        questionary.checkbox(
            "Packages (space to select):", choices=pkg_choices, style=custom_style
        ).ask()
        or []
    )

    # Add custom packages
    custom_pkgs = questionary.text(
        "Additional packages (space-separated):", default="", style=custom_style
    ).ask()

    if custom_pkgs:
        selected_packages.extend(custom_pkgs.split())

    # === Base Image ===
    base_image = questionary.text(
        "Base image path (optional, leave empty for blank disk):", default="", style=custom_style
    ).ask()

    # === GUI ===
    enable_gui = questionary.confirm(
        "Enable SPICE graphics (GUI)?", default=True, style=custom_style
    ).ask()

    # === Summary ===
    console.print("\n")

    # Build paths mapping
    paths_mapping = {}
    for idx, host_path in enumerate(selected_paths):
        guest_path = f"/mnt/host{idx}"
        paths_mapping[host_path] = guest_path

    # Summary table
    summary_table = Table(title="VM Configuration Summary", border_style="cyan")
    summary_table.add_column("Setting", style="bold")
    summary_table.add_column("Value")

    summary_table.add_row("Name", vm_name)
    summary_table.add_row("RAM", f"{ram_mb} MB")
    summary_table.add_row("vCPUs", str(vcpus))
    summary_table.add_row("Services", ", ".join(selected_services) or "None")
    summary_table.add_row(
        "Packages",
        ", ".join(selected_packages[:5]) + ("..." if len(selected_packages) > 5 else "") or "None",
    )
    summary_table.add_row("Paths", f"{len(paths_mapping)} bind mounts")
    summary_table.add_row("GUI", "Yes (SPICE)" if enable_gui else "No")

    console.print(summary_table)

    if paths_mapping:
        console.print("\n[bold]Bind mounts:[/]")
        for host, guest in paths_mapping.items():
            console.print(f"  [cyan]{host}[/] → [green]{guest}[/]")

    console.print()

    # === Confirm ===
    if not questionary.confirm(
        "Create VM with these settings?", default=True, style=custom_style
    ).ask():
        console.print("[yellow]Cancelled.[/]")
        return

    # === Create VM ===
    console.print("\n[bold cyan]🔧 Creating VM...[/]\n")

    config = VMConfig(
        name=vm_name,
        ram_mb=ram_mb,
        vcpus=vcpus,
        gui=enable_gui,
        base_image=base_image if base_image else None,
        paths=paths_mapping,
        packages=selected_packages,
        services=selected_services,
    )

    try:
        cloner = SelectiveVMCloner(user_session=user_session)

        # Check prerequisites
        checks = cloner.check_prerequisites()
        if not all(checks.values()):
            console.print("[yellow]⚠️  Prerequisites check:[/]")
            for check, passed in checks.items():
                icon = "✅" if passed else "❌"
                console.print(f"   {icon} {check}")

            if not checks["libvirt_connected"]:
                console.print("\n[red]Cannot proceed without libvirt connection.[/]")
                console.print("Try: [cyan]sudo systemctl start libvirtd[/]")
                return

        vm_uuid = cloner.create_vm(config, console=console)

        # Ask to start
        if questionary.confirm("Start VM now?", default=True, style=custom_style).ask():
            cloner.start_vm(vm_name, open_viewer=enable_gui, console=console)
            console.print("\n[bold green]🎉 VM is running![/]")

            if paths_mapping:
                console.print("\n[bold]Inside the VM, mount shared folders with:[/]")
                for idx, (host, guest) in enumerate(paths_mapping.items()):
                    console.print(f"  [cyan]sudo mount -t 9p -o trans=virtio mount{idx} {guest}[/]")

        console.print(f"\n[dim]VM UUID: {vm_uuid}[/]")

    except Exception as e:
        console.print(f"\n[red]❌ Error: {e}[/]")
        raise


def cmd_create(args):
    """Create VM from JSON config."""
    config_data = json.loads(args.config)

    config = VMConfig(
        name=args.name,
        ram_mb=args.ram,
        vcpus=args.vcpus,
        gui=not args.no_gui,
        base_image=args.base_image,
        paths=config_data.get("paths", {}),
        packages=config_data.get("packages", []),
        services=config_data.get("services", []),
    )

    cloner = SelectiveVMCloner()
    vm_uuid = cloner.create_vm(config, console=console)

    if args.start:
        cloner.start_vm(args.name, open_viewer=not args.no_gui, console=console)

    console.print(f"[green]✅ VM created: {vm_uuid}[/]")


def cmd_start(args):
    """Start a VM or create from .clonebox.yaml."""
    name = args.name

    # Check if it's a path (contains / or . or ~)
    if name and (name.startswith(".") or name.startswith("/") or name.startswith("~")):
        # Treat as path - load .clonebox.yaml
        target_path = Path(name).expanduser().resolve()

        if target_path.is_dir():
            config_file = target_path / CLONEBOX_CONFIG_FILE
        else:
            config_file = target_path

        if not config_file.exists():
            console.print(f"[red]❌ Config not found: {config_file}[/]")
            console.print(f"[dim]Run 'clonebox clone {target_path}' first to generate config[/]")
            return

        console.print(f"[bold cyan]📦 Loading config: {config_file}[/]\n")

        config = load_clonebox_config(config_file)
        vm_name = config["vm"]["name"]

        # Check if VM already exists
        cloner = SelectiveVMCloner(user_session=getattr(args, "user", False))
        try:
            existing_vms = [v["name"] for v in cloner.list_vms()]
            if vm_name in existing_vms:
                console.print(f"[cyan]VM '{vm_name}' exists, starting...[/]")
                cloner.start_vm(vm_name, open_viewer=not args.no_viewer, console=console)
                return
        except:
            pass

        # Create new VM from config
        console.print(f"[cyan]Creating VM '{vm_name}' from config...[/]\n")
        vm_uuid = create_vm_from_config(config, start=True, user_session=getattr(args, "user", False))
        console.print(f"\n[bold green]🎉 VM '{vm_name}' is running![/]")
        console.print(f"[dim]UUID: {vm_uuid}[/]")

        if config.get("paths"):
            console.print("\n[bold]Inside VM, mount paths with:[/]")
            for idx, (host, guest) in enumerate(config["paths"].items()):
                console.print(f"  [cyan]sudo mount -t 9p -o trans=virtio mount{idx} {guest}[/]")
        return

    # Default: treat as VM name
    if not name:
        # No argument - check current directory for .clonebox.yaml
        config_file = Path.cwd() / CLONEBOX_CONFIG_FILE
        if config_file.exists():
            console.print(f"[cyan]Found {CLONEBOX_CONFIG_FILE} in current directory[/]")
            args.name = "."
            return cmd_start(args)
        else:
            console.print(
                "[red]❌ No VM name specified and no .clonebox.yaml in current directory[/]"
            )
            console.print("[dim]Usage: clonebox start <vm-name> or clonebox start .[/]")
            return

    cloner = SelectiveVMCloner(user_session=getattr(args, "user", False))
    cloner.start_vm(name, open_viewer=not args.no_viewer, console=console)


def cmd_stop(args):
    """Stop a VM."""
    cloner = SelectiveVMCloner(user_session=getattr(args, "user", False))
    cloner.stop_vm(args.name, force=args.force, console=console)


def cmd_delete(args):
    """Delete a VM."""
    if not args.yes:
        if not questionary.confirm(
            f"Delete VM '{args.name}' and its storage?", default=False, style=custom_style
        ).ask():
            console.print("[yellow]Cancelled.[/]")
            return

    cloner = SelectiveVMCloner(user_session=getattr(args, "user", False))
    cloner.delete_vm(args.name, delete_storage=not args.keep_storage, console=console)


def cmd_list(args):
    """List all VMs."""
    cloner = SelectiveVMCloner(user_session=getattr(args, "user", False))
    vms = cloner.list_vms()

    if not vms:
        console.print("[dim]No VMs found.[/]")
        return

    table = Table(title="Virtual Machines", border_style="cyan")
    table.add_column("Name", style="bold")
    table.add_column("State")
    table.add_column("UUID", style="dim")

    for vm in vms:
        state_style = "green" if vm["state"] == "running" else "dim"
        table.add_row(vm["name"], f"[{state_style}]{vm['state']}[/]", vm["uuid"][:8])

    console.print(table)


def cmd_status(args):
    """Check VM installation status and health from workstation."""
    import subprocess
    
    name = args.name
    user_session = getattr(args, "user", False)
    conn_uri = "qemu:///session" if user_session else "qemu:///system"
    
    # If name is a path, load config to get VM name
    if name and (name.startswith(".") or name.startswith("/") or name.startswith("~")):
        target_path = Path(name).expanduser().resolve()
        config_file = target_path / ".clonebox.yaml" if target_path.is_dir() else target_path
        if config_file.exists():
            config = load_clonebox_config(config_file)
            name = config["vm"]["name"]
        else:
            console.print(f"[red]❌ Config not found: {config_file}[/]")
            return
    
    if not name:
        # Try current directory
        config_file = Path.cwd() / ".clonebox.yaml"
        if config_file.exists():
            config = load_clonebox_config(config_file)
            name = config["vm"]["name"]
        else:
            console.print("[red]❌ No VM name specified and no .clonebox.yaml found[/]")
            return
    
    console.print(f"[bold cyan]📊 Checking VM status: {name}[/]\n")
    
    # Check VM state
    try:
        result = subprocess.run(
            ["virsh", "--connect", conn_uri, "domstate", name],
            capture_output=True, text=True, timeout=5
        )
        vm_state = result.stdout.strip()
        
        if "running" in vm_state.lower():
            console.print(f"[green]✅ VM State: {vm_state}[/]")
        elif "shut off" in vm_state.lower():
            console.print(f"[yellow]⏸️  VM State: {vm_state}[/]")
            console.print("[dim]Start with: clonebox start .[/]")
            return
        else:
            console.print(f"[dim]VM State: {vm_state}[/]")
    except subprocess.TimeoutExpired:
        console.print("[red]❌ Timeout checking VM state[/]")
        return
    except Exception as e:
        console.print(f"[red]❌ Error: {e}[/]")
        return
    
    # Get VM IP address
    console.print("\n[bold]🔍 Checking VM network...[/]")
    try:
        result = subprocess.run(
            ["virsh", "--connect", conn_uri, "domifaddr", name],
            capture_output=True, text=True, timeout=10
        )
        if result.stdout.strip():
            console.print(f"[dim]{result.stdout.strip()}[/]")
            # Extract IP
            for line in result.stdout.split('\n'):
                if 'ipv4' in line.lower():
                    parts = line.split()
                    for p in parts:
                        if '/' in p and '.' in p:
                            ip = p.split('/')[0]
                            console.print(f"[green]IP Address: {ip}[/]")
                            break
        else:
            console.print("[yellow]⚠️  No IP address yet (VM may still be booting)[/]")
    except Exception as e:
        console.print(f"[yellow]⚠️  Cannot get IP: {e}[/]")
    
    # Check cloud-init status via console
    console.print("\n[bold]☁️  Checking cloud-init status...[/]")
    try:
        # Use virsh console to check - this is tricky, so we check for the ready file
        result = subprocess.run(
            ["virsh", "--connect", conn_uri, "qemu-agent-command", name, 
             '{"execute":"guest-exec","arguments":{"path":"/bin/cat","arg":["/var/log/clonebox-ready"],"capture-output":true}}'],
            capture_output=True, text=True, timeout=10
        )
        if "CloneBox VM ready" in result.stdout or result.returncode == 0:
            console.print("[green]✅ Cloud-init: Complete[/]")
        else:
            console.print("[yellow]⏳ Cloud-init: Still running (packages installing)[/]")
    except Exception:
        console.print("[yellow]⏳ Cloud-init status: Unknown (QEMU agent may not be ready)[/]")
    
    # Check health status if available
    console.print("\n[bold]🏥 Health Check Status...[/]")
    try:
        result = subprocess.run(
            ["virsh", "--connect", conn_uri, "qemu-agent-command", name,
             '{"execute":"guest-exec","arguments":{"path":"/bin/cat","arg":["/var/log/clonebox-health-status"],"capture-output":true}}'],
            capture_output=True, text=True, timeout=10
        )
        if "HEALTH_STATUS=OK" in result.stdout:
            console.print("[green]✅ Health: All checks passed[/]")
        elif "HEALTH_STATUS=FAILED" in result.stdout:
            console.print("[red]❌ Health: Some checks failed[/]")
        else:
            console.print("[yellow]⏳ Health check not yet run[/]")
    except Exception:
        console.print("[dim]Health status: Not available yet[/]")
    
    # Show useful commands
    console.print("\n[bold]📋 Useful commands:[/]")
    console.print(f"  [cyan]virt-viewer --connect {conn_uri} {name}[/]  # Open GUI")
    console.print(f"  [cyan]virsh --connect {conn_uri} console {name}[/]  # Console access")
    console.print("  [dim]Inside VM:[/]")
    console.print("    [cyan]cat /var/log/clonebox-health.log[/]  # Full health report")
    console.print("    [cyan]sudo cloud-init status[/]  # Cloud-init status")
    console.print("    [cyan]clonebox-health[/]  # Re-run health check")
    
    # Run full health check if requested
    if getattr(args, "health", False):
        console.print("\n[bold]🔄 Running full health check...[/]")
        try:
            result = subprocess.run(
                ["virsh", "--connect", conn_uri, "qemu-agent-command", name,
                 '{"execute":"guest-exec","arguments":{"path":"/usr/local/bin/clonebox-health","capture-output":true}}'],
                capture_output=True, text=True, timeout=60
            )
            console.print("[green]Health check triggered. View results with:[/]")
            console.print(f"  [cyan]virsh --connect {conn_uri} console {name}[/]")
            console.print("  Then run: [cyan]cat /var/log/clonebox-health.log[/]")
        except Exception as e:
            console.print(f"[yellow]⚠️  Could not trigger health check: {e}[/]")


def cmd_export(args):
    """Export VM and data for migration to another workstation."""
    import subprocess
    import tarfile
    import shutil
    
    name = args.name
    user_session = getattr(args, "user", False)
    conn_uri = "qemu:///session" if user_session else "qemu:///system"
    include_data = getattr(args, "include_data", False)
    output = getattr(args, "output", None)
    
    # If name is a path, load config
    if name and (name.startswith(".") or name.startswith("/") or name.startswith("~")):
        target_path = Path(name).expanduser().resolve()
        config_file = target_path / ".clonebox.yaml" if target_path.is_dir() else target_path
        if config_file.exists():
            config = load_clonebox_config(config_file)
            name = config["vm"]["name"]
        else:
            console.print(f"[red]❌ Config not found: {config_file}[/]")
            return
    
    if not name:
        config_file = Path.cwd() / ".clonebox.yaml"
        if config_file.exists():
            config = load_clonebox_config(config_file)
            name = config["vm"]["name"]
        else:
            console.print("[red]❌ No VM name specified[/]")
            return
    
    console.print(f"[bold cyan]📦 Exporting VM: {name}[/]\n")
    
    # Determine storage path
    if user_session:
        storage_base = Path.home() / ".local/share/libvirt/images"
    else:
        storage_base = Path("/var/lib/libvirt/images")
    
    vm_dir = storage_base / name
    
    if not vm_dir.exists():
        console.print(f"[red]❌ VM storage not found: {vm_dir}[/]")
        return
    
    # Create export directory
    export_name = output or f"{name}-export.tar.gz"
    if not export_name.endswith(".tar.gz"):
        export_name += ".tar.gz"
    
    export_path = Path(export_name).resolve()
    temp_dir = Path(f"/tmp/clonebox-export-{name}")
    
    try:
        # Clean up temp dir if exists
        if temp_dir.exists():
            shutil.rmtree(temp_dir)
        temp_dir.mkdir(parents=True)
        
        # Stop VM if running
        console.print("[cyan]Stopping VM for export...[/]")
        subprocess.run(
            ["virsh", "--connect", conn_uri, "shutdown", name],
            capture_output=True, timeout=30
        )
        import time
        time.sleep(5)
        subprocess.run(
            ["virsh", "--connect", conn_uri, "destroy", name],
            capture_output=True, timeout=10
        )
        
        # Export VM XML
        console.print("[cyan]Exporting VM definition...[/]")
        result = subprocess.run(
            ["virsh", "--connect", conn_uri, "dumpxml", name],
            capture_output=True, text=True, timeout=30
        )
        (temp_dir / "vm.xml").write_text(result.stdout)
        
        # Copy disk image
        console.print("[cyan]Copying disk image (this may take a while)...[/]")
        disk_image = vm_dir / f"{name}.qcow2"
        if disk_image.exists():
            shutil.copy2(disk_image, temp_dir / "disk.qcow2")
        
        # Copy cloud-init ISO
        cloudinit_iso = vm_dir / "cloud-init.iso"
        if cloudinit_iso.exists():
            shutil.copy2(cloudinit_iso, temp_dir / "cloud-init.iso")
        
        # Copy config file
        config_file = Path.cwd() / ".clonebox.yaml"
        if config_file.exists():
            shutil.copy2(config_file, temp_dir / ".clonebox.yaml")
        
        # Copy .env file (without sensitive data warning)
        env_file = Path.cwd() / ".env"
        if env_file.exists():
            shutil.copy2(env_file, temp_dir / ".env")
        
        # Include shared data if requested
        if include_data:
            console.print("[cyan]Bundling shared data (browser profiles, configs)...[/]")
            data_dir = temp_dir / "data"
            data_dir.mkdir()
            
            # Load config to get paths
            if config_file.exists():
                config = load_clonebox_config(config_file)
                all_paths = config.get("paths", {}).copy()
                all_paths.update(config.get("app_data_paths", {}))
                
                for idx, (host_path, guest_path) in enumerate(all_paths.items()):
                    host_p = Path(host_path)
                    if host_p.exists():
                        dest = data_dir / f"mount{idx}"
                        console.print(f"  [dim]Copying {host_path}...[/]")
                        try:
                            if host_p.is_dir():
                                shutil.copytree(host_p, dest, symlinks=True, 
                                              ignore=shutil.ignore_patterns('*.pyc', '__pycache__', '.git'))
                            else:
                                shutil.copy2(host_p, dest)
                        except Exception as e:
                            console.print(f"  [yellow]⚠️  Skipped {host_path}: {e}[/]")
                
                # Save path mapping
                import json
                (data_dir / "paths.json").write_text(json.dumps(all_paths, indent=2))
        
        # Create tarball
        console.print(f"[cyan]Creating archive: {export_path}[/]")
        with tarfile.open(export_path, "w:gz") as tar:
            tar.add(temp_dir, arcname=name)
        
        # Get size
        size_mb = export_path.stat().st_size / 1024 / 1024
        
        console.print(f"\n[bold green]✅ Export complete![/]")
        console.print(f"   File: [cyan]{export_path}[/]")
        console.print(f"   Size: [cyan]{size_mb:.1f} MB[/]")
        console.print(f"\n[bold]To import on another workstation:[/]")
        console.print(f"   [cyan]clonebox import {export_path.name}[/]")
        
    finally:
        # Cleanup
        if temp_dir.exists():
            shutil.rmtree(temp_dir)
        
        # Restart VM
        console.print("\n[cyan]Restarting VM...[/]")
        subprocess.run(
            ["virsh", "--connect", conn_uri, "start", name],
            capture_output=True, timeout=30
        )


def cmd_import(args):
    """Import VM from export archive."""
    import subprocess
    import tarfile
    import shutil
    
    archive_path = Path(args.archive).resolve()
    user_session = getattr(args, "user", False)
    conn_uri = "qemu:///session" if user_session else "qemu:///system"
    
    if not archive_path.exists():
        console.print(f"[red]❌ Archive not found: {archive_path}[/]")
        return
    
    console.print(f"[bold cyan]📥 Importing VM from: {archive_path}[/]\n")
    
    # Determine storage path
    if user_session:
        storage_base = Path.home() / ".local/share/libvirt/images"
    else:
        storage_base = Path("/var/lib/libvirt/images")
    
    storage_base.mkdir(parents=True, exist_ok=True)
    
    temp_dir = Path(f"/tmp/clonebox-import-{archive_path.stem}")
    
    try:
        # Extract archive
        console.print("[cyan]Extracting archive...[/]")
        if temp_dir.exists():
            shutil.rmtree(temp_dir)
        temp_dir.mkdir(parents=True)
        
        with tarfile.open(archive_path, "r:gz") as tar:
            tar.extractall(temp_dir)
        
        # Find extracted VM directory
        vm_dirs = list(temp_dir.iterdir())
        if not vm_dirs:
            console.print("[red]❌ Empty archive[/]")
            return
        
        extracted_dir = vm_dirs[0]
        vm_name = extracted_dir.name
        
        console.print(f"[cyan]VM Name: {vm_name}[/]")
        
        # Create VM storage directory
        vm_storage = storage_base / vm_name
        if vm_storage.exists():
            if not getattr(args, "replace", False):
                console.print(f"[red]❌ VM '{vm_name}' already exists. Use --replace to overwrite.[/]")
                return
            shutil.rmtree(vm_storage)
        
        vm_storage.mkdir(parents=True)
        
        # Copy disk image
        console.print("[cyan]Copying disk image...[/]")
        disk_src = extracted_dir / "disk.qcow2"
        if disk_src.exists():
            shutil.copy2(disk_src, vm_storage / f"{vm_name}.qcow2")
        
        # Copy cloud-init ISO
        cloudinit_src = extracted_dir / "cloud-init.iso"
        if cloudinit_src.exists():
            shutil.copy2(cloudinit_src, vm_storage / "cloud-init.iso")
        
        # Copy config files to current directory
        config_src = extracted_dir / ".clonebox.yaml"
        if config_src.exists():
            shutil.copy2(config_src, Path.cwd() / ".clonebox.yaml")
            console.print("[green]✅ Copied .clonebox.yaml[/]")
        
        env_src = extracted_dir / ".env"
        if env_src.exists():
            shutil.copy2(env_src, Path.cwd() / ".env")
            console.print("[green]✅ Copied .env[/]")
        
        # Restore data if included
        data_dir = extracted_dir / "data"
        if data_dir.exists():
            import json
            paths_file = data_dir / "paths.json"
            if paths_file.exists():
                paths_mapping = json.loads(paths_file.read_text())
                console.print("\n[cyan]Restoring shared data...[/]")
                
                for idx, (host_path, guest_path) in enumerate(paths_mapping.items()):
                    src = data_dir / f"mount{idx}"
                    if src.exists():
                        dest = Path(host_path)
                        console.print(f"  [dim]Restoring to {host_path}...[/]")
                        try:
                            if dest.exists():
                                console.print(f"    [yellow]⚠️  Skipped (already exists)[/]")
                            else:
                                dest.parent.mkdir(parents=True, exist_ok=True)
                                if src.is_dir():
                                    shutil.copytree(src, dest)
                                else:
                                    shutil.copy2(src, dest)
                        except Exception as e:
                            console.print(f"    [yellow]⚠️  Error: {e}[/]")
        
        # Modify and define VM XML
        console.print("\n[cyan]Defining VM...[/]")
        xml_src = extracted_dir / "vm.xml"
        if xml_src.exists():
            xml_content = xml_src.read_text()
            
            # Update paths in XML to new storage location
            # This is a simple replacement - may need more sophisticated handling
            xml_content = xml_content.replace(
                f"/home/", f"{Path.home()}/"
            )
            
            # Write modified XML
            modified_xml = temp_dir / "vm-modified.xml"
            modified_xml.write_text(xml_content)
            
            # Define VM
            result = subprocess.run(
                ["virsh", "--connect", conn_uri, "define", str(modified_xml)],
                capture_output=True, text=True, timeout=30
            )
            
            if result.returncode == 0:
                console.print(f"[green]✅ VM '{vm_name}' defined successfully![/]")
            else:
                console.print(f"[yellow]⚠️  VM definition warning: {result.stderr}[/]")
        
        console.print(f"\n[bold green]✅ Import complete![/]")
        console.print(f"\n[bold]To start the VM:[/]")
        console.print(f"   [cyan]clonebox start . {'--user' if user_session else ''}[/]")
        
    finally:
        # Cleanup
        if temp_dir.exists():
            shutil.rmtree(temp_dir)


CLONEBOX_CONFIG_FILE = ".clonebox.yaml"
CLONEBOX_ENV_FILE = ".env"


def load_env_file(env_path: Path) -> dict:
    """Load environment variables from .env file."""
    env_vars = {}
    if not env_path.exists():
        return env_vars
    
    with open(env_path) as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith('#'):
                continue
            if '=' in line:
                key, value = line.split('=', 1)
                env_vars[key.strip()] = value.strip()
    
    return env_vars


def expand_env_vars(value, env_vars: dict):
    """Expand environment variables in string values like ${VAR_NAME}."""
    if isinstance(value, str):
        # Replace ${VAR_NAME} with value from env_vars or os.environ
        def replacer(match):
            var_name = match.group(1)
            return env_vars.get(var_name, os.environ.get(var_name, match.group(0)))
        return re.sub(r'\$\{([^}]+)\}', replacer, value)
    elif isinstance(value, dict):
        return {k: expand_env_vars(v, env_vars) for k, v in value.items()}
    elif isinstance(value, list):
        return [expand_env_vars(item, env_vars) for item in value]
    return value


def deduplicate_list(items: list, key=None) -> list:
    """Remove duplicates from list, preserving order."""
    seen = set()
    result = []
    for item in items:
        k = key(item) if key else item
        if k not in seen:
            seen.add(k)
            result.append(item)
    return result


def generate_clonebox_yaml(
    snapshot,
    detector,
    deduplicate: bool = True,
    target_path: str = None,
    vm_name: str = None,
    network_mode: str = "auto",
    base_image: Optional[str] = None,
) -> str:
    """Generate YAML config from system snapshot."""
    sys_info = detector.get_system_info()

    # Collect services
    services = [s.name for s in snapshot.running_services]
    if deduplicate:
        services = deduplicate_list(services)

    # Collect paths with types
    paths_by_type = {"project": [], "config": [], "data": []}
    for p in snapshot.paths:
        if p.type in paths_by_type:
            paths_by_type[p.type].append(p.path)

    if deduplicate:
        for ptype in paths_by_type:
            paths_by_type[ptype] = deduplicate_list(paths_by_type[ptype])

    # Collect working directories from running apps
    working_dirs = []
    for app in snapshot.applications:
        if app.working_dir and app.working_dir != "/" and app.working_dir.startswith("/home"):
            working_dirs.append(app.working_dir)

    if deduplicate:
        working_dirs = deduplicate_list(working_dirs)

    # If target_path specified, prioritize it
    if target_path:
        target_path = Path(target_path).resolve()
        target_str = str(target_path)
        if target_str not in paths_by_type["project"]:
            paths_by_type["project"].insert(0, target_str)

    # Build paths mapping
    paths_mapping = {}
    idx = 0
    for host_path in paths_by_type["project"][:5]:  # Limit projects
        paths_mapping[host_path] = f"/mnt/project{idx}"
        idx += 1

    for host_path in working_dirs[:3]:  # Limit working dirs
        if host_path not in paths_mapping:
            paths_mapping[host_path] = f"/mnt/workdir{idx}"
            idx += 1

    # Add default user folders (Downloads, Documents)
    home_dir = Path.home()
    default_folders = [
        (home_dir / "Downloads", "/home/ubuntu/Downloads"),
        (home_dir / "Documents", "/home/ubuntu/Documents"),
    ]
    for host_folder, guest_folder in default_folders:
        if host_folder.exists() and str(host_folder) not in paths_mapping:
            paths_mapping[str(host_folder)] = guest_folder

    # Detect and add app-specific data directories for running applications
    # This includes browser profiles, IDE settings, credentials, extensions, etc.
    app_data_dirs = detector.detect_app_data_dirs(snapshot.applications)
    app_data_mapping = {}
    for app_data in app_data_dirs:
        host_path = app_data["path"]
        if host_path not in paths_mapping:
            # Map to same relative path in VM user home
            rel_path = host_path.replace(str(home_dir), "").lstrip("/")
            guest_path = f"/home/ubuntu/{rel_path}"
            app_data_mapping[host_path] = guest_path

    # Determine VM name
    if not vm_name:
        if target_path:
            vm_name = f"clone-{target_path.name}"
        else:
            vm_name = f"clone-{sys_info['hostname']}"

    # Calculate recommended resources
    ram_mb = min(4096, int(sys_info["memory_available_gb"] * 1024 * 0.5))
    vcpus = max(2, sys_info["cpu_count"] // 2)

    # Auto-detect packages from running applications and services
    app_packages = detector.suggest_packages_for_apps(snapshot.applications)
    service_packages = detector.suggest_packages_for_services(snapshot.running_services)
    
    # Combine with base packages (apt only)
    base_packages = [
        "build-essential",
        "git",
        "curl",
        "vim",
    ]
    
    # Merge apt packages and deduplicate
    all_apt_packages = base_packages + app_packages["apt"] + service_packages["apt"]
    if deduplicate:
        all_apt_packages = deduplicate_list(all_apt_packages)
    
    # Merge snap packages and deduplicate
    all_snap_packages = app_packages["snap"] + service_packages["snap"]
    if deduplicate:
        all_snap_packages = deduplicate_list(all_snap_packages)

    # Build config
    config = {
        "version": "1",
        "generated": datetime.now().isoformat(),
        "vm": {
            "name": vm_name,
            "ram_mb": ram_mb,
            "vcpus": vcpus,
            "gui": True,
            "base_image": base_image,
            "network_mode": network_mode,
            "username": "ubuntu",
            "password": "${VM_PASSWORD}",
        },
        "services": services,
        "packages": all_apt_packages,
        "snap_packages": all_snap_packages,
        "post_commands": [],  # User can add custom commands to run after setup
        "paths": paths_mapping,
        "app_data_paths": app_data_mapping,  # App-specific config/data directories
        "detected": {
            "running_apps": [
                {"name": a.name, "cwd": a.working_dir or "", "memory_mb": round(a.memory_mb)}
                for a in snapshot.applications[:10]
            ],
            "app_data_dirs": [
                {"path": d["path"], "app": d["app"], "size_mb": d["size_mb"]}
                for d in app_data_dirs[:15]
            ],
            "all_paths": {
                "projects": list(paths_by_type["project"]),
                "configs": list(paths_by_type["config"][:5]),
                "data": list(paths_by_type["data"][:5]),
            },
        },
    }

    return yaml.dump(config, default_flow_style=False, allow_unicode=True, sort_keys=False)


def load_clonebox_config(path: Path) -> dict:
    """Load .clonebox.yaml config file and expand environment variables from .env."""
    config_file = path / CLONEBOX_CONFIG_FILE if path.is_dir() else path

    if not config_file.exists():
        raise FileNotFoundError(f"Config file not found: {config_file}")

    # Load .env file from same directory
    config_dir = config_file.parent
    env_file = config_dir / CLONEBOX_ENV_FILE
    env_vars = load_env_file(env_file)

    # Load YAML config
    with open(config_file) as f:
        config = yaml.safe_load(f)
    
    # Expand environment variables in config
    config = expand_env_vars(config, env_vars)
    
    return config


def monitor_cloud_init_status(vm_name: str, user_session: bool = False, timeout: int = 900):
    """Monitor cloud-init status in VM and show progress."""
    import subprocess
    import time
    
    conn_uri = "qemu:///session" if user_session else "qemu:///system"
    start_time = time.time()
    shutdown_count = 0  # Count consecutive shutdown detections
    restart_detected = False
    
    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        console=console,
    ) as progress:
        task = progress.add_task("[cyan]Starting VM and initializing...", total=None)
        
        while time.time() - start_time < timeout:
            try:
                elapsed = int(time.time() - start_time)
                minutes = elapsed // 60
                seconds = elapsed % 60
                
                # Check VM state
                result = subprocess.run(
                    ["virsh", "--connect", conn_uri, "domstate", vm_name],
                    capture_output=True,
                    text=True,
                    timeout=5
                )
                
                vm_state = result.stdout.strip().lower()
                
                if "shut off" in vm_state or "shutting down" in vm_state:
                    # VM is shutting down - count consecutive detections
                    shutdown_count += 1
                    if shutdown_count >= 3 and not restart_detected:
                        # Confirmed shutdown after 3 consecutive checks
                        restart_detected = True
                        progress.update(task, description="[yellow]⟳ VM restarting after package installation...")
                    time.sleep(3)
                    continue
                else:
                    # VM is running - reset shutdown counter
                    if shutdown_count > 0 and shutdown_count < 3:
                        # Was a brief glitch, not a real shutdown
                        shutdown_count = 0
                
                if restart_detected and "running" in vm_state and shutdown_count >= 3:
                    # VM restarted successfully - GUI should be ready
                    progress.update(task, description=f"[green]✓ GUI ready! Total time: {minutes}m {seconds}s")
                    time.sleep(2)
                    break
                
                # Estimate remaining time (total ~12-15 minutes for full desktop install)
                if elapsed < 60:
                    remaining = "~12-15 minutes"
                elif elapsed < 300:
                    remaining = f"~{12 - minutes} minutes"
                elif elapsed < 600:
                    remaining = f"~{10 - minutes} minutes"
                elif elapsed < 800:
                    remaining = "finishing soon..."
                else:
                    remaining = "almost done"
                
                if restart_detected:
                    progress.update(task, description=f"[cyan]Starting GUI... ({minutes}m {seconds}s, {remaining})")
                else:
                    progress.update(task, description=f"[cyan]Installing desktop packages... ({minutes}m {seconds}s, {remaining})")
                
            except (subprocess.TimeoutExpired, Exception) as e:
                elapsed = int(time.time() - start_time)
                minutes = elapsed // 60
                seconds = elapsed % 60
                progress.update(task, description=f"[cyan]Configuring VM... ({minutes}m {seconds}s)")
            
            time.sleep(3)
        
        # Final status
        if time.time() - start_time >= timeout:
            progress.update(task, description="[yellow]⚠ Monitoring timeout - VM continues in background")


def create_vm_from_config(
    config: dict,
    start: bool = False,
    user_session: bool = False,
    replace: bool = False,
) -> str:
    """Create VM from YAML config dict."""
    # Merge paths and app_data_paths
    all_paths = config.get("paths", {}).copy()
    all_paths.update(config.get("app_data_paths", {}))
    
    vm_config = VMConfig(
        name=config["vm"]["name"],
        ram_mb=config["vm"].get("ram_mb", 4096),
        vcpus=config["vm"].get("vcpus", 4),
        gui=config["vm"].get("gui", True),
        base_image=config["vm"].get("base_image"),
        paths=all_paths,
        packages=config.get("packages", []),
        snap_packages=config.get("snap_packages", []),
        services=config.get("services", []),
        post_commands=config.get("post_commands", []),
        user_session=user_session,
        network_mode=config["vm"].get("network_mode", "auto"),
        username=config["vm"].get("username", "ubuntu"),
        password=config["vm"].get("password", "ubuntu"),
    )

    cloner = SelectiveVMCloner(user_session=user_session)

    # Check prerequisites and show detailed info
    checks = cloner.check_prerequisites()

    if not checks["images_dir_writable"]:
        console.print(f"[yellow]⚠️  Storage directory: {checks['images_dir']}[/]")
        if "images_dir_error" in checks:
            console.print(f"[red]{checks['images_dir_error']}[/]")
            raise PermissionError(checks["images_dir_error"])

    console.print(f"[dim]Session: {checks['session_type']}, Storage: {checks['images_dir']}[/]")

    vm_uuid = cloner.create_vm(vm_config, console=console, replace=replace)

    if start:
        cloner.start_vm(vm_config.name, open_viewer=vm_config.gui, console=console)
        
        # Monitor cloud-init progress if GUI is enabled
        if vm_config.gui:
            console.print("\n[bold cyan]📊 Monitoring setup progress...[/]")
            try:
                monitor_cloud_init_status(vm_config.name, user_session=user_session)
            except KeyboardInterrupt:
                console.print("\n[yellow]Monitoring stopped. VM continues setup in background.[/]")
            except Exception as e:
                console.print(f"\n[dim]Note: Could not monitor status ({e}). VM continues setup in background.[/]")

    return vm_uuid


def cmd_clone(args):
    """Generate clone config from path and optionally create VM."""
    target_path = Path(args.path).resolve()

    if not target_path.exists():
        console.print(f"[red]❌ Path does not exist: {target_path}[/]")
        return

    console.print(f"[bold cyan]📦 Generating clone config for: {target_path}[/]\n")

    # Detect system state
    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        console=console,
        transient=True,
    ) as progress:
        progress.add_task("Scanning system...", total=None)
        detector = SystemDetector()
        snapshot = detector.detect_all()

    # Generate config
    vm_name = args.name or f"clone-{target_path.name}"
    yaml_content = generate_clonebox_yaml(
        snapshot,
        detector,
        deduplicate=args.dedupe,
        target_path=str(target_path),
        vm_name=vm_name,
        network_mode=args.network,
        base_image=getattr(args, "base_image", None),
    )

    # Save config file
    config_file = (
        target_path / CLONEBOX_CONFIG_FILE
        if target_path.is_dir()
        else target_path.parent / CLONEBOX_CONFIG_FILE
    )
    config_file.write_text(yaml_content)
    console.print(f"[green]✅ Config saved: {config_file}[/]\n")

    # Show config
    console.print(Panel(yaml_content, title="[bold].clonebox.yaml[/]", border_style="cyan"))

    # Open in editor if requested
    if args.edit:
        editor = os.environ.get("EDITOR", "nano")
        console.print(f"[cyan]Opening {editor}...[/]")
        os.system(f"{editor} {config_file}")
        # Reload after edit
        yaml_content = config_file.read_text()

    # Ask to create VM
    if args.run:
        create_now = True
    else:
        create_now = questionary.confirm(
            "Create VM with this config?", default=True, style=custom_style
        ).ask()

    if create_now:
        # Load config with environment variable expansion
        config = load_clonebox_config(config_file.parent)
        user_session = getattr(args, "user", False)

        console.print("\n[bold cyan]🔧 Creating VM...[/]\n")
        if user_session:
            console.print("[cyan]Using user session (qemu:///session) - no root required[/]")

        try:
            vm_uuid = create_vm_from_config(
                config,
                start=True,
                user_session=user_session,
                replace=getattr(args, "replace", False),
            )
            console.print(f"\n[bold green]🎉 VM '{config['vm']['name']}' is running![/]")
            console.print(f"[dim]UUID: {vm_uuid}[/]")

            # Show GUI startup info if GUI is enabled
            if config.get("vm", {}).get("gui", False):
                username = config['vm'].get('username', 'ubuntu')
                password = config['vm'].get('password', 'ubuntu')
                console.print("\n[bold yellow]⏰ GUI Setup Process:[/]")
                console.print("  [yellow]•[/] Installing desktop environment (~5-10 minutes)")
                console.print("  [yellow]•[/] Running health checks on all components")
                console.print("  [yellow]•[/] Automatic restart after installation")
                console.print("  [yellow]•[/] GUI login screen will appear")
                console.print(f"  [yellow]•[/] Login: [cyan]{username}[/] / [cyan]{'*' * len(password)}[/] (from .env)")
                console.print("\n[dim]💡 Progress will be monitored automatically below[/]")

            # Show health check info
            console.print("\n[bold]📊 Health Check (inside VM):[/]")
            console.print("  [cyan]cat /var/log/clonebox-health.log[/]  # View full report")
            console.print("  [cyan]cat /var/log/clonebox-health-status[/]  # Quick status")
            console.print("  [cyan]clonebox-health[/]  # Re-run health check")

            # Show mount instructions
            all_paths = config.get("paths", {}).copy()
            all_paths.update(config.get("app_data_paths", {}))
            if all_paths:
                console.print("\n[bold]📁 Mounted paths (automatic):[/]")
                for idx, (host, guest) in enumerate(list(all_paths.items())[:5]):
                    console.print(f"  [dim]{host}[/] → [cyan]{guest}[/]")
                if len(all_paths) > 5:
                    console.print(f"  [dim]... and {len(all_paths) - 5} more paths[/]")
        except PermissionError as e:
            console.print(f"[red]❌ Permission Error:[/]\n{e}")
            console.print("\n[yellow]💡 Try running with --user flag:[/]")
            console.print(f"  [cyan]clonebox clone {target_path} --user[/]")
        except Exception as e:
            console.print(f"[red]❌ Error: {e}[/]")
    else:
        console.print("\n[dim]To create VM later, run:[/]")
        console.print(f"  [cyan]clonebox start {target_path}[/]")


def cmd_detect(args):
    """Detect and show system state."""
    console.print("[bold cyan]🔍 Detecting system state...[/]\n")

    detector = SystemDetector()
    snapshot = detector.detect_all()

    # JSON output
    if args.json:
        result = {
            "services": [{"name": s.name, "status": s.status} for s in snapshot.running_services],
            "applications": [
                {"name": a.name, "pid": a.pid, "cwd": a.working_dir} for a in snapshot.applications
            ],
            "paths": [
                {"path": p.path, "type": p.type, "size_mb": p.size_mb} for p in snapshot.paths
            ],
        }
        print(json.dumps(result, indent=2))
        return

    # YAML output
    if args.yaml:
        result = generate_clonebox_yaml(snapshot, detector, deduplicate=args.dedupe)

        if args.output:
            output_path = Path(args.output)
            output_path.write_text(result)
            console.print(f"[green]✅ Config saved to: {output_path}[/]")
        else:
            print(result)
        return

    # Services
    services = detector.detect_services()
    running = [s for s in services if s.status == "running"]

    if running:
        table = Table(title="Running Services", border_style="green")
        table.add_column("Service")
        table.add_column("Status")
        table.add_column("Enabled")

        for svc in running:
            table.add_row(svc.name, f"[green]{svc.status}[/]", "✓" if svc.enabled else "")

        console.print(table)

    # Applications
    apps = detector.detect_applications()

    if apps:
        console.print()
        table = Table(title="Running Applications", border_style="blue")
        table.add_column("Name")
        table.add_column("PID")
        table.add_column("Memory")
        table.add_column("Working Dir")

        for app in apps[:15]:
            table.add_row(
                app.name,
                str(app.pid),
                f"{app.memory_mb:.0f} MB",
                app.working_dir[:40] if app.working_dir else "",
            )

        console.print(table)

    # Paths
    paths = detector.detect_paths()

    if paths:
        console.print()
        table = Table(title="Detected Paths", border_style="yellow")
        table.add_column("Type")
        table.add_column("Path")
        table.add_column("Size")

        for p in paths[:20]:
            table.add_row(
                f"[cyan]{p.type}[/]", p.path, f"{p.size_mb:.0f} MB" if p.size_mb > 0 else "-"
            )

        console.print(table)


def main():
    """Main entry point."""
    parser = argparse.ArgumentParser(
        prog="clonebox", description="Clone your workstation environment to an isolated VM"
    )
    parser.add_argument("--version", action="version", version=f"clonebox {__version__}")

    subparsers = parser.add_subparsers(dest="command", help="Commands")

    # Interactive mode (default)
    parser.set_defaults(func=lambda args: interactive_mode())

    # Create command
    create_parser = subparsers.add_parser("create", help="Create VM from config")
    create_parser.add_argument("--name", "-n", default="clonebox-vm", help="VM name")
    create_parser.add_argument(
        "--config",
        "-c",
        required=True,
        help='JSON config: {"paths": {}, "packages": [], "services": []}',
    )
    create_parser.add_argument("--ram", type=int, default=4096, help="RAM in MB")
    create_parser.add_argument("--vcpus", type=int, default=4, help="Number of vCPUs")
    create_parser.add_argument("--base-image", help="Path to base qcow2 image")
    create_parser.add_argument("--no-gui", action="store_true", help="Disable SPICE graphics")
    create_parser.add_argument("--start", "-s", action="store_true", help="Start VM after creation")
    create_parser.set_defaults(func=cmd_create)

    # Start command
    start_parser = subparsers.add_parser("start", help="Start a VM")
    start_parser.add_argument(
        "name", nargs="?", default=None, help="VM name or '.' to use .clonebox.yaml"
    )
    start_parser.add_argument("--no-viewer", action="store_true", help="Don't open virt-viewer")
    start_parser.add_argument(
        "-u",
        "--user",
        action="store_true",
        help="Use user session (qemu:///session) - no root required",
    )
    start_parser.set_defaults(func=cmd_start)

    # Stop command
    stop_parser = subparsers.add_parser("stop", help="Stop a VM")
    stop_parser.add_argument("name", help="VM name")
    stop_parser.add_argument("--force", "-f", action="store_true", help="Force stop")
    stop_parser.add_argument(
        "-u",
        "--user",
        action="store_true",
        help="Use user session (qemu:///session) - no root required",
    )
    stop_parser.set_defaults(func=cmd_stop)

    # Delete command
    delete_parser = subparsers.add_parser("delete", help="Delete a VM")
    delete_parser.add_argument("name", help="VM name")
    delete_parser.add_argument("--yes", "-y", action="store_true", help="Skip confirmation")
    delete_parser.add_argument("--keep-storage", action="store_true", help="Keep disk images")
    delete_parser.add_argument(
        "-u",
        "--user",
        action="store_true",
        help="Use user session (qemu:///session) - no root required",
    )
    delete_parser.set_defaults(func=cmd_delete)

    # List command
    list_parser = subparsers.add_parser("list", aliases=["ls"], help="List VMs")
    list_parser.add_argument(
        "-u",
        "--user",
        action="store_true",
        help="Use user session (qemu:///session) - no root required",
    )
    list_parser.set_defaults(func=cmd_list)

    # Detect command
    detect_parser = subparsers.add_parser("detect", help="Detect system state")
    detect_parser.add_argument("--json", action="store_true", help="Output as JSON")
    detect_parser.add_argument("--yaml", action="store_true", help="Output as YAML config")
    detect_parser.add_argument("--dedupe", action="store_true", help="Remove duplicate entries")
    detect_parser.add_argument("-o", "--output", help="Save output to file")
    detect_parser.set_defaults(func=cmd_detect)

    # Clone command
    clone_parser = subparsers.add_parser("clone", help="Generate clone config from path")
    clone_parser.add_argument(
        "path", nargs="?", default=".", help="Path to clone (default: current dir)"
    )
    clone_parser.add_argument("--name", "-n", help="VM name (default: directory name)")
    clone_parser.add_argument(
        "--run", "-r", action="store_true", help="Create and start VM immediately"
    )
    clone_parser.add_argument(
        "--edit", "-e", action="store_true", help="Open config in editor before creating"
    )
    clone_parser.add_argument(
        "--dedupe", action="store_true", default=True, help="Remove duplicate entries"
    )
    clone_parser.add_argument(
        "--user",
        "-u",
        action="store_true",
        help="Use user session (qemu:///session) - no root required, stores in ~/.local/share/libvirt/",
    )
    clone_parser.add_argument(
        "--network",
        choices=["auto", "default", "user"],
        default="auto",
        help="Network mode: auto (default), default (libvirt network), user (slirp)",
    )
    clone_parser.add_argument(
        "--base-image",
        help="Path to a bootable qcow2 image to use as a base disk",
    )
    clone_parser.add_argument(
        "--replace",
        action="store_true",
        help="If VM already exists, stop+undefine it and recreate (also deletes its storage)",
    )
    clone_parser.set_defaults(func=cmd_clone)

    # Status command - check VM health from workstation
    status_parser = subparsers.add_parser("status", help="Check VM installation status and health")
    status_parser.add_argument(
        "name", nargs="?", default=None, help="VM name or '.' to use .clonebox.yaml"
    )
    status_parser.add_argument(
        "-u",
        "--user",
        action="store_true",
        help="Use user session (qemu:///session)",
    )
    status_parser.add_argument(
        "--health", "-H", action="store_true", help="Run full health check"
    )
    status_parser.set_defaults(func=cmd_status)

    # Export command - package VM for migration
    export_parser = subparsers.add_parser("export", help="Export VM and data for migration")
    export_parser.add_argument(
        "name", nargs="?", default=None, help="VM name or '.' to use .clonebox.yaml"
    )
    export_parser.add_argument(
        "-u", "--user", action="store_true", help="Use user session (qemu:///session)"
    )
    export_parser.add_argument(
        "-o", "--output", help="Output archive filename (default: <vmname>-export.tar.gz)"
    )
    export_parser.add_argument(
        "--include-data", "-d", action="store_true",
        help="Include shared data (browser profiles, configs) in export"
    )
    export_parser.set_defaults(func=cmd_export)

    # Import command - restore VM from export
    import_parser = subparsers.add_parser("import", help="Import VM from export archive")
    import_parser.add_argument("archive", help="Path to export archive (.tar.gz)")
    import_parser.add_argument(
        "-u", "--user", action="store_true", help="Use user session (qemu:///session)"
    )
    import_parser.add_argument(
        "--replace", action="store_true", help="Replace existing VM if exists"
    )
    import_parser.set_defaults(func=cmd_import)

    args = parser.parse_args()

    if hasattr(args, "func"):
        try:
            args.func(args)
        except KeyboardInterrupt:
            console.print("\n[yellow]Interrupted.[/]")
            sys.exit(1)
        except Exception as e:
            console.print(f"[red]Error: {e}[/]")
            sys.exit(1)
    else:
        interactive_mode()


if __name__ == "__main__":
    main()
