#!/usr/bin/env bash

# Copyright (c) 2021-2026 community-scripts ORG
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.proxmox.com/

function header_info {
  clear
  cat <<"EOF"
   ____  ________   ______            __        _
  / __ \/ ____/ /  / ____/___  ____  / /_____ _(_)___  ___  _____
 / / / / /   / /  / /   / __ \/ __ \/ __/ __ `/ / __ \/ _ \/ ___/
/ /_/ / /___/ /  / /___/ /_/ / / / / /_/ /_/ / / / / /  __/ /
\____/\____/_/   \____/\____/_/ /_/\__/\__,_/_/_/ /_/\___/_/

EOF
}

YW=$(echo "\033[33m")
GN=$(echo "\033[1;92m")
RD=$(echo "\033[01;31m")
BL=$(echo "\033[36m")
CL=$(echo "\033[m")
CM="${GN}✔️${CL}"
CROSS="${RD}✖️${CL}"
INFO="${BL}ℹ️${CL}"

APP="OCI-Container"

header_info

function msg_info() {
  local msg="$1"
  echo -e "${INFO} ${YW}${msg}...${CL}"
}

function msg_ok() {
  local msg="$1"
  echo -e "${CM} ${GN}${msg}${CL}"
}

function msg_error() {
  local msg="$1"
  echo -e "${CROSS} ${RD}${msg}${CL}"
}

# Check Proxmox version
if ! command -v pveversion &>/dev/null; then
  msg_error "This script must be run on Proxmox VE"
  exit 1
fi

PVE_VER=$(pveversion | grep -oP 'pve-manager/\K[0-9.]+' | cut -d. -f1,2)
MAJOR=$(echo "$PVE_VER" | cut -d. -f1)
MINOR=$(echo "$PVE_VER" | cut -d. -f2)

if [[ "$MAJOR" -lt 9 ]] || { [[ "$MAJOR" -eq 9 ]] && [[ "$MINOR" -lt 1 ]]; }; then
  msg_error "Proxmox VE 9.1+ required (current: $PVE_VER)"
  exit 1
fi

msg_ok "Proxmox VE $PVE_VER detected"

# Parse OCI image
parse_image() {
  local input="$1"
  if [[ "$input" =~ ^([^/]+\.[^/]+)/ ]]; then
    echo "$input"
  elif [[ "$input" =~ / ]]; then
    echo "docker.io/$input"
  else
    echo "docker.io/library/$input"
  fi
}

# Interactive image selection
if [[ -z "${OCI_IMAGE:-}" ]]; then
  echo ""
  echo -e "${YW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
  echo -e "${BL}Select OCI Image:${CL}"
  echo -e "${YW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
  echo -e "  ${BL}1)${CL} nginx:alpine          - Lightweight web server"
  echo -e "  ${BL}2)${CL} postgres:16-alpine    - PostgreSQL database"
  echo -e "  ${BL}3)${CL} redis:alpine          - Redis cache"
  echo -e "  ${BL}4)${CL} mariadb:latest        - MariaDB database"
  echo -e "  ${BL}5)${CL} ghcr.io/linkwarden/linkwarden:latest"
  echo -e "  ${BL}6)${CL} Custom image"
  echo -e "${YW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
  echo ""

  read -r -p "Select option (1-6): " IMAGE_CHOICE

  case $IMAGE_CHOICE in
  1) OCI_IMAGE="nginx:alpine" ;;
  2) OCI_IMAGE="postgres:16-alpine" ;;
  3) OCI_IMAGE="redis:alpine" ;;
  4) OCI_IMAGE="mariadb:latest" ;;
  5) OCI_IMAGE="ghcr.io/linkwarden/linkwarden:latest" ;;
  6)
    read -r -p "Enter OCI image (e.g., ghcr.io/user/repo:tag): " OCI_IMAGE
    [[ -z "$OCI_IMAGE" ]] && {
      msg_error "No image specified"
      exit 1
    }
    ;;
  *)
    msg_error "Invalid choice"
    exit 1
    ;;
  esac
fi

FULL_IMAGE=$(parse_image "$OCI_IMAGE")
msg_ok "Selected: $FULL_IMAGE"

# Derive container name
if [[ -z "${CT_NAME:-}" ]]; then
  DEFAULT_NAME=$(echo "$OCI_IMAGE" | sed 's|.*/||; s/:.*//; s/[^a-zA-Z0-9-]/-/g' | cut -c1-60)
  read -r -p "Container name [${DEFAULT_NAME}]: " CT_NAME
  CT_NAME=${CT_NAME:-$DEFAULT_NAME}
fi

# Get next VMID
if [[ -z "${VMID:-}" ]]; then
  NEXT_ID=$(pvesh get /cluster/nextid)
  read -r -p "Container ID [${NEXT_ID}]: " VMID
  VMID=${VMID:-$NEXT_ID}
fi

# Resources
if [[ -z "${CORES:-}" ]]; then
  read -r -p "CPU cores [2]: " CORES
  CORES=${CORES:-2}
fi

if [[ -z "${MEMORY:-}" ]]; then
  read -r -p "Memory in MB [2048]: " MEMORY
  MEMORY=${MEMORY:-2048}
fi

if [[ -z "${DISK:-}" ]]; then
  read -r -p "Disk size in GB [8]: " DISK
  DISK=${DISK:-8}
fi

# Storage
if [[ -z "${STORAGE:-}" ]]; then
  AVAIL_STORAGE=$(pvesm status | awk '/^local-(zfs|lvm)/ {print $1; exit}')
  [[ -z "$AVAIL_STORAGE" ]] && AVAIL_STORAGE="local"
  read -r -p "Storage [${AVAIL_STORAGE}]: " STORAGE
  STORAGE=${STORAGE:-$AVAIL_STORAGE}
fi

# Network
if [[ -z "${BRIDGE:-}" ]]; then
  read -r -p "Network bridge [vmbr0]: " BRIDGE
  BRIDGE=${BRIDGE:-vmbr0}
fi

if [[ -z "${IP_MODE:-}" ]]; then
  read -r -p "IP mode (dhcp/static) [dhcp]: " IP_MODE
  IP_MODE=${IP_MODE:-dhcp}
fi

if [[ "$IP_MODE" == "static" ]]; then
  read -r -p "Static IP (CIDR, e.g., 192.168.1.100/24): " STATIC_IP
  read -r -p "Gateway IP: " GATEWAY
fi

# Environment variables
declare -a ENV_VARS=()

case "$OCI_IMAGE" in
postgres* | postgresql*)
  echo ""
  msg_info "PostgreSQL requires environment variables"
  read -r -p "PostgreSQL password: " -s PG_PASS
  echo ""
  ENV_VARS+=("POSTGRES_PASSWORD=$PG_PASS")

  read -r -p "Create database (optional): " PG_DB
  [[ -n "$PG_DB" ]] && ENV_VARS+=("POSTGRES_DB=$PG_DB")

  read -r -p "PostgreSQL user (optional): " PG_USER
  [[ -n "$PG_USER" ]] && ENV_VARS+=("POSTGRES_USER=$PG_USER")
  ;;

mariadb* | mysql*)
  echo ""
  msg_info "MariaDB/MySQL requires environment variables"
  read -r -p "Root password: " -s MYSQL_PASS
  echo ""
  ENV_VARS+=("MYSQL_ROOT_PASSWORD=$MYSQL_PASS")

  read -r -p "Create database (optional): " MYSQL_DB
  [[ -n "$MYSQL_DB" ]] && ENV_VARS+=("MYSQL_DATABASE=$MYSQL_DB")

  read -r -p "Create user (optional): " MYSQL_USER
  if [[ -n "$MYSQL_USER" ]]; then
    ENV_VARS+=("MYSQL_USER=$MYSQL_USER")
    read -r -p "User password: " -s MYSQL_USER_PASS
    echo ""
    ENV_VARS+=("MYSQL_PASSWORD=$MYSQL_USER_PASS")
  fi
  ;;

*linkwarden*)
  echo ""
  msg_info "Linkwarden configuration"
  read -r -p "NEXTAUTH_SECRET (press Enter to generate): " NEXTAUTH_SECRET
  if [[ -z "$NEXTAUTH_SECRET" ]]; then
    NEXTAUTH_SECRET=$(openssl rand -base64 32)
  fi
  ENV_VARS+=("NEXTAUTH_SECRET=$NEXTAUTH_SECRET")

  read -r -p "NEXTAUTH_URL [http://localhost:3000]: " NEXTAUTH_URL
  NEXTAUTH_URL=${NEXTAUTH_URL:-http://localhost:3000}
  ENV_VARS+=("NEXTAUTH_URL=$NEXTAUTH_URL")

  read -r -p "DATABASE_URL (PostgreSQL connection string): " DATABASE_URL
  [[ -n "$DATABASE_URL" ]] && ENV_VARS+=("DATABASE_URL=$DATABASE_URL")
  ;;
esac

# Additional env vars
read -r -p "Add custom environment variables? (y/N): " ADD_ENV
if [[ "${ADD_ENV,,}" =~ ^(y|yes)$ ]]; then
  while true; do
    read -r -p "Enter KEY=VALUE (or press Enter to finish): " CUSTOM_ENV
    [[ -z "$CUSTOM_ENV" ]] && break
    ENV_VARS+=("$CUSTOM_ENV")
  done
fi

# Privileged mode
read -r -p "Run as privileged container? (y/N): " PRIV_MODE
if [[ "${PRIV_MODE,,}" =~ ^(y|yes)$ ]]; then
  UNPRIVILEGED="0"
else
  UNPRIVILEGED="1"
fi

# Auto-start
read -r -p "Start container after creation? (Y/n): " AUTO_START
if [[ "${AUTO_START,,}" =~ ^(n|no)$ ]]; then
  START_AFTER="no"
else
  START_AFTER="yes"
fi

# Summary
echo ""
echo -e "${YW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
echo -e "${BL}Container Configuration Summary:${CL}"
echo -e "${YW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
echo -e "  Image:      $FULL_IMAGE"
echo -e "  ID:         $VMID"
echo -e "  Name:       $CT_NAME"
echo -e "  CPUs:       $CORES"
echo -e "  Memory:     ${MEMORY}MB"
echo -e "  Disk:       ${DISK}GB"
echo -e "  Storage:    $STORAGE"
echo -e "  Network:    $BRIDGE ($IP_MODE)"
[[ ${#ENV_VARS[@]} -gt 0 ]] && echo -e "  Env vars:   ${#ENV_VARS[@]} configured"
echo -e "${YW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
echo ""

read -r -p "Proceed with creation? (Y/n): " CONFIRM
if [[ "${CONFIRM,,}" =~ ^(n|no)$ ]]; then
  msg_error "Cancelled by user"
  exit 0
fi

# Create container
msg_info "Creating container $VMID"

# Build pct create command
PCT_CMD="pct create $VMID"
PCT_CMD+=" --hostname $CT_NAME"
PCT_CMD+=" --cores $CORES"
PCT_CMD+=" --memory $MEMORY"
PCT_CMD+=" --rootfs ${STORAGE}:${DISK},oci=${FULL_IMAGE}"
PCT_CMD+=" --unprivileged $UNPRIVILEGED"

if [[ "$IP_MODE" == "static" && -n "$STATIC_IP" ]]; then
  PCT_CMD+=" --net0 name=eth0,bridge=$BRIDGE,ip=$STATIC_IP"
  [[ -n "$GATEWAY" ]] && PCT_CMD+=",gw=$GATEWAY"
else
  PCT_CMD+=" --net0 name=eth0,bridge=$BRIDGE,ip=dhcp"
fi

if eval "$PCT_CMD" 2>&1; then
  msg_ok "Container created"
else
  msg_error "Failed to create container"
  exit 1
fi

# Set environment variables
if [[ ${#ENV_VARS[@]} -gt 0 ]]; then
  msg_info "Configuring environment variables"
  for env_var in "${ENV_VARS[@]}"; do
    if pct set "$VMID" -env "$env_var" &>/dev/null; then
      :
    else
      msg_error "Failed to set: $env_var"
    fi
  done
  msg_ok "Environment variables configured (${#ENV_VARS[@]} variables)"
fi

# Start container
if [[ "$START_AFTER" == "yes" ]]; then
  msg_info "Starting container"
  if pct start "$VMID" 2>&1; then
    msg_ok "Container started"

    # Wait for network
    sleep 3
    CT_IP=$(pct exec "$VMID" -- hostname -I 2>/dev/null | awk '{print $1}' || echo "N/A")

    echo ""
    echo -e "${GN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
    echo -e "${BL}Container Information:${CL}"
    echo -e "${GN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
    echo -e "  ID:       ${GN}$VMID${CL}"
    echo -e "  Name:     ${GN}$CT_NAME${CL}"
    echo -e "  Image:    ${GN}$FULL_IMAGE${CL}"
    echo -e "  IP:       ${GN}$CT_IP${CL}"
    echo -e "  Status:   ${GN}Running${CL}"
    echo -e "${GN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
    echo ""
    echo -e "${INFO} ${YW}Access console:${CL} pct console $VMID"
    echo -e "${INFO} ${YW}View logs:${CL}      pct logs $VMID"
    echo ""
  else
    msg_error "Failed to start container"
  fi
else
  echo ""
  echo -e "${GN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
  echo -e "${BL}Container Information:${CL}"
  echo -e "${GN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
  echo -e "  ID:       ${GN}$VMID${CL}"
  echo -e "  Name:     ${GN}$CT_NAME${CL}"
  echo -e "  Image:    ${GN}$FULL_IMAGE${CL}"
  echo -e "  Status:   ${YW}Stopped${CL}"
  echo -e "${GN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${CL}"
  echo ""
  echo -e "${INFO} ${YW}Start with:${CL} pct start $VMID"
  echo ""
fi
