#!/bin/bash

# ===============================================
# DEPLOY MULTI-SERVIDOR PARA TAXES/COMEXNOW/MISNUMEROS/WATAX
# ===============================================

# No usar set -e para permitir continuar aunque haya errores
# set -e

# Colores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Configuraci\u00f3n de servidores
declare -A SERVERS
SERVERS["taxes"]="forge@localhost:/home/forge/taxes.com.ar"
SERVERS["taxes-worker"]="forge@134.209.208.210:/home/forge/taxes.com.ar"
SERVERS["comexnow"]="forge@134.209.208.210:/home/forge/comexnow.com.ar"
SERVERS["misnumeros"]="forge@134.122.125.132:/home/forge/misnumeros.com.ar"
# Watax: sitio comercial del servicio de WhatsApp (mismo repo, SITIO=watax en su .env).
# Vive en el servidor principal, al lado de taxes.com.ar.
# Dominio canonico: watax.app. watax.com.ar redirige con 301 a watax.app desde
# nginx, no tiene instalacion propia (una sola carpeta, un solo git pull).
SERVERS["watax"]="forge@localhost:/home/forge/watax.app"
SERVERS["mysql1"]="root@10.136.92.187:/home/forge/taxes.com.ar"  # MySQL-1 (usando IP privada)
SERVERS["mysql2"]="root@10.136.92.186:/home/forge/taxes.com.ar"  # MySQL-2 (usando IP privada)
SERVERS["mysql4"]="root@10.136.92.188:/home/forge/taxes.com.ar"  # MySQL-4 (usando IP privada)
SERVERS["mysql5"]="root@10.136.92.189:/home/forge/taxes.com.ar"  # MySQL-5 (usando IP privada)
SERVERS["mysql7"]="root@10.136.92.191:/home/forge/taxes.com.ar"  # MySQL-7 (usando IP privada)

# Variables comunes
PHP_FPM="php8.2-fpm"
BRANCH="master"

# Funci\u00f3n para imprimir con color
print_color() {
    local color=$1
    local message=$2
    echo -e "${color}${message}${NC}"
}

# Función para verificar conexión SSH
check_ssh_connection() {
    local server=$1
    
    print_color "$CYAN" "  Verificando conexión SSH a $server..."
    
    # Intentar conexión SSH con timeout de 5 segundos
    if ssh -o BatchMode=yes -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$server" "echo 'Conexión exitosa'" &>/dev/null; then
        print_color "$GREEN" "  ✓ Conexión SSH establecida"
        return 0
    else
        print_color "$RED" "  ✗ No se pudo conectar a $server"
        print_color "$YELLOW" "  Verifica que:"
        echo "    - Tienes las claves SSH configuradas"
        echo "    - El servidor está accesible"
        echo "    - El usuario tiene permisos"
        return 1
    fi
}

# Función para ejecutar comando mostrando output
execute_with_output() {
    local cmd=$1
    local description=$2
    
    print_color "$CYAN" "\n→ $description"
    echo "  Comando: $cmd"
    echo "  ----------------------------------------"
    
    # Ejecutar y mostrar output
    if eval "$cmd"; then
        print_color "$GREEN" "  ✓ $description completado"
        return 0
    else
        print_color "$RED" "  ✗ Error en: $description"
        return 1
    fi
}

# Función para ejecutar comando remoto mostrando output
execute_ssh_with_output() {
    local server=$1
    local cmd=$2
    local description=$3
    
    print_color "$CYAN" "\n→ $description"
    echo "  Servidor: $server"
    echo "  Comando: $cmd"
    echo "  ----------------------------------------"
    
    # Ejecutar SSH sin -t para evitar problemas con pseudo-terminal
    # Usar -o BatchMode=yes para evitar prompts interactivos
    if ssh -o BatchMode=yes -o StrictHostKeyChecking=no "$server" "$cmd" 2>&1; then
        print_color "$GREEN" "  ✓ $description completado"
        return 0
    else
        print_color "$RED" "  ✗ Error en: $description"
        return 1
    fi
}

# Función para ejecutar deploy en un servidor
deploy_server() {
    local server_name=$1
    local server_info=$2
    local deploy_type=$3
    local has_errors=0

    # Separar usuario@host y directorio
    IFS=':' read -r server_ssh server_dir <<< "$server_info"

    print_color "$BLUE" "\n========================================="
    print_color "$BLUE" " 🚀 Deploying to: $server_name"
    print_color "$BLUE" " Server: $server_ssh"
    print_color "$BLUE" " Directory: $server_dir"
    print_color "$BLUE" "========================================="

    # Si es servidor local
    if [[ "$server_ssh" == "forge@localhost" ]]; then
        print_color "$YELLOW" "\n📍 Ejecutando en servidor LOCAL..."

        # Sitio todavia no instalado en este servidor: se saltea, NO es un error.
        # (Sirve para tener la entrada cargada antes de crear el vhost.)
        if [[ ! -d "$server_dir" ]]; then
            print_color "$YELLOW" "  ⏭️  $server_dir no existe: sitio no instalado todavia. Salteado."
            return 2
        fi

        # Git pull
        execute_with_output "cd $server_dir && git pull origin $BRANCH" "Git pull" || has_errors=1

        # Asegurar symlink storage (no se versiona en git)
        execute_with_output "ln -sf $server_dir/storage/app/public $server_dir/public/storage" "Storage symlink" || has_errors=1

        # Assets ya vienen compilados del pipeline (git pull los trae)

        # Si es deploy completo
        if [[ "$deploy_type" == "2" ]]; then
            print_color "$YELLOW" "\n📦 Ejecutando deploy completo..."

            execute_with_output "cd $server_dir && composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev" "Composer install" || has_errors=1
            execute_with_output "cd $server_dir && php artisan migrate --force" "Migraciones" || has_errors=1
            execute_with_output "cd $server_dir && php artisan queue:restart" "Restart queues" || has_errors=1
            execute_with_output "cd $server_dir && php artisan config:cache" "Cache config" || has_errors=1
            execute_with_output "cd $server_dir && php artisan route:cache" "Cache routes" || has_errors=1
            execute_with_output "cd $server_dir && php artisan view:cache" "Cache views" || has_errors=1
            execute_with_output "sudo service $PHP_FPM reload" "Reload PHP-FPM" || has_errors=1

            # Supervisor solo si existe
            if command -v supervisorctl &> /dev/null; then
                execute_with_output "sudo supervisorctl reread && sudo supervisorctl update && sudo supervisorctl restart all" "Restart Supervisor" || has_errors=1
            fi
        fi

        if [[ $has_errors -eq 0 ]]; then
            print_color "$GREEN" "\n✅ Deploy completado en $server_name (LOCAL)"
        else
            print_color "$RED" "\n⚠️  Deploy en $server_name (LOCAL) terminó con errores"
        fi

    else
        print_color "$YELLOW" "\n🌐 Ejecutando en servidor REMOTO: $server_name"

        # Verificar conexión primero
        if ! check_ssh_connection "$server_ssh"; then
            print_color "$RED" "\n✗ No se puede conectar a $server_name. Saltando este servidor..."
            return 1
        fi

        # Sitio todavia no instalado en ese servidor: se saltea, NO es un error.
        if ! ssh -o BatchMode=yes -o StrictHostKeyChecking=no "$server_ssh" "[ -d $server_dir ]" &>/dev/null; then
            print_color "$YELLOW" "  ⏭️  $server_dir no existe en $server_name: sitio no instalado todavia. Salteado."
            return 2
        fi

        # Git pull
        #
        # WhatsApp ya NO se reinicia en el deploy: corre por WAHA, un contenedor
        # Docker en el worker (docker/waha) con su propio ciclo de vida.
        #
        # Antes, acá se detectaban cambios en whatsapp-service/ y se hacía
        # `pm2 restart taxes-whatsapp || pm2 start ecosystem.config.js`. Eso hoy es
        # peligroso: el proceso está DETENIDO a propósito (pm2 stop + pm2 save) y ese
        # `pm2 start` de fallback lo REVIVIRÍA, volviendo a levantar sesiones de
        # WhatsApp Web que consumen ~1,15 GB de RAM cada una y que ya nadie usa.
        # El código de whatsapp-service/ se conserva; para reactivarlo, a mano:
        #   pm2 start taxes-whatsapp && pm2 save
        execute_ssh_with_output "$server_ssh" "cd $server_dir && git pull origin $BRANCH" "Git pull en $server_name" || has_errors=1

        # Asegurar symlink storage (no se versiona en git)
        execute_ssh_with_output "$server_ssh" "ln -sf $server_dir/storage/app/public $server_dir/public/storage" "Storage symlink en $server_name" || has_errors=1

        # Para workers: reiniciar colas (soft) después de git pull para que tomen el código nuevo.
        # queue:restart deja una marca en cache (CACHE_DRIVER=file, local y compartido en
        # taxes-worker); cada worker `queue:work` se recicla limpio ENTRE jobs, sin cortar el
        # job en curso. NO hacemos restart DURO por supervisor: con timeout=0 en los jobs
        # largos (sueldos_masivos/finance) mataría jobs en vuelo (SIGKILL) y además reinicia
        # ~82 procesos en CADA deploy (lento). Contrapartida asumida: si un deploy toca el
        # código de un job largo y justo hay uno corriendo, ese job termina con código viejo
        # y el nuevo recién toma efecto en el siguiente proc reciclado.
        if [[ "$server_name" == "taxes-worker" ]]; then
            execute_ssh_with_output "$server_ssh" "cd $server_dir && php artisan queue:restart" "Restart colas (soft) en $server_name" || has_errors=1
        fi

        # Assets ya vienen compilados del pipeline (git pull los trae)

        # Si es deploy completo
        if [[ "$deploy_type" == "2" ]]; then
            print_color "$YELLOW" "\n📦 Ejecutando deploy completo en $server_name..."

            execute_ssh_with_output "$server_ssh" "cd $server_dir && composer install --no-interaction --prefer-dist --optimize-autoloader --no-dev" "Composer install" || has_errors=1

            # Migraciones específicas por servidor
            print_color "$YELLOW" "\n🗃️ Ejecutando migraciones específicas..."

            if [[ "$server_name" == "comexnow" ]]; then
                execute_ssh_with_output "$server_ssh" "cd $server_dir && php artisan migrate --force" "Migración principal" || has_errors=1
                execute_ssh_with_output "$server_ssh" "cd $server_dir && [ -f artisan2.php ] && php artisan2.php migrate --db=30-71666043-1 --force || echo 'artisan2.php no encontrado'" "Migración DB 30-71666043-1" || has_errors=1

            elif [[ "$server_name" == "misnumeros" ]]; then
                execute_ssh_with_output "$server_ssh" "cd $server_dir && php artisan migrate --force" "Migración principal" || has_errors=1
                execute_ssh_with_output "$server_ssh" "cd $server_dir && [ -f artisan2.php ] && php artisan2.php migrate --db=20-28468190-9 --force || echo 'artisan2.php no encontrado'" "Migración DB 20-28468190-9" || has_errors=1
                execute_ssh_with_output "$server_ssh" "cd $server_dir && [ -f artisan2.php ] && php artisan2.php migrate --db=30-71726980-9 --force || echo 'artisan2.php no encontrado'" "Migración DB 30-71726980-9" || has_errors=1

            else
                execute_ssh_with_output "$server_ssh" "cd $server_dir && php artisan migrate --force" "Migraciones" || has_errors=1
            fi

            execute_ssh_with_output "$server_ssh" "cd $server_dir && php artisan queue:restart" "Restart queues" || has_errors=1
            execute_ssh_with_output "$server_ssh" "cd $server_dir && php artisan config:cache" "Cache config" || has_errors=1
            execute_ssh_with_output "$server_ssh" "cd $server_dir && php artisan route:cache" "Cache routes" || has_errors=1
            execute_ssh_with_output "$server_ssh" "cd $server_dir && php artisan view:cache" "Cache views" || has_errors=1
            execute_ssh_with_output "$server_ssh" "sudo service $PHP_FPM reload" "Reload PHP-FPM" || has_errors=1

            # Supervisor solo si existe
            execute_ssh_with_output "$server_ssh" "command -v supervisorctl &> /dev/null && sudo supervisorctl reread && sudo supervisorctl update && sudo supervisorctl restart all || echo 'Supervisor no disponible'" "Restart Supervisor" || has_errors=1
        fi

        if [[ $has_errors -eq 0 ]]; then
            print_color "$GREEN" "\n✅ Deploy completado en $server_name (REMOTO)"
        else
            print_color "$RED" "\n⚠️  Deploy en $server_name (REMOTO) terminó con errores"
        fi
    fi

    echo ""
    return $has_errors
}

# Arrays para tracking de resultados
SERVERS_OK=()
SERVERS_FAIL=()
SERVERS_SKIP=()

# Función para ejecutar deploy en todos los servidores (secuencial)
deploy_all_sequential() {
    local deploy_type=$1

    print_color "$YELLOW" "\n🚀 Iniciando deploy SECUENCIAL en todos los servidores..."
    print_color "$YELLOW" "Orden: taxes (local) → taxes-worker → watax.app → comexnow → misnumeros → servidores MySQL"

    local server_order=("taxes" "taxes-worker" "watax" "comexnow" "misnumeros" "mysql1" "mysql2" "mysql4" "mysql5" "mysql7")

    for server_name in "${server_order[@]}"; do
        if [[ -n "${SERVERS[$server_name]}" ]]; then
            deploy_server "$server_name" "${SERVERS[$server_name]}" "$deploy_type"
            local rc=$?

            if [[ $rc -eq 0 ]]; then
                SERVERS_OK+=("$server_name")
            elif [[ $rc -eq 2 ]]; then
                # Sitio no instalado en ese servidor: no cuenta como error.
                SERVERS_SKIP+=("$server_name")
            else
                SERVERS_FAIL+=("$server_name")
            fi
        fi
    done
}

# Menú principal
print_color "$GREEN" "========================================="
print_color "$GREEN" " DEPLOY MULTI-SERVIDOR"
print_color "$GREEN" "========================================="
echo ""
echo "Servidores configurados:"
for server in "${!SERVERS[@]}"; do
    echo "  - $server: ${SERVERS[$server]}"
done
echo ""

# Tipo de deploy fijo: solo git pull
deploy_type="1"
print_color "$CYAN" "Tipo de deploy: Solo git pull (actualizar código)"

# Servidores fijos: todos (opción 10)
print_color "$CYAN" "Servidores: Todos (secuencial: local → taxes-worker → comex → misnumeros → servidores MySQL)"
echo ""

# Ejecutar deploy en todos los servidores
deploy_all_sequential "$deploy_type"

# Resumen final
echo ""
print_color "$BLUE" "========================================="
print_color "$BLUE" " RESUMEN DEL DEPLOY"
print_color "$BLUE" "========================================="

if [[ ${#SERVERS_OK[@]} -gt 0 ]]; then
    print_color "$GREEN" "\n✅ Servidores OK (${#SERVERS_OK[@]}):"
    for s in "${SERVERS_OK[@]}"; do
        print_color "$GREEN" "   ✓ $s"
    done
fi

if [[ ${#SERVERS_SKIP[@]} -gt 0 ]]; then
    print_color "$YELLOW" "\n⏭️  Salteados — sitio no instalado (${#SERVERS_SKIP[@]}):"
    for s in "${SERVERS_SKIP[@]}"; do
        print_color "$YELLOW" "   - $s"
    done
fi

if [[ ${#SERVERS_FAIL[@]} -gt 0 ]]; then
    print_color "$RED" "\n❌ Servidores con ERROR (${#SERVERS_FAIL[@]}):"
    for s in "${SERVERS_FAIL[@]}"; do
        print_color "$RED" "   ✗ $s"
    done
fi

echo ""
if [[ ${#SERVERS_FAIL[@]} -eq 0 ]]; then
    print_color "$GREEN" "========================================="
    print_color "$GREEN" " DEPLOY EXITOSO EN TODOS LOS SERVIDORES"
    print_color "$GREEN" "========================================="
else
    print_color "$RED" "========================================="
    print_color "$RED" " DEPLOY CON ERRORES - REVISAR SERVIDORES"
    print_color "$RED" "========================================="
    exit 1
fi