#!/usr/bin/env bash
# deploy.sh — Despliega la migración SF5.4 en el servidor destino.
#
# Requisitos mínimos:
#   - PHP >= 8.1 (8.2 recomendado)
#   - Composer 2.x
#   - MySQL 8.0 accesible
#   - Archivo .env.local configurado (DATABASE_URL, APP_SECRET, etc.)
#
# Uso:
#   ./scripts/deploy.sh                      # despliegue completo
#   ./scripts/deploy.sh --dry-run            # solo verificar, sin cambios
#   ./scripts/deploy.sh --no-smoke           # saltar smoke test post-deploy
#   ./scripts/deploy.sh --env prod           # APP_ENV=prod (default: prod)
#   ./scripts/deploy.sh --php /ruta/php8.2   # PHP binario específico
#
# Variables de entorno que puede sobreescribir:
#   DEPLOY_PHP=/usr/local/opt/php@8.2/bin/php
#   DEPLOY_COMPOSER=/usr/local/bin/composer

set -euo pipefail

# ── Parámetros ────────────────────────────────────────────────────────────────
APP_ENV="${DEPLOY_ENV:-prod}"
PHP="${DEPLOY_PHP:-}"
COMPOSER="${DEPLOY_COMPOSER:-composer}"
DRY_RUN=0
RUN_SMOKE=1
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"

for arg in "$@"; do
  case $arg in
    --dry-run)     DRY_RUN=1 ;;
    --no-smoke)    RUN_SMOKE=0 ;;
    --env=*)       APP_ENV="${arg#--env=}" ;;
    --php=*)       PHP="${arg#--php=}" ;;
  esac
done

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'

log()  { echo -e "${CYAN}[deploy]${RESET} $*"; }
ok()   { echo -e "  ${GREEN}✓${RESET} $*"; }
warn() { echo -e "  ${YELLOW}!${RESET} $*"; }
fail() { echo -e "  ${RED}✗${RESET} $*" >&2; }
die()  { fail "$*"; exit 1; }
run()  {
  if [[ $DRY_RUN -eq 1 ]]; then
    echo -e "  ${YELLOW}[dry]${RESET} $*"
  else
    eval "$*"
  fi
}

echo ""
echo -e "${BOLD}╔══════════════════════════════════════════════╗${RESET}"
echo -e "${BOLD}║        MBInv — Deploy  (SF 5.4 / PHP 8.x)    ║${RESET}"
echo -e "${BOLD}╚══════════════════════════════════════════════╝${RESET}"
echo -e "  Directorio : ${PROJECT_DIR}"
echo -e "  APP_ENV    : ${APP_ENV}"
[[ $DRY_RUN -eq 1 ]] && echo -e "  ${YELLOW}MODO DRY-RUN — sin cambios reales${RESET}"
echo ""

# ─────────────────────────────────────────────────────────────────────────────
# 1. VERIFICAR PHP >= 8.1
# ─────────────────────────────────────────────────────────────────────────────
log "1/7  Verificando PHP..."

# Detectar PHP automáticamente si no fue especificado
if [[ -z "$PHP" ]]; then
  for candidate in \
      /usr/local/opt/php@8.2/bin/php \
      /usr/local/opt/php@8.1/bin/php \
      /usr/bin/php8.2 /usr/bin/php8.1 \
      php8.2 php8.1 php; do
    if command -v "$candidate" &>/dev/null; then
      PHP="$candidate"
      break
    fi
  done
fi

[[ -z "$PHP" ]] && die "No se encontró PHP. Instala PHP >= 8.1 o usa --php=/ruta/php"

PHP_VERSION=$("$PHP" -r "echo PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;")
PHP_MAJOR=$(echo "$PHP_VERSION" | cut -d. -f1)
PHP_MINOR=$(echo "$PHP_VERSION" | cut -d. -f2)

if [[ "$PHP_MAJOR" -lt 8 ]] || { [[ "$PHP_MAJOR" -eq 8 ]] && [[ "$PHP_MINOR" -lt 1 ]]; }; then
  echo ""
  fail "PHP ${PHP_VERSION} detectado. SF 5.4 requiere PHP >= 8.1."
  echo ""
  echo -e "  ${BOLD}Para instalar PHP 8.2 en el servidor:${RESET}"
  echo -e "  ${YELLOW}  Ubuntu/Debian:${RESET}"
  echo -e "    add-apt-repository ppa:ondrej/php"
  echo -e "    apt install php8.2 php8.2-cli php8.2-fpm php8.2-mysql php8.2-xml php8.2-mbstring php8.2-zip php8.2-intl php8.2-curl"
  echo -e "  ${YELLOW}  CentOS/RHEL:${RESET}"
  echo -e "    dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm"
  echo -e "    dnf module enable php:remi-8.2 && dnf install php php-cli php-fpm php-mysqlnd php-xml php-mbstring"
  echo -e "  ${YELLOW}  macOS (Homebrew):${RESET}"
  echo -e "    brew install php@8.2"
  echo ""
  exit 1
fi

ok "PHP ${PHP_VERSION} en ${PHP}"

# Verificar extensiones requeridas
MISSING_EXT=0
PHP_MODULES=$("$PHP" -m 2>/dev/null)
for ext in pdo_mysql mbstring xml intl zip; do
  if ! echo "$PHP_MODULES" | grep -qi "^${ext}$"; then
    warn "Extensión PHP faltante: ${ext}"
    MISSING_EXT=1
  fi
done
# opcache es extensión Zend — verificar por separado
if ! echo "$PHP_MODULES" | grep -qi "opcache\|Zend OPcache"; then
  warn "OPcache no habilitado (recomendado para producción)"
fi
[[ $MISSING_EXT -eq 1 ]] && die "Instala las extensiones PHP faltantes antes de continuar."

# ─────────────────────────────────────────────────────────────────────────────
# 2. VERIFICAR COMPOSER
# ─────────────────────────────────────────────────────────────────────────────
log "2/7  Verificando Composer..."

if ! command -v "$COMPOSER" &>/dev/null; then
  # Intentar composer.phar local
  if [[ -f "${PROJECT_DIR}/composer.phar" ]]; then
    COMPOSER="$PHP ${PROJECT_DIR}/composer.phar"
  else
    echo ""
    fail "Composer no encontrado."
    echo -e "  Instalar: curl -sS https://getcomposer.org/installer | $PHP -- --install-dir=/usr/local/bin --filename=composer"
    exit 1
  fi
fi

COMPOSER_VERSION=$($COMPOSER --version --no-ansi 2>/dev/null | grep -oE '[0-9]+\.[0-9]+' | head -1)
ok "Composer ${COMPOSER_VERSION}"

# ─────────────────────────────────────────────────────────────────────────────
# 3. VERIFICAR .env.local
# ─────────────────────────────────────────────────────────────────────────────
log "3/7  Verificando configuración..."

if [[ ! -f "${PROJECT_DIR}/.env.local" ]]; then
  echo ""
  fail ".env.local no existe."
  echo ""
  echo -e "  Crea ${PROJECT_DIR}/.env.local con:"
  echo -e "  ${YELLOW}DATABASE_URL=\"mysql://USUARIO:CLAVE@HOST:PUERTO/NOMBRE_BD?serverVersion=8.0\"${RESET}"
  echo -e "  ${YELLOW}APP_ENV=${APP_ENV}${RESET}"
  echo -e "  ${YELLOW}APP_SECRET=$(openssl rand -hex 16 2>/dev/null || echo 'cambia-este-secret')${RESET}"
  echo ""
  exit 1
fi

# Verificar que hay configuración de BD (URL o variables individuales)
if ! grep -qE "DATABASE_URL|DATABASE_HOST|DATABASE_NAME" "${PROJECT_DIR}/.env.local"; then
  die ".env.local existe pero falta configuración de BD (DATABASE_HOST / DATABASE_URL)"
fi
ok ".env.local presente"

# ─────────────────────────────────────────────────────────────────────────────
# 4. INSTALAR DEPENDENCIAS
# ─────────────────────────────────────────────────────────────────────────────
log "4/7  Instalando dependencias PHP..."

COMPOSER_FLAGS="--no-interaction --prefer-dist --optimize-autoloader"
if [[ "$APP_ENV" == "prod" ]]; then
  COMPOSER_FLAGS="$COMPOSER_FLAGS --no-dev"
fi

run "cd '${PROJECT_DIR}' && $COMPOSER install $COMPOSER_FLAGS"
ok "Dependencias instaladas"

# ─────────────────────────────────────────────────────────────────────────────
# 5. PERMISOS DE DIRECTORIOS
# ─────────────────────────────────────────────────────────────────────────────
log "5/7  Configurando permisos..."

for dir in var/cache var/log public/uploads tmp; do
  if [[ ! -d "${PROJECT_DIR}/${dir}" ]]; then
    run "mkdir -p '${PROJECT_DIR}/${dir}'"
  fi
  run "chmod -R 775 '${PROJECT_DIR}/${dir}'"
done

# En producción: asegurar que www-data (o el usuario del webserver) puede escribir
if [[ "$APP_ENV" == "prod" ]]; then
  WEB_USER=$(ps aux | grep -E 'nginx|apache|httpd|php-fpm' | grep -v grep | awk '{print $1}' | head -1 || echo "")
  if [[ -n "$WEB_USER" && "$WEB_USER" != "root" ]]; then
    run "chown -R ${WEB_USER} '${PROJECT_DIR}/var' '${PROJECT_DIR}/tmp' 2>/dev/null || true"
    ok "Permisos asignados a ${WEB_USER}"
  else
    ok "Permisos configurados (ajusta el owner al usuario de tu webserver)"
  fi
else
  ok "Permisos configurados"
fi

# ─────────────────────────────────────────────────────────────────────────────
# 6. CACHÉ SYMFONY
# ─────────────────────────────────────────────────────────────────────────────
log "6/7  Limpiando y calentando caché..."

CONSOLE="${PROJECT_DIR}/bin/console"

run "$PHP -d memory_limit=256M '$CONSOLE' cache:clear --env=${APP_ENV} --no-warmup"
run "$PHP -d memory_limit=256M '$CONSOLE' cache:warmup --env=${APP_ENV} --no-optional-warmers"

# Verificar mapeos Doctrine (solo lectura — no modifica la BD)
if [[ $DRY_RUN -eq 0 ]]; then
  mapping_result=$("$PHP" -d memory_limit=256M "$CONSOLE" doctrine:mapping:info 2>&1) || true
  mapping_fails=$(echo "$mapping_result" | awk '/\[FAIL\]/{c++} END{print c+0}')
  if [[ "$mapping_fails" -gt 0 ]]; then
    warn "doctrine:mapping:info reportó ${mapping_fails} error(es) — revisa antes de continuar"
    echo "$mapping_result" | grep "\[FAIL\]" | sed 's/^/    /'
  else
    ok "Mapeos Doctrine OK"
  fi
fi

# ─────────────────────────────────────────────────────────────────────────────
# 7. SMOKE TEST POST-DEPLOY (opcional)
# ─────────────────────────────────────────────────────────────────────────────
if [[ $RUN_SMOKE -eq 1 ]] && [[ $DRY_RUN -eq 0 ]]; then
  log "7/7  Verificación post-deploy (smoke test)..."

  SMOKE_SCRIPT="${PROJECT_DIR}/scripts/smoke-test.sh"
  if [[ -f "$SMOKE_SCRIPT" ]]; then
    SMOKE_URL="${MBINV_URL:-http://127.0.0.1:8099}"
    if "$SMOKE_SCRIPT" --no-warmup --strict --url="$SMOKE_URL"; then
      ok "Smoke test: sin errores"
    else
      warn "Smoke test reportó errores — verifica las rutas antes de apuntar tráfico"
    fi
  else
    warn "smoke-test.sh no encontrado — omitiendo verificación"
  fi
else
  log "7/7  Smoke test omitido"
fi

# ─────────────────────────────────────────────────────────────────────────────
# RESUMEN
# ─────────────────────────────────────────────────────────────────────────────
echo ""
echo -e "${BOLD}══════════════════════════════════════════════════════════${RESET}"
if [[ $DRY_RUN -eq 1 ]]; then
  echo -e "${YELLOW}${BOLD}  DRY-RUN completado — sin cambios aplicados${RESET}"
else
  echo -e "${GREEN}${BOLD}  Deploy completado${RESET}"
fi
echo -e "${BOLD}══════════════════════════════════════════════════════════${RESET}"
echo ""

if [[ "$APP_ENV" == "prod" ]]; then
  echo -e "  ${BOLD}Próximos pasos manuales:${RESET}"
  echo -e "  1. Apuntar el virtualhost / nginx config a ${PROJECT_DIR}/public/"
  echo -e "  2. Configurar PHP-FPM con el pool correcto (php${PHP_VERSION}-fpm)"
  echo -e "  3. Reiniciar nginx/apache: sudo systemctl reload nginx"
  echo -e "  4. Verificar logs: tail -f ${PROJECT_DIR}/var/log/prod.log"
  echo ""
fi
