#!/bin/bash
# ═══════════════════════════════════════════════════════════════════════════════
#  AIRE PROJECT – MASTER DEPLOYMENT SCRIPT
#  Stack: Node.js + Express + Socket.io + SQLite
#  Entry: server.js | Port: 5000
#  Domains: facturaire.com, www.facturaire.com, micuentaire.com, www.micuentaire.com
# ═══════════════════════════════════════════════════════════════════════════════
set -e

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

ok()   { echo -e "${GREEN}✔ $*${NC}"; }
info() { echo -e "${CYAN}➜ $*${NC}"; }
warn() { echo -e "${YELLOW}⚠ $*${NC}"; }
err()  { echo -e "${RED}✘ $*${NC}"; }
h1()   { echo -e "\n${BOLD}${BLUE}══════════════════════════════════════════${NC}"; echo -e "${BOLD}${BLUE}  $*${NC}"; echo -e "${BOLD}${BLUE}══════════════════════════════════════════${NC}"; }

# ── Config ────────────────────────────────────────────────────────────────────
APP_DIR="/var/www/aire"
APP_USER="ubuntu"
APP_NAME="aire"
APP_PORT=5000
ENTRY="server.js"
DOMAINS="facturaire.com www.facturaire.com micuentaire.com www.micuentaire.com"
PRIMARY_DOMAIN="facturaire.com"
EMAIL="admin@facturaire.com"

# ═══════════════════════════════════════════════════════════════════════════════
h1 "1/9 · SISTEMA BASE"
# ═══════════════════════════════════════════════════════════════════════════════

info "Actualizando paquetes del sistema..."
sudo apt-get update -qq
sudo apt-get install -y -qq curl git build-essential nginx ufw certbot python3-certbot-nginx sqlite3 > /dev/null 2>&1
ok "Paquetes del sistema instalados"

# ═══════════════════════════════════════════════════════════════════════════════
h1 "2/9 · NODE.JS (via NVM)"
# ═══════════════════════════════════════════════════════════════════════════════

if ! command -v node &> /dev/null; then
    info "Instalando NVM + Node.js LTS..."
    curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
    nvm install --lts
    nvm use --lts
    nvm alias default 'lts/*'
    # Persist in bashrc
    echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.bashrc
    echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> ~/.bashrc
    ok "Node.js $(node --version) instalado"
else
    # Source NVM if already installed
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
    ok "Node.js ya instalado: $(node --version)"
fi

# Ensure node/npm are in PATH for sudo
NODE_BIN=$(dirname $(which node))
if [[ ":$PATH:" != *":$NODE_BIN:"* ]]; then
    export PATH="$NODE_BIN:$PATH"
fi

# ═══════════════════════════════════════════════════════════════════════════════
h1 "3/9 · PM2"
# ═══════════════════════════════════════════════════════════════════════════════

if ! command -v pm2 &> /dev/null; then
    info "Instalando PM2..."
    npm install -g pm2 > /dev/null 2>&1
    ok "PM2 instalado: $(pm2 --version)"
else
    ok "PM2 ya instalado: $(pm2 --version)"
fi

# ═══════════════════════════════════════════════════════════════════════════════
h1 "4/9 · DIRECTORIO + ARCHIVOS"
# ═══════════════════════════════════════════════════════════════════════════════

info "Creando directorio de la aplicación: $APP_DIR"
sudo mkdir -p "$APP_DIR"
sudo chown -R "$APP_USER:$APP_USER" "$APP_DIR"

info "Copiando archivos del proyecto (sin sobreescribir datos)..."

# Copy everything except node_modules, .git and existing DB/uploads
rsync -av --progress \
    --exclude='node_modules/' \
    --exclude='.git/' \
    --exclude='*.log' \
    /home/ubuntu/aire_src/ "$APP_DIR/" \
    --backup --suffix=".bak_$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true

ok "Archivos copiados a $APP_DIR"

# Protect existing database – don't overwrite if already exists
if [ -f "$APP_DIR/database.sqlite" ]; then
    warn "Base de datos SQLite ya existe – no se sobreescribe"
else
    info "Base de datos SQLite copiada por primera vez"
fi

# ─── .env setup ───────────────────────────────────────────────────────────────
if [ -f "$APP_DIR/.env" ]; then
    warn ".env ya existe – haciendo backup y actualizando NODE_ENV=production"
    cp "$APP_DIR/.env" "$APP_DIR/.env.bak_$(date +%Y%m%d_%H%M%S)"
    # Only update NODE_ENV to production, keep all other values
    sed -i 's/^NODE_ENV=.*/NODE_ENV=production/' "$APP_DIR/.env"
else
    info "Creando .env..."
    cp /home/ubuntu/aire_src/.env "$APP_DIR/.env"
    sed -i 's/^NODE_ENV=.*/NODE_ENV=production/' "$APP_DIR/.env"
fi

# Ensure uploads directory exists
sudo mkdir -p "$APP_DIR/uploads"
sudo chown -R "$APP_USER:$APP_USER" "$APP_DIR/uploads"
ok ".env y directorios configurados"

# ═══════════════════════════════════════════════════════════════════════════════
h1 "5/9 · DEPENDENCIAS NPM"
# ═══════════════════════════════════════════════════════════════════════════════

info "Instalando dependencias de producción..."
cd "$APP_DIR"
npm install --omit=dev 2>&1 | tail -5
ok "Dependencias instaladas"

# ═══════════════════════════════════════════════════════════════════════════════
h1 "6/9 · PM2 PROCESO + AUTOSTART"
# ═══════════════════════════════════════════════════════════════════════════════

cd "$APP_DIR"

# Stop existing process if running
if pm2 list | grep -q "$APP_NAME"; then
    warn "Proceso PM2 '$APP_NAME' ya existe – reiniciando con nueva versión"
    pm2 stop "$APP_NAME" 2>/dev/null || true
    pm2 delete "$APP_NAME" 2>/dev/null || true
fi

info "Iniciando aplicación con PM2..."
pm2 start "$ENTRY" \
    --name "$APP_NAME" \
    --env production \
    --log-date-format "YYYY-MM-DD HH:mm:ss" \
    --max-memory-restart 512M \
    --restart-delay 3000 \
    --max-restarts 10

info "Configurando PM2 para iniciar en boot..."
pm2 save
# Generate startup script and run it
STARTUP_CMD=$(pm2 startup | grep "sudo" | tail -1)
if [ -n "$STARTUP_CMD" ]; then
    eval "$STARTUP_CMD"
    ok "PM2 startup configurado"
else
    warn "No se pudo configurar startup automático – ejecuta 'pm2 startup' manualmente"
fi

ok "PM2 proceso '$APP_NAME' corriendo en puerto $APP_PORT"

# ═══════════════════════════════════════════════════════════════════════════════
h1 "7/9 · NGINX REVERSE PROXY"
# ═══════════════════════════════════════════════════════════════════════════════

NGINX_CONF="/etc/nginx/sites-available/$APP_NAME"
NGINX_ENABLED="/etc/nginx/sites-enabled/$APP_NAME"

info "Creando configuración Nginx..."
sudo tee "$NGINX_CONF" > /dev/null <<'NGINXEOF'
# ── AIRE – Nginx config (HTTP – Certbot agregará SSL automáticamente) ──────────
upstream aire_backend {
    server 127.0.0.1:5000;
    keepalive 64;
}

server {
    listen 80;
    server_name facturaire.com www.facturaire.com micuentaire.com www.micuentaire.com;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;

    # Large body for file uploads (multer)
    client_max_body_size 25M;

    # Proxy to Node.js
    location / {
        proxy_pass http://aire_backend;
        proxy_http_version 1.1;

        # WebSocket / Socket.io support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;

        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # Socket.io explicit path
    location /socket.io/ {
        proxy_pass http://aire_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_cache_bypass $http_upgrade;
    }

    # Static uploads folder
    location /uploads/ {
        alias /var/www/aire/uploads/;
        expires 7d;
        add_header Cache-Control "public, immutable";
    }
}
NGINXEOF

# Enable site
sudo ln -sf "$NGINX_CONF" "$NGINX_ENABLED"

# Remove default site if still linked
if [ -L /etc/nginx/sites-enabled/default ]; then
    sudo rm /etc/nginx/sites-enabled/default
    warn "Sitio 'default' de Nginx deshabilitado"
fi

# Test config
info "Verificando configuración de Nginx..."
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl enable nginx
ok "Nginx configurado y recargado"

# ═══════════════════════════════════════════════════════════════════════════════
h1 "8/9 · UFW FIREWALL"
# ═══════════════════════════════════════════════════════════════════════════════

info "Configurando UFW..."
sudo ufw allow OpenSSH    > /dev/null 2>&1
sudo ufw allow 'Nginx Full' > /dev/null 2>&1
sudo ufw --force enable   > /dev/null 2>&1
ok "UFW habilitado: SSH + HTTP + HTTPS permitidos"
sudo ufw status

# ═══════════════════════════════════════════════════════════════════════════════
h1 "9/9 · SSL CON CERTBOT (Let's Encrypt)"
# ═══════════════════════════════════════════════════════════════════════════════

info "Obteniendo certificados SSL para todos los dominios..."

# Check if certificates already exist
CERT_EXISTS=false
for domain in facturaire.com micuentaire.com; do
    if sudo certbot certificates 2>/dev/null | grep -q "$domain"; then
        CERT_EXISTS=true
        warn "Certificado para $domain ya existe"
    fi
done

if [ "$CERT_EXISTS" = false ]; then
    info "Solicitando nuevos certificados..."
    sudo certbot --nginx \
        -d facturaire.com \
        -d www.facturaire.com \
        -d micuentaire.com \
        -d www.micuentaire.com \
        --non-interactive \
        --agree-tos \
        --email "$EMAIL" \
        --redirect \
        --hsts \
        --staple-ocsp 2>&1 || {
            warn "Certbot falló para todos los dominios juntos. Intentando por separado..."
            sudo certbot --nginx \
                -d facturaire.com \
                -d www.facturaire.com \
                --non-interactive \
                --agree-tos \
                --email "$EMAIL" \
                --redirect 2>&1 || warn "Certbot falló para facturaire.com"
            sudo certbot --nginx \
                -d micuentaire.com \
                -d www.micuentaire.com \
                --non-interactive \
                --agree-tos \
                --email "$EMAIL" \
                --redirect 2>&1 || warn "Certbot falló para micuentaire.com"
        }
else
    info "Renovando certificados existentes..."
    sudo certbot renew --quiet 2>&1 || warn "Renovación falló – puede que aún no hayan vencido"
fi

# Enable certbot auto-renewal timer
sudo systemctl enable certbot.timer 2>/dev/null || true
sudo systemctl start certbot.timer 2>/dev/null || true

# Final nginx reload with SSL config
sudo nginx -t && sudo systemctl reload nginx
ok "SSL configurado con renovación automática"

# ═══════════════════════════════════════════════════════════════════════════════
h1 "✅ VERIFICACIÓN FINAL"
# ═══════════════════════════════════════════════════════════════════════════════

echo ""
info "──────────── PM2 STATUS ────────────"
pm2 status

echo ""
info "──────────── NGINX STATUS ────────────"
sudo systemctl status nginx --no-pager | head -20

echo ""
info "──────────── PUERTOS ACTIVOS ────────────"
sudo ss -tlnp | grep -E ':80|:443|:5000'

echo ""
info "──────────── UFW STATUS ────────────"
sudo ufw status

echo ""
info "──────────── CERTIFICADOS SSL ────────────"
sudo certbot certificates 2>/dev/null || echo "(sin certificados aún)"

echo ""
info "──────────── PRUEBA HTTP → HTTPS ────────────"
sleep 3
for domain in facturaire.com www.facturaire.com micuentaire.com www.micuentaire.com; do
    HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 "http://$domain" 2>/dev/null || echo "TIMEOUT")
    HTTPS_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 -k "https://$domain" 2>/dev/null || echo "TIMEOUT")
    echo -e "  ${CYAN}$domain${NC} → HTTP:${HTTP_CODE} | HTTPS:${HTTPS_CODE}"
done

# ═══════════════════════════════════════════════════════════════════════════════
echo ""
echo -e "${GREEN}${BOLD}╔══════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}${BOLD}║         🚀 DESPLIEGUE COMPLETADO EXITOSAMENTE        ║${NC}"
echo -e "${GREEN}${BOLD}╠══════════════════════════════════════════════════════╣${NC}"
echo -e "${GREEN}${BOLD}║  App:     /var/www/aire                              ║${NC}"
echo -e "${GREEN}${BOLD}║  Puerto:  5000 (interno)                             ║${NC}"
echo -e "${GREEN}${BOLD}║  PM2:     pm2 status | pm2 logs aire                 ║${NC}"
echo -e "${GREEN}${BOLD}║  URLs:    https://facturaire.com                     ║${NC}"
echo -e "${GREEN}${BOLD}║           https://micuentaire.com                    ║${NC}"
echo -e "${GREEN}${BOLD}╚══════════════════════════════════════════════════════╝${NC}"
echo ""
