#!/usr/bin/env bash

# Copyright (c) 2021-2025 community-scripts ORG
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Universal VM Template Manager - Create, Deploy, List Templates with optional Cloud-Init

set -euo pipefail

# ============================================================================
# OS IMAGE CATALOG
# ============================================================================

declare -A OS_IMAGES=(
    # Debian - Cloud-Init enabled
    ["debian-13"]="https://cloud.debian.org/images/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2"
    ["debian-12"]="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2"

    # Debian - NoCloud variants (without cloud-init pre-installed)
    ["debian-13-nocloud"]="https://cloud.debian.org/images/cloud/trixie/latest/debian-13-nocloud-amd64.qcow2"
    ["debian-12-nocloud"]="https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-nocloud-amd64.qcow2"

    # Ubuntu - Cloud-Init enabled
    ["ubuntu-24.04"]="https://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img"
    ["ubuntu-22.04"]="https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img"
    ["ubuntu-20.04"]="https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-amd64.img"

    # AlmaLinux
    ["alma-9"]="https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
    ["alma-8"]="https://repo.almalinux.org/almalinux/8/cloud/x86_64/images/AlmaLinux-8-GenericCloud-latest.x86_64.qcow2"

    # Rocky Linux
    ["rocky-9"]="https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2"
    ["rocky-8"]="https://dl.rockylinux.org/pub/rocky/8/images/x86_64/Rocky-8-GenericCloud-Base.latest.x86_64.qcow2"

    # Fedora
    ["fedora-41"]="https://download.fedoraproject.org/pub/fedora/linux/releases/41/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2"
    ["fedora-40"]="https://download.fedoraproject.org/pub/fedora/linux/releases/40/Cloud/x86_64/images/Fedora-Cloud-Base-Generic-40-1.14.x86_64.qcow2"

    # Arch Linux
    ["arch"]="https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"

    # CentOS Stream
    ["centos-9"]="https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2"

    # Alpine Linux
    ["alpine-3.20"]="https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/cloud/generic_alpine-3.20.0-x86_64-bios-cloudinit-r0.qcow2"
)

# ============================================================================
# CONFIGURATION
# ============================================================================

# Defaults
MODE=""
TEMPLATE_PREFIX="template"
TEMPLATE_ID_START=900
VMID=""
OS_KEY=""
HOSTNAME=""
CORES=2
MEMORY=2048
DISK_SIZE=30
STORAGE=""
BRIDGE="vmbr0"
START_VM="no"
MACHINE_TYPE="q35"

# Cloud-Init Options
ENABLE_CLOUDINIT="yes" # yes|no - Enable/disable cloud-init drive
CI_USER=""
CI_PASSWORD=""
CI_SSH_KEY=""
CI_FILE=""

# Post-Install Scripts
POST_INSTALL=""          # none|docker|podman|portainer
POST_INSTALL_TIMEOUT=300 # Timeout in seconds for post-install completion

# Interactive Mode
INTERACTIVE_MODE="no" # yes|no - Enable whiptail interactive mode

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;36m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'

# ============================================================================
# HELPER FUNCTIONS
# ============================================================================

info() { echo -e "${BLUE}ℹ${NC} $*"; }
ok() { echo -e "${GREEN}✓${NC} $*"; }
error() {
    echo -e "${RED}✗${NC} $*" >&2
    exit 1
}
warn() { echo -e "${YELLOW}⚠${NC} $*"; }

get_next_vmid() {
    local start_id=${1:-100}
    local id=$start_id
    while [ -f "/etc/pve/qemu-server/${id}.conf" ] || [ -f "/etc/pve/lxc/${id}.conf" ]; do
        id=$((id + 1))
    done
    echo "$id"
}

get_default_storage() {
    pvesm status -content images 2>/dev/null | awk 'NR==2 {print $1}' || echo "local-lvm"
}

list_storage_pools() {
    pvesm status -content images 2>/dev/null | awk 'NR>1 {print $1}'
}

get_snippet_storage() {
    pvesm status -content snippets 2>/dev/null | awk 'NR==2 {print $1}' || echo "local"
}

find_template_by_name() {
    local name=$1
    qm list 2>/dev/null | awk -v n="$name" '$2 == n {print $1; exit}'
}

is_template() {
    local vmid=$1
    qm config "$vmid" 2>/dev/null | grep -q "^template: 1"
}

cleanup_vm() {
    if [ -n "${VMID:-}" ] && qm status "$VMID" &>/dev/null; then
        warn "Cleanup: Removing VM $VMID"
        qm destroy "$VMID" &>/dev/null || true
    fi
}

# ============================================================================
# INTERACTIVE WHIPTAIL MENUS
# ============================================================================

interactive_main_menu() {
    local choice
    choice=$(whiptail --title "VM Manager" --menu "Choose action:" 20 70 10 \
        "1" "Create VM Template" \
        "2" "Deploy VM from Template" \
        "3" "List Templates" \
        "4" "List Available OS Images" \
        "5" "Exit" \
        3>&1 1>&2 2>&3)

    case $choice in
    1) interactive_create_template ;;
    2) interactive_deploy_vm ;;
    3)
        list_templates
        read -p "Press Enter to continue..."
        interactive_main_menu
        ;;
    4)
        list_os_options
        read -p "Press Enter to continue..."
        interactive_main_menu
        ;;
    5) exit 0 ;;
    *) exit 0 ;;
    esac
}

interactive_select_os() {
    local menu_items=()
    local i=1

    for key in $(echo "${!OS_IMAGES[@]}" | tr ' ' '\n' | sort); do
        menu_items+=("$key" "${OS_IMAGES[$key]}")
    done

    OS_KEY=$(whiptail --title "Select OS" --menu "Choose operating system:" 25 80 15 \
        "${menu_items[@]}" 3>&1 1>&2 2>&3)

    [ -z "$OS_KEY" ] && return 1
    return 0
}

interactive_create_template() {
    clear
    info "Creating VM Template - Interactive Mode"
    echo ""

    # Select OS
    interactive_select_os || {
        warn "No OS selected"
        interactive_main_menu
        return
    }

    # VM ID
    local input_vmid
    input_vmid=$(whiptail --title "VM ID" --inputbox "Enter VM ID (leave empty for auto):" 10 60 "" 3>&1 1>&2 2>&3)
    [ -n "$input_vmid" ] && VMID="$input_vmid"

    # CPU Cores
    CORES=$(whiptail --title "CPU Cores" --inputbox "Number of CPU cores:" 10 60 "$CORES" 3>&1 1>&2 2>&3) || CORES=2

    # Memory
    MEMORY=$(whiptail --title "Memory" --inputbox "Memory in MB:" 10 60 "$MEMORY" 3>&1 1>&2 2>&3) || MEMORY=2048

    # Disk Size
    DISK_SIZE=$(whiptail --title "Disk Size" --inputbox "Disk size in GB:" 10 60 "$DISK_SIZE" 3>&1 1>&2 2>&3) || DISK_SIZE=30

    # Storage
    local storage_list=()
    while IFS= read -r stor; do
        storage_list+=("$stor" "")
    done < <(list_storage_pools)

    if [ ${#storage_list[@]} -gt 0 ]; then
        STORAGE=$(whiptail --title "Storage Pool" --menu "Select storage:" 20 70 10 \
            "${storage_list[@]}" 3>&1 1>&2 2>&3) || STORAGE=""
    fi

    # Cloud-Init
    if whiptail --title "Cloud-Init" --yesno "Enable Cloud-Init?" 10 60; then
        ENABLE_CLOUDINIT="yes"

        # Optional credentials
        if whiptail --title "Cloud-Init Credentials" --yesno "Configure Cloud-Init credentials now?" 10 60; then
            CI_USER=$(whiptail --title "Cloud-Init User" --inputbox "Username:" 10 60 "root" 3>&1 1>&2 2>&3) || CI_USER=""
            CI_PASSWORD=$(whiptail --title "Cloud-Init Password" --passwordbox "Password (optional):" 10 60 3>&1 1>&2 2>&3) || CI_PASSWORD=""
            CI_SSH_KEY=$(whiptail --title "SSH Public Key" --inputbox "SSH Public Key (optional):" 10 60 "" 3>&1 1>&2 2>&3) || CI_SSH_KEY=""
        fi
    else
        ENABLE_CLOUDINIT="no"
    fi

    # Confirm
    if whiptail --title "Confirm" --yesno "Create template with these settings?\n\nOS: $OS_KEY\nCores: $CORES\nMemory: ${MEMORY}MB\nDisk: ${DISK_SIZE}GB\nCloud-Init: $ENABLE_CLOUDINIT" 15 60; then
        clear
        create_template
        echo ""
        read -p "Press Enter to continue..."
    fi

    interactive_main_menu
}

interactive_deploy_vm() {
    clear
    info "Deploy VM from Template - Interactive Mode"
    echo ""

    # Select OS (template must exist)
    interactive_select_os || {
        warn "No OS selected"
        interactive_main_menu
        return
    }

    # Check if template exists
    local template_name="${TEMPLATE_PREFIX}-${OS_KEY}"
    local template_id=$(find_template_by_name "$template_name")

    if [ -z "$template_id" ]; then
        whiptail --title "Error" --msgbox "Template '$template_name' not found!\n\nCreate it first." 10 60
        interactive_main_menu
        return
    fi

    # Hostname
    HOSTNAME=$(whiptail --title "Hostname" --inputbox "Enter hostname:" 10 60 "${OS_KEY}-vm" 3>&1 1>&2 2>&3)
    [ -z "$HOSTNAME" ] && HOSTNAME="${OS_KEY}-vm"

    # VM ID
    local input_vmid
    input_vmid=$(whiptail --title "VM ID" --inputbox "Enter VM ID (leave empty for auto):" 10 60 "" 3>&1 1>&2 2>&3)
    [ -n "$input_vmid" ] && VMID="$input_vmid"

    # Disk Size
    local template_size=$(qm config "$template_id" | grep "scsi0:" | grep -oP '\d+G' | head -1 | sed 's/G//')
    DISK_SIZE=$(whiptail --title "Disk Size" --inputbox "Disk size in GB:" 10 60 "${template_size:-30}" 3>&1 1>&2 2>&3) || DISK_SIZE=30

    # Post-Install
    local post_choice
    post_choice=$(whiptail --title "Post-Install" --menu "Install additional software?" 20 70 10 \
        "none" "No additional software" \
        "docker" "Install Docker CE" \
        "podman" "Install Podman" \
        "portainer" "Install Docker + Portainer" \
        3>&1 1>&2 2>&3)

    POST_INSTALL="${post_choice:-none}"

    # Start VM
    if whiptail --title "Start VM" --yesno "Start VM after deployment?" 10 60; then
        START_VM="yes"
    else
        START_VM="no"
    fi

    # Confirm
    local confirm_msg="Deploy VM with these settings?\n\nTemplate: $template_name\nHostname: $HOSTNAME\nDisk: ${DISK_SIZE}GB"
    [ "$POST_INSTALL" != "none" ] && confirm_msg+="\nPost-Install: $POST_INSTALL"
    [ "$START_VM" = "yes" ] && confirm_msg+="\nAuto-start: Yes"

    if whiptail --title "Confirm" --yesno "$confirm_msg" 18 60; then
        clear
        deploy_from_template
        echo ""
        read -p "Press Enter to continue..."
    fi

    interactive_main_menu
}

wait_for_vm_ready() {
    local vmid=$1
    local timeout=${2:-120}
    local elapsed=0

    info "Waiting for VM $vmid to be ready..."

    while [ $elapsed -lt $timeout ]; do
        if qm guest exec $vmid -- test -f /usr/bin/systemctl &>/dev/null; then
            ok "VM is ready"
            return 0
        fi
        sleep 5
        elapsed=$((elapsed + 5))
    done

    warn "VM readiness timeout after ${timeout}s"
    return 1
}

run_post_install() {
    local vmid=$1
    local script_type=$2

    [ -z "$script_type" ] || [ "$script_type" = "none" ] && return 0

    info "Running post-install: $script_type"

    # Wait for VM to be ready
    wait_for_vm_ready "$vmid" 180 || {
        warn "VM not ready, skipping post-install"
        return 1
    }

    case "$script_type" in
    docker)
        info "Installing Docker..."
        qm guest exec "$vmid" -- bash -c '
        curl -fsSL https://get.docker.com | sh && \
        systemctl enable --now docker && \
        usermod -aG docker $(whoami) 2>/dev/null || true
      ' || {
            warn "Docker installation failed"
            return 1
        }
        ok "Docker installed successfully"
        ;;

    podman)
        info "Installing Podman..."
        qm guest exec "$vmid" -- bash -c '
        if command -v apt-get &>/dev/null; then
          apt-get update && apt-get install -y podman
        elif command -v dnf &>/dev/null; then
          dnf install -y podman
        elif command -v yum &>/dev/null; then
          yum install -y podman
        else
          echo "Package manager not supported"
          exit 1
        fi && \
        systemctl enable --now podman || true
      ' || {
            warn "Podman installation failed"
            return 1
        }
        ok "Podman installed successfully"
        ;;

    portainer)
        info "Installing Portainer (requires Docker)..."
        # First install Docker
        run_post_install "$vmid" "docker" || return 1

        info "Deploying Portainer container..."
        qm guest exec "$vmid" -- bash -c '
        docker volume create portainer_data && \
        docker run -d \
          -p 8000:8000 \
          -p 9443:9443 \
          --name portainer \
          --restart=always \
          -v /var/run/docker.sock:/var/run/docker.sock \
          -v portainer_data:/data \
          portainer/portainer-ce:latest
      ' || {
            warn "Portainer deployment failed"
            return 1
        }
        ok "Portainer deployed successfully"
        info "Access Portainer at: https://<vm-ip>:9443"
        ;;

    *)
        warn "Unknown post-install script: $script_type"
        return 1
        ;;
    esac

    return 0
}

# ============================================================================
# TEMPLATE OPERATIONS
# ============================================================================

list_templates() {
    echo -e "\n${BOLD}${CYAN}Available VM Templates:${NC}\n"
    echo "┌──────┬────────────────────────────┬─────────┬────────┬──────────┬────────────┐"
    echo "│ VMID │ Name                       │ Cores   │ Memory │ Disk     │ Cloud-Init │"
    echo "├──────┼────────────────────────────┼─────────┼────────┼──────────┼────────────┤"

    local found=0
    while IFS= read -r line; do
        local vmid=$(echo "$line" | awk '{print $1}')
        local name=$(echo "$line" | awk '{print $2}')

        if is_template "$vmid"; then
            local config=$(qm config "$vmid" 2>/dev/null)
            local cores=$(echo "$config" | grep "^cores:" | awk '{print $2}')
            local memory=$(echo "$config" | grep "^memory:" | awk '{print $2}')
            local disk=$(echo "$config" | grep "scsi0:" | grep -oP '\d+G' | head -1)
            local has_ci=$(echo "$config" | grep -q "ide2:.*cloudinit" && echo "Yes" || echo "No")

            printf "│ %-4s │ %-26s │ %-7s │ %-6s │ %-8s │ %-10s │\n" \
                "$vmid" "$name" "${cores:-N/A}" "${memory:-N/A}MB" "${disk:-N/A}" "$has_ci"
            found=$((found + 1))
        fi
    done < <(qm list 2>/dev/null | tail -n +2)

    echo "└──────┴────────────────────────────┴─────────┴────────┴──────────┴────────────┘"

    if [ $found -eq 0 ]; then
        echo -e "\n${YELLOW}No templates found.${NC}"
        echo -e "Create one with: $0 create --os <os-key>\n"
    else
        echo -e "\n${GREEN}Total: $found template(s)${NC}\n"
    fi
}

list_os_options() {
    echo -e "\n${BOLD}${CYAN}Available OS Images:${NC}\n"
    local i=1
    for key in $(echo "${!OS_IMAGES[@]}" | tr ' ' '\n' | sort); do
        printf "%2d) %-20s %s\n" $i "$key" "${OS_IMAGES[$key]}"
        i=$((i + 1))
    done
    echo ""
}

create_template() {
    # Validate OS
    [ -z "$OS_KEY" ] && error "OS not specified. Use --os <os-key>"
    [ -z "${OS_IMAGES[$OS_KEY]:-}" ] && error "Unknown OS: $OS_KEY (use --list-os)"

    local image_url="${OS_IMAGES[$OS_KEY]}"
    local template_name="${TEMPLATE_PREFIX}-${OS_KEY}"

    # Check if template already exists
    local existing_id=$(find_template_by_name "$template_name")
    if [ -n "$existing_id" ]; then
        warn "Template '$template_name' already exists (ID: $existing_id)"
        read -p "Overwrite? (y/N): " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            info "Aborted"
            exit 0
        fi
        qm destroy "$existing_id" &>/dev/null || true
    fi

    # Get VM ID
    [ -z "$VMID" ] && VMID=$(get_next_vmid $TEMPLATE_ID_START)
    [ -z "$STORAGE" ] && STORAGE=$(get_default_storage)

    info "Creating template: $template_name (ID: $VMID)"
    [ "$ENABLE_CLOUDINIT" = "yes" ] && info "Cloud-Init: Enabled" || info "Cloud-Init: Disabled"

    # Download/cache image
    local cache_dir="/var/lib/vz/template/cache"
    local image_file="$cache_dir/$(basename "$image_url")"
    mkdir -p "$cache_dir"

    if [ ! -f "$image_file" ]; then
        info "Downloading image..."
        curl -fL --progress-bar -o "$image_file" "$image_url" || error "Download failed"
        ok "Image downloaded"
    else
        ok "Using cached image"
    fi

    # Create VM
    info "Creating VM shell"
    qm create "$VMID" \
        --name "$template_name" \
        --machine "$MACHINE_TYPE" \
        --bios ovmf \
        --cores "$CORES" \
        --memory "$MEMORY" \
        --net0 "virtio,bridge=$BRIDGE" \
        --scsihw virtio-scsi-single \
        --ostype l26 \
        --agent enabled=1 \
        >/dev/null || error "VM creation failed"

    ok "VM shell created"

    # Import disk
    info "Importing disk"
    local import_out
    if command -v "qm" &>/dev/null && qm disk import --help &>/dev/null 2>&1; then
        import_out=$(qm disk import "$VMID" "$image_file" "$STORAGE" --format qcow2 2>&1 || true)
    else
        import_out=$(qm importdisk "$VMID" "$image_file" "$STORAGE" 2>&1 || true)
    fi

    local disk_ref=$(echo "$import_out" | grep -oP "vm-$VMID-disk-\d+" | head -1)
    [ -z "$disk_ref" ] && disk_ref=$(pvesm list "$STORAGE" | awk -v id="$VMID" '$5 ~ ("vm-"id"-disk-") {print $5}' | sort | tail -n1)
    [ -z "$disk_ref" ] && error "Disk import failed"

    ok "Disk imported: $disk_ref"

    # Configure disks
    info "Configuring disks"
    if [ "$ENABLE_CLOUDINIT" = "yes" ]; then
        qm set "$VMID" \
            --scsi0 "${STORAGE}:${disk_ref},discard=on" \
            --boot order=scsi0 \
            --ide2 "${STORAGE}:cloudinit" \
            >/dev/null || error "Disk configuration failed"
    else
        qm set "$VMID" \
            --scsi0 "${STORAGE}:${disk_ref},discard=on" \
            --boot order=scsi0 \
            >/dev/null || error "Disk configuration failed"
    fi

    # Resize disk
    qm resize "$VMID" scsi0 "${DISK_SIZE}G" >/dev/null 2>&1 || warn "Disk resize failed"
    ok "Disk configured (${DISK_SIZE}G)"

    # Cloud-Init configuration
    if [ "$ENABLE_CLOUDINIT" = "yes" ]; then
        if [ -n "$CI_USER" ] && [ -n "$CI_SSH_KEY" ]; then
            info "Configuring Cloud-Init credentials"
            qm set "$VMID" --ciuser "$CI_USER" >/dev/null
            qm set "$VMID" --sshkeys <(echo "$CI_SSH_KEY") >/dev/null
            [ -n "$CI_PASSWORD" ] && qm set "$VMID" --cipassword "$CI_PASSWORD" >/dev/null
            ok "Cloud-Init configured"
        else
            info "Cloud-Init drive created (configure after deployment)"
        fi
    fi

    # Convert to template
    info "Converting to template"
    qm template "$VMID" >/dev/null || error "Template conversion failed"

    ok "Template created successfully!"
    echo ""
    echo "  Template ID:   $VMID"
    echo "  Template Name: $template_name"
    echo "  OS:            $OS_KEY"
    echo "  Cloud-Init:    $ENABLE_CLOUDINIT"
    echo ""
}

deploy_from_template() {
    local template_name="${TEMPLATE_PREFIX}-${OS_KEY}"
    local template_id=$(find_template_by_name "$template_name")

    [ -z "$template_id" ] && error "Template '$template_name' not found"

    if ! is_template "$template_id"; then
        error "VM $template_id is not a template"
    fi

    [ -z "$VMID" ] && VMID=$(get_next_vmid)
    [ -z "$HOSTNAME" ] && HOSTNAME="${OS_KEY}-vm-${VMID}"

    info "Cloning template $template_id -> VM $VMID ($HOSTNAME)"

    # Full clone
    qm clone "$template_id" "$VMID" --name "$HOSTNAME" --full 1 >/dev/null || error "Clone failed"
    ok "VM cloned"

    # Reconfigure network (remove MAC to get new one)
    qm set "$VMID" --delete net0 >/dev/null
    qm set "$VMID" --net0 "virtio,bridge=$BRIDGE" >/dev/null
    ok "Network reconfigured"

    # Resize if different from template
    local template_size=$(qm config "$template_id" | grep "scsi0:" | grep -oP '\d+G' | head -1)
    template_size=${template_size%G}
    if [ "$DISK_SIZE" -gt "$template_size" ]; then
        local diff=$((DISK_SIZE - template_size))
        info "Expanding disk by ${diff}G"
        qm resize "$VMID" scsi0 "+${diff}G" >/dev/null 2>&1 || warn "Resize failed"
    fi

    # Start VM if requested or if post-install is needed
    local need_start="no"
    [ "$START_VM" = "yes" ] && need_start="yes"
    [ -n "$POST_INSTALL" ] && [ "$POST_INSTALL" != "none" ] && need_start="yes"

    if [ "$need_start" = "yes" ]; then
        info "Starting VM"
        qm start "$VMID" || { warn "Start failed"; }
        ok "VM started"
    fi

    # Execute post-install scripts if specified
    if [ -n "$POST_INSTALL" ] && [ "$POST_INSTALL" != "none" ]; then
        if run_post_install "$VMID" "$POST_INSTALL"; then
            ok "Post-install completed: $POST_INSTALL"
        else
            warn "Post-install had issues, but VM is deployed"
        fi
    fi

    ok "VM deployed successfully!"
    echo ""
    echo "  VM ID:      $VMID"
    echo "  Hostname:   $HOSTNAME"
    echo "  Template:   $template_name (ID: $template_id)"
    [ -n "$POST_INSTALL" ] && [ "$POST_INSTALL" != "none" ] && echo "  Post-Install: $POST_INSTALL"
    echo ""
}

# ============================================================================
# USAGE
# ============================================================================

usage() {
    cat <<EOF
${BOLD}Usage:${NC} $0 [COMMAND] [OPTIONS]

${BOLD}Interactive Mode:${NC}
    $0                  Start interactive menu (whiptail)
    $0 --interactive    Start interactive menu
    $0 -i               Start interactive menu

${BOLD}CLI Commands:${NC}
    create              Create a new VM template
    deploy              Deploy VM from template
    list                List all templates
    list-os             Show available OS images

${BOLD}Options:${NC}
    --os KEY            OS from catalog (e.g. debian-12, ubuntu-24.04)
                        Use -nocloud suffix for images without cloud-init
    --vmid ID           VM/Template ID (auto-assigned if not specified)
    --hostname NAME     Hostname for deployed VM
    --cores NUM         CPU cores (default: $CORES)
    --memory MB         RAM in MB (default: $MEMORY)
    --disk GB           Disk size in GB (default: $DISK_SIZE)
    --storage NAME      Storage pool
    --bridge NAME       Network bridge (default: $BRIDGE)
    --start             Start VM after deployment
    --no-cloudinit      Disable cloud-init drive (default: enabled)

    ${BOLD}Cloud-Init:${NC}
    --ci-user USER      Cloud-Init username
    --ci-password PASS  Cloud-Init password
    --ci-ssh-key KEY    SSH public key

    ${BOLD}Post-Install:${NC}
    --post-install PKG  Install software after first boot
                        Options: docker, podman, portainer
                        Note: Requires cloud-init + SSH access

${BOLD}Examples:${NC}
    ${BOLD}# Create templates${NC}
    $0 create --os debian-12
    $0 create --os debian-12-nocloud --no-cloudinit
    $0 create --os ubuntu-24.04 --cores 4 --memory 4096
    $0 create --os debian-12 --ci-user admin --ci-ssh-key "ssh-rsa AAA..."

    ${BOLD}# Deploy VMs${NC}
    $0 deploy --os debian-12 --hostname webserver --start
    $0 deploy --os ubuntu-24.04 --hostname docker-host --post-install docker
    $0 deploy --os debian-12 --hostname portainer --post-install portainer --start
    $0 deploy --os rocky-9 --hostname podman-host --post-install podman --disk 100

    ${BOLD}# List resources${NC}
    $0 list
    $0 list-os

${BOLD}Post-Install Details:${NC}
    docker      - Installs Docker CE via get.docker.com
    podman      - Installs Podman via system package manager
    portainer   - Installs Docker + Portainer CE container
                  Access at https://<vm-ip>:9443

${BOLD}NoCloud Images:${NC}
    NoCloud variants (e.g., debian-12-nocloud) are minimal images
    without cloud-init pre-installed. Use --no-cloudinit with these.

EOF
    exit 0
}

# ============================================================================
# ARGUMENT PARSING
# ============================================================================

# Check if run without arguments or with --interactive
if [ $# -eq 0 ] || [ "${1:-}" = "--interactive" ] || [ "${1:-}" = "-i" ]; then
    command -v whiptail >/dev/null 2>&1 || error "whiptail not found. Install it or use CLI mode."
    interactive_main_menu
    exit 0
fi

MODE="$1"
shift

while [ $# -gt 0 ]; do
    case "$1" in
    --os)
        OS_KEY="$2"
        shift 2
        ;;
    --vmid)
        VMID="$2"
        shift 2
        ;;
    --hostname)
        HOSTNAME="$2"
        shift 2
        ;;
    --cores)
        CORES="$2"
        shift 2
        ;;
    --memory)
        MEMORY="$2"
        shift 2
        ;;
    --disk)
        DISK_SIZE="$2"
        shift 2
        ;;
    --storage)
        STORAGE="$2"
        shift 2
        ;;
    --bridge)
        BRIDGE="$2"
        shift 2
        ;;
    --start)
        START_VM="yes"
        shift
        ;;
    --no-cloudinit)
        ENABLE_CLOUDINIT="no"
        shift
        ;;
    --ci-user)
        CI_USER="$2"
        shift 2
        ;;
    --ci-password)
        CI_PASSWORD="$2"
        shift 2
        ;;
    --ci-ssh-key)
        CI_SSH_KEY="$2"
        shift 2
        ;;
    --post-install)
        POST_INSTALL="$2"
        shift 2
        ;;
    -h | --help) usage ;;
    *) error "Unknown option: $1 (use --help)" ;;
    esac
done

# ============================================================================
# CHECKS
# ============================================================================

[ "$(id -u)" -ne 0 ] && error "Root privileges required"
command -v qm >/dev/null 2>&1 || error "qm not found - Is Proxmox VE installed?"
command -v pvesm >/dev/null 2>&1 || error "pvesm not found"

# ============================================================================
# MAIN
# ============================================================================

trap cleanup_vm EXIT

case "$MODE" in
create)
    create_template
    ;;
deploy)
    deploy_from_template
    ;;
list)
    list_templates
    ;;
list-os)
    list_os_options
    ;;
*)
    error "Unknown command: $MODE (use --help)"
    ;;
esac
