#!/usr/bin/env bash
# delete-project.sh — Elimina una cuenta cPanel y sus registros Airtable
# Uso: ./scripts/delete-project.sh <cpanel_user> [--dry-run] [--keep-airtable] [--yes] [--skip-backup]
#
# Antes de borrar: genera un backup completo con pkgacct y lo sube a Backblaze
# usando el destino ya configurado en WHM Backup Restoration.
#
# VPS1 = local (el script corre ahí), VPS2 = SSH puerto 5633 (igual que process-airtable-dual.sh)

set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"

########################################
# CONFIGURACIÓN DUAL VPS
# (igual que process-airtable-dual.sh)
########################################

VPS1_IP="72.61.45.136"
VPS2_IP="179.43.124.219"
VPS2_PORT="5633"
VPS1_NAME="VPS Hostinger 1"
VPS2_NAME="VPS Donweb 1"

########################################
# FLAGS
########################################

DRY_RUN=false
KEEP_AIRTABLE=false
AUTO_CONFIRM=false
SKIP_BACKUP=false
CPANEL_USER=""

# Directorio temporal donde pkgacct genera el .tar.gz antes de subirlo a Backblaze.
# Necesita espacio equivalente al tamaño de la cuenta. Debe existir en cada VPS.
BACKUP_STAGING_DIR="${BACKUP_STAGING_DIR:-/backup/pre-delete}"

usage() {
  cat <<'EOF'
Uso:
  ./scripts/delete-project.sh <cpanel_user> [--dry-run] [--keep-airtable] [--yes] [--skip-backup]

Opciones:
  --dry-run        Muestra qué se borraría sin ejecutar cambios.
  --keep-airtable  Borra solo la cuenta cPanel, mantiene Airtable.
  --yes            No pide confirmación interactiva.
  --skip-backup    Omite el backup previo a Backblaze (no recomendado).
  -h, --help       Muestra esta ayuda.

Variables de entorno opcionales:
  BACKUP_STAGING_DIR   Directorio temporal para pkgacct en cada VPS (default: /backup/pre-delete)
EOF
}

while (($#)); do
  case "$1" in
    --dry-run)       DRY_RUN=true;        shift ;;
    --keep-airtable) KEEP_AIRTABLE=true;  shift ;;
    --yes)           AUTO_CONFIRM=true;   shift ;;
    --skip-backup)   SKIP_BACKUP=true;    shift ;;
    -h|--help)       usage; exit 0 ;;
    -*)
      echo "Opción no reconocida: $1" >&2
      usage; exit 1
      ;;
    *)
      if [[ -z "$CPANEL_USER" ]]; then
        CPANEL_USER="$1"
      else
        echo "Parámetro inesperado: $1" >&2
        usage; exit 1
      fi
      shift
      ;;
  esac
done

if [[ -z "$CPANEL_USER" ]]; then
  echo "Debes indicar el usuario cPanel." >&2
  usage; exit 1
fi

########################################
# CARGAR CONFIG
########################################

CONFIG_FILE="/root/scripts/.airtable.env"
if [[ -f "$CONFIG_FILE" ]]; then
  source "$CONFIG_FILE"
elif [[ -f "${PROJECT_ROOT}/.env" ]]; then
  source "${PROJECT_ROOT}/.env"
fi

AIRTABLE_TOKEN="${AIRTABLE_TOKEN:-}"
AIRTABLE_BASE_ID="${AIRTABLE_BASE_ID:-}"
AIRTABLE_PROJECTS_TABLE="${AIRTABLE_SUBSCRIPTIONS_TABLE:-${AIRTABLE_TABLE_ID:-}}"
AIRTABLE_SUBS_TABLE="${AIRTABLE_SUBSCRIPTIONS_TRACKING_TABLE:-tblnpr52JhFBBi2Mg}"

API_BASE=""
if [[ -n "$AIRTABLE_TOKEN" && -n "$AIRTABLE_BASE_ID" ]]; then
  API_BASE="https://api.airtable.com/v0/${AIRTABLE_BASE_ID}"
fi

########################################
# FUNCIONES REMOTE EXEC
# VPS1 = local, VPS2 = ssh -p 5633
########################################

remote_exec() {
  local server_name="$1"; shift
  local cmd="$*"

  if [[ "$server_name" == "$VPS1_NAME" ]]; then
    bash -c "$cmd"
  else
    ssh -p "${VPS2_PORT}" \
        -o StrictHostKeyChecking=no \
        -o ConnectTimeout=10 \
        root@${VPS2_IP} \
        "$cmd"
  fi
}

remote_test_file() {
  local server_name="$1"
  local filepath="$2"

  if [[ "$server_name" == "$VPS1_NAME" ]]; then
    [[ -f "$filepath" ]]
  else
    ssh -p "${VPS2_PORT}" \
        -o StrictHostKeyChecking=no \
        -o ConnectTimeout=10 \
        root@${VPS2_IP} \
        "test -f '${filepath}'"
  fi
}

########################################
# FUNCIÓN DE BACKUP PRE-DELETE
#
# Estrategia en dos pasos:
#   1. pkgacct → genera cpmove-<user>.tar.gz en BACKUP_STAGING_DIR (blocking/sincrónico)
#   2. Subir el .tar.gz a Backblaze usando el transporte disponible en la VPS:
#      a) rclone (instalado por WHM junto con Backblaze B2 nativo)
#      b) b2 CLI (alternativa)
#      c) WARN si ninguno está disponible
#   3. Limpiar el .tar.gz local del staging si la subida fue exitosa
########################################

run_pre_delete_backup() {
  local server_name="$1"
  local DUMP_TIMEOUT=1800   # 30 min máximo para mysqldump
  local POLL_INTERVAL=5

  echo "  ── Pre-delete backup (MySQL only) ─────────"

  # 1. Crear directorio de staging
  remote_exec "$server_name" "mkdir -p '${BACKUP_STAGING_DIR}'" 2>/dev/null || true

  local dump_file="${BACKUP_STAGING_DIR}/${CPANEL_USER}_mysql_$(date +%Y%m%d_%H%M%S).sql.gz"
  local REMOTE_LOG="${BACKUP_STAGING_DIR}/.mysqldump-${CPANEL_USER}.log"
  local REMOTE_PID="${BACKUP_STAGING_DIR}/.mysqldump-${CPANEL_USER}.pid"
  local REMOTE_DONE="${BACKUP_STAGING_DIR}/.mysqldump-${CPANEL_USER}.done"

  # Limpiar archivos de control previos
  remote_exec "$server_name" \
    "rm -f '${REMOTE_LOG}' '${REMOTE_PID}' '${REMOTE_DONE}'" 2>/dev/null || true

  # 2. Obtener lista de bases de datos del usuario
  #    cPanel nombra las DBs como <cpanel_user>_<dbname>
  local db_list
  db_list="$(remote_exec "$server_name" "
    mysql -N -e \"SHOW DATABASES;\" 2>/dev/null \
    | grep -E '^${CPANEL_USER}_|^${CPANEL_USER}$'
  " || echo "")"

  if [[ -z "$db_list" ]]; then
    echo "  WARN: No MySQL databases found for '${CPANEL_USER}' — skipping DB backup"
    # Sin DBs no hay nada que respaldar, continuar sin error
    return 0
  fi

  local db_count
  db_count="$(echo "$db_list" | wc -l | tr -d ' ')"
  echo "  Databases found: ${db_count}"
  echo "$db_list" | while read -r db; do echo "    - ${db}"; done

  # 3. Lanzar mysqldump en background (todas las DBs en un solo archivo comprimido)
  echo "  Running mysqldump on ${server_name}..."

  # Construir string de DBs para mysqldump
  local db_args
  db_args="$(echo "$db_list" | tr '\n' ' ')"

  remote_exec "$server_name" "bash -c '
    nohup bash -c \"mysqldump --single-transaction --routines --triggers \
      --databases ${db_args} 2>>${REMOTE_LOG} | gzip > ${dump_file}
      echo \\\$? > ${REMOTE_DONE}\" > ${REMOTE_LOG} 2>&1 &
    echo \$! > ${REMOTE_PID}
  '" 2>/dev/null || true

  sleep 2

  # 4. Polling hasta que termine o timeout
  local elapsed=0
  local spinner_chars='|/-\'
  local spinner_idx=0

  while [[ $elapsed -lt $DUMP_TIMEOUT ]]; do
    if remote_exec "$server_name" "test -f '${REMOTE_DONE}'" 2>/dev/null; then
      break
    fi
    printf "\r  %s Dumping databases..." "${spinner_chars:$((spinner_idx % ${#spinner_chars})):1}"
    spinner_idx=$((spinner_idx + 1))
    sleep $POLL_INTERVAL
    elapsed=$((elapsed + POLL_INTERVAL))
  done

  printf "\r%-60s\n" ""

  if [[ $elapsed -ge $DUMP_TIMEOUT ]]; then
    echo "  ✗ mysqldump timeout (${DUMP_TIMEOUT}s)" >&2
    local remote_pid
    remote_pid="$(remote_exec "$server_name" "cat '${REMOTE_PID}' 2>/dev/null" || echo "")"
    [[ -n "$remote_pid" ]] && remote_exec "$server_name" "kill ${remote_pid} 2>/dev/null" || true
    remote_exec "$server_name" "rm -f '${REMOTE_LOG}' '${REMOTE_PID}' '${REMOTE_DONE}' '${dump_file}'" 2>/dev/null || true
    return 1
  fi

  local dump_exit
  dump_exit="$(remote_exec "$server_name" "cat '${REMOTE_DONE}' 2>/dev/null" || echo "1")"
  dump_exit="${dump_exit//[^0-9]/}"
  dump_exit="${dump_exit:-1}"

  if [[ "$dump_exit" -ne 0 ]]; then
    echo "  ✗ mysqldump failed (exit ${dump_exit}):" >&2
    remote_exec "$server_name" "cat '${REMOTE_LOG}' 2>/dev/null" >&2 || true
    remote_exec "$server_name" "rm -f '${REMOTE_LOG}' '${REMOTE_PID}' '${REMOTE_DONE}' '${dump_file}'" 2>/dev/null || true
    return 1
  fi

  if ! remote_exec "$server_name" "test -f '${dump_file}'" 2>/dev/null; then
    echo "  ✗ mysqldump completed but file not found: ${dump_file}" >&2
    return 1
  fi

  local dump_size
  dump_size="$(remote_exec "$server_name" "du -sh '${dump_file}' 2>/dev/null | cut -f1" || echo "?")"
  echo "  ✓ mysqldump completed: $(basename "${dump_file}") (${dump_size})"

  remote_exec "$server_name" "rm -f '${REMOTE_LOG}' '${REMOTE_PID}' '${REMOTE_DONE}'" 2>/dev/null || true

  # 5. Subir a Backblaze usando WHM nativo: cpbackup_transport_file
  #    Sube a: <bucket>/<path_configurado>/manual_backup/<archivo>
  #    Ej: bewpro-backup-server/backups/donweb/manual_backup/<user>_mysql_<fecha>.sql.gz
  echo "  Uploading to Backblaze via WHM transport..."

  local transport_id transport_name transport_path_remote
  local dest_info
  dest_info="$(remote_exec "$server_name" "
    whmapi1 backup_destination_list --output=json 2>/dev/null \
    | python3 -c \"
import json,sys
data=json.load(sys.stdin)
for d in data.get('data',{}).get('destination_list',[]):
    if str(d.get('disabled','1')) == '0':
        print(d.get('id','') + '|' + d.get('name','') + '|' + d.get('path',''))
        break
\" 2>/dev/null
  " || echo "")"

  transport_id="${dest_info%%|*}"
  transport_name="$(echo "$dest_info" | cut -d'|' -f2)"
  transport_path_remote="$(echo "$dest_info" | cut -d'|' -f3)"

  if [[ -z "$transport_id" ]]; then
    echo "  ✗ No active WHM backup destination found" >&2
    echo "  WARN: Dump kept at ${dump_file} — upload manually" >&2
    return 1
  fi

  echo "  Destination  : ${transport_name} (ID: ${transport_id})"
  echo "  Remote path  : ${transport_path_remote}/manual_backup/$(basename "${dump_file}")"

  local transport_output transport_exit
  transport_output="$(remote_exec "$server_name" "
    /scripts/cpbackup_transport_file \
      --transport '${transport_id}' \
      --upload '${dump_file}' 2>&1
  ")"
  transport_exit=$?

  # cpbackup_transport_file puede retornar exit 0 con errores internos — verificar output
  local upload_failed=false
  if [[ $transport_exit -ne 0 ]]; then
    upload_failed=true
  elif echo "$transport_output" | grep -qi "upload attempt failed\|storage_cap_exceeded\|403 Forbidden\|Exception::HTTP"; then
    upload_failed=true
  fi

  if [[ "$upload_failed" == "false" ]]; then
    echo "  ✓ Uploaded to Backblaze: ${transport_path_remote}/manual_backup/$(basename "${dump_file}")"
    remote_exec "$server_name" "rm -f '${dump_file}'" 2>/dev/null || true
    echo "  ✓ Local copy removed"
    return 0
  else
    echo "  ✗ Upload failed (exit ${transport_exit}):" >&2
    echo "$transport_output" | grep -i "warn\|error\|failed\|storage_cap\|403" | head -5 >&2
    echo "  WARN: Dump kept at ${dump_file} — fix Backblaze cap and upload manually" >&2
    echo "  CMD:  /scripts/cpbackup_transport_file --transport ${transport_id} --upload ${dump_file}" >&2
    return 1
  fi
}

########################################
# FUNCIONES AIRTABLE
########################################

urlencode() {
  python3 - "$1" <<'PYEOF'
import sys, urllib.parse
print(urllib.parse.quote(sys.argv[1], safe=""))
PYEOF
}

extract_project_info() {
  python3 - "$1" <<'PYEOF'
import json, sys

raw = sys.argv[1]
try:
    data = json.loads(raw)
except Exception:
    print("||")
    raise SystemExit(0)

records = data.get("records", [])
if not records:
    print("||")
    raise SystemExit(0)

record = records[0]
rid    = record.get("id", "")
fields = record.get("fields", {})
name   = fields.get("Name", "")
server = fields.get("Server", "").strip()
print(f"{rid}|{name}|{server}")
PYEOF
}

extract_subscription_ids() {
  python3 - "$1" <<'PYEOF'
import json, sys

raw = sys.argv[1]
try:
    data = json.loads(raw)
except Exception:
    raise SystemExit(0)

for rec in data.get("records", []):
    rid = rec.get("id")
    if rid:
        print(rid)
PYEOF
}

airtable_get() {
  local table="$1" formula="$2" max_records="${3:-}"
  local encoded_formula url
  encoded_formula="$(urlencode "$formula")"
  url="${API_BASE}/${table}?filterByFormula=${encoded_formula}"
  [[ -n "$max_records" ]] && url="${url}&maxRecords=${max_records}"
  curl -sS -H "Authorization: Bearer ${AIRTABLE_TOKEN}" "$url"
}

airtable_delete_record() {
  local table="$1" record_id="$2"
  curl -sS -X DELETE \
    -H "Authorization: Bearer ${AIRTABLE_TOKEN}" \
    "${API_BASE}/${table}/${record_id}" > /dev/null
}

########################################
# ENCABEZADO
########################################

echo ""
echo "========================================"
echo "  DELETE PROJECT: ${CPANEL_USER}"
echo "========================================"
echo ""

########################################
# BUSCAR PROYECTO EN AIRTABLE
########################################

PROJECT_ID=""
PROJECT_NAME=""
SERVER_NAME=""
SUB_IDS=()

if [[ -n "$API_BASE" && -n "$AIRTABLE_PROJECTS_TABLE" ]]; then
  PROJECT_JSON="$(airtable_get "$AIRTABLE_PROJECTS_TABLE" "{Cpanel_User}=\"${CPANEL_USER}\"" "1")"
  PROJECT_INFO="$(extract_project_info "$PROJECT_JSON")"

  PROJECT_ID="${PROJECT_INFO%%|*}"
  _rest="${PROJECT_INFO#*|}"
  PROJECT_NAME="${_rest%%|*}"
  SERVER_NAME="${_rest#*|}"

  if [[ -n "$PROJECT_ID" ]]; then
    echo "  Airtable Project : ${PROJECT_NAME:-?} (${PROJECT_ID})"
    echo "  Server           : ${SERVER_NAME:-NOT SET}"

    SUBS_JSON="$(airtable_get "$AIRTABLE_SUBS_TABLE" "SEARCH(\"${PROJECT_NAME}\",{Project})")"
    while IFS= read -r rid; do
      [[ -n "$rid" ]] && SUB_IDS+=("$rid")
    done < <(extract_subscription_ids "$SUBS_JSON")
    echo "  Subscriptions    : ${#SUB_IDS[@]} record(s)"
  else
    echo "  Airtable Project : NOT FOUND (Cpanel_User=${CPANEL_USER})"
  fi
else
  echo "  Airtable         : NOT CONFIGURED"
fi

########################################
# VERIFICAR CUENTA CPANEL — con fallback a la otra VPS
########################################

USER_EXISTS=false
ACTUAL_SERVER=""

find_user_on_server() {
  local sname="$1"
  if remote_test_file "$sname" "/var/cpanel/users/${CPANEL_USER}" 2>/dev/null; then
    return 0
  fi
  if remote_exec "$sname" "test -d '/home/${CPANEL_USER}'" 2>/dev/null; then
    return 0
  fi
  return 1
}

if [[ "$SERVER_NAME" == "$VPS2_NAME" ]]; then
  SEARCH_ORDER=("$VPS2_NAME" "$VPS1_NAME")
else
  SEARCH_ORDER=("$VPS1_NAME" "$VPS2_NAME")
fi

for vps in "${SEARCH_ORDER[@]}"; do
  if find_user_on_server "$vps"; then
    USER_EXISTS=true
    ACTUAL_SERVER="$vps"
    echo "  cPanel account   : EXISTS on ${vps}"
    if [[ -n "$SERVER_NAME" && "$vps" != "$SERVER_NAME" ]]; then
      echo "  WARN: Airtable dice '${SERVER_NAME}' pero la cuenta está en '${vps}'"
    fi
    break
  else
    echo "  cPanel account   : not found on ${vps}"
  fi
done

if [[ "$USER_EXISTS" == "false" ]]; then
  echo "  cPanel account   : NOT FOUND on any VPS"
fi

[[ "$SKIP_BACKUP" == "true" ]] && echo "  Backup           : SKIPPED (--skip-backup)"

echo ""

########################################
# DRY RUN
########################################

if [[ "$DRY_RUN" == "true" ]]; then
  echo "DRY RUN — nothing deleted."
  if [[ "$USER_EXISTS" == "true" ]]; then
    if [[ "$SKIP_BACKUP" == "false" ]]; then
      echo "  Would backup: pkgacct '${CPANEL_USER}' on ${ACTUAL_SERVER} → Backblaze"
    fi
    echo "  Would delete: cPanel account '${CPANEL_USER}' on ${ACTUAL_SERVER}"
  else
    echo "  cPanel account not found — would skip backup and cPanel deletion"
  fi
  [[ -n "$PROJECT_ID" ]] && \
    echo "  Would delete: Airtable Project ${PROJECT_ID}"
  for sub_id in "${SUB_IDS[@]}"; do
    echo "  Would delete: Airtable Subscription ${sub_id}"
  done
  exit 0
fi

########################################
# CONFIRMACIÓN
########################################

if [[ "$AUTO_CONFIRM" != "true" ]]; then
  CONFIRM_MSG="Delete '${CPANEL_USER}'"
  if [[ "$USER_EXISTS" == "true" ]]; then
    [[ "$SKIP_BACKUP" == "false" ]] && CONFIRM_MSG+=" (backup → Backblaze first)"
    CONFIRM_MSG+=" on ${ACTUAL_SERVER}"
  fi
  [[ -n "$PROJECT_ID" ]] && CONFIRM_MSG+=" + Airtable records"
  read -r -p "${CONFIRM_MSG}? [y/N]: " reply
  if [[ ! "$reply" =~ ^[Yy]$ ]]; then
    echo "Cancelled."
    exit 0
  fi
fi

########################################
# BACKUP PRE-DELETE → BACKBLAZE
########################################

BACKUP_OK=false

if [[ "$USER_EXISTS" == "true" && "$SKIP_BACKUP" == "false" ]]; then
  if run_pre_delete_backup "$ACTUAL_SERVER"; then
    BACKUP_OK=true
  else
    echo ""
    echo "  ✗ Backup falló. El proyecto NO será eliminado por seguridad." >&2
    echo "    Para forzar el borrado sin backup usa: --skip-backup" >&2
    exit 1
  fi
elif [[ "$USER_EXISTS" == "false" ]]; then
  # Sin cuenta cPanel no hay nada que respaldar, seguir adelante
  BACKUP_OK=true
else
  # --skip-backup explícito
  BACKUP_OK=true
fi

########################################
# ELIMINAR CUENTA CPANEL
########################################

if [[ "$USER_EXISTS" == "true" ]]; then
  echo "  Deleting cPanel account on ${ACTUAL_SERVER}..."

  REMOVE_OUTPUT="$(remote_exec "$ACTUAL_SERVER" \
    "/scripts/removeacct ${CPANEL_USER} --force" 2>&1)"
  REMOVE_EXIT=$?

  if [[ $REMOVE_EXIT -eq 0 ]]; then
    remote_exec "$ACTUAL_SERVER" \
      "[ -d /home/${CPANEL_USER} ] && rm -rf /home/${CPANEL_USER} || true" 2>/dev/null
    echo "  ✓ cPanel account deleted on ${ACTUAL_SERVER}"
  else
    echo "  ✗ removeacct failed: ${REMOVE_OUTPUT}" >&2
  fi
else
  echo "  cPanel: no account found — skipping removeacct"
fi

########################################
# ELIMINAR REGISTROS AIRTABLE
########################################

if [[ "$KEEP_AIRTABLE" != "true" && -n "$API_BASE" ]]; then
  for sub_id in "${SUB_IDS[@]}"; do
    airtable_delete_record "$AIRTABLE_SUBS_TABLE" "$sub_id"
    echo "  ✓ Subscription deleted: ${sub_id}"
  done

  if [[ -n "$PROJECT_ID" ]]; then
    airtable_delete_record "$AIRTABLE_PROJECTS_TABLE" "$PROJECT_ID"
    echo "  ✓ Project deleted: ${PROJECT_ID}"
  fi
fi

echo ""
echo "  Project '${CPANEL_USER}' deleted completely."
