#!/bin/bash

#===========================================================================================================
# Script: UpdateAPILAMP.sh
# Descripción: Actualiza APIDIAN desde versiones anteriores a la versión 2025
#              Cambia el repositorio git y aplica todas las migraciones necesarias
# Autor: Sistema de Actualización APIDIAN
# Fecha: 2025-12-01
# Version: 1.0
#
# Requisitos:
# - Ubuntu 20.04 o superior
# - Aplicación APIDIAN ya instalada
# - Git configurado
#
# Uso:
#   sudo bash UpdateAPILAMP.sh
#
# Repositorio nuevo:
#   https://gitlab.torresoftware.com/TorreSoftware/apidian-laravel-8-s3.git
#
#===========================================================================================================

#-------------------------------------COLORES PARA MENSAJES------------------------------------------------------------
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m' # No Color
BOLD='\033[1m'

#-------------------------------------FUNCIONES DE MENSAJES------------------------------------------------------------
print_header() {
    echo ""
    echo -e "${CYAN}╔═══════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${CYAN}║                                                               ║${NC}"
    echo -e "${CYAN}║  ${BOLD}${MAGENTA}     ACTUALIZACIÓN APIDIAN - Versión 2025${NC}${CYAN}                    ║${NC}"
    echo -e "${CYAN}║  ${BLUE}     Cambio de Repositorio y Aplicación de Cambios${NC}${CYAN}           ║${NC}"
    echo -e "${CYAN}║                                                               ║${NC}"
    echo -e "${CYAN}╚═══════════════════════════════════════════════════════════════╝${NC}"
    echo ""
}

print_success() {
    echo -e "${GREEN}✓ $1${NC}"
}

print_error() {
    echo -e "${RED}✗ $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}⚠ $1${NC}"
}

print_info() {
    echo -e "${BLUE}ℹ $1${NC}"
}

print_step() {
    echo ""
    echo -e "${CYAN}${BOLD}▶ $1${NC}"
    echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}

# Función para ejecutar comandos con spinner y timeout
run_with_spinner() {
    local cmd="$1"
    local msg="$2"
    local timeout="${3:-300}"

    print_info "$msg"

    eval "$cmd" > /tmp/update_output.log 2>&1 &
    local pid=$!

    local spin='-\|/'
    local i=0
    local elapsed=0

    while kill -0 $pid 2>/dev/null; do
        i=$(( (i+1) %4 ))
        printf "\r${CYAN}   Procesando... ${spin:$i:1} (${elapsed}s)${NC}"
        sleep 1
        elapsed=$((elapsed + 1))

        if [ $elapsed -ge $timeout ]; then
            kill -9 $pid 2>/dev/null
            printf "\r"
            print_error "Tiempo de espera agotado después de ${timeout}s"
            print_info "Revisa los logs en /tmp/update_output.log"
            tail -20 /tmp/update_output.log
            return 1
        fi
    done

    wait $pid
    local exit_code=$?
    printf "\r"

    if [ $exit_code -eq 0 ]; then
        return 0
    else
        print_error "Comando falló con código $exit_code"
        print_info "Últimas líneas del log:"
        tail -20 /tmp/update_output.log
        return $exit_code
    fi
}

# Función para ejecutar comandos interactivos (sin redirección, permite entrada del usuario)
run_interactive() {
    local cmd="$1"
    local msg="$2"

    print_info "$msg"

    eval "$cmd"
    local exit_code=$?

    if [ $exit_code -eq 0 ]; then
        print_success "Operación completada exitosamente"
        return 0
    else
        print_error "Comando falló con código $exit_code"
        return $exit_code
    fi
}

#===========================================================================================================
# VERIFICACIONES INICIALES
#===========================================================================================================

print_header

# Verificar que se ejecuta como root
if [ "$EUID" -ne 0 ]; then
    print_error "Este script debe ejecutarse como root (sudo)"
    echo -e "${YELLOW}Uso: sudo bash $0${NC}"
    exit 1
fi

print_success "Ejecutando como root"

# Información del sistema
UBUNTU_VERSION=$(lsb_release -rs)
UBUNTU_MAJOR=$(echo "$UBUNTU_VERSION" | cut -d. -f1)

print_info "Sistema: Ubuntu $UBUNTU_VERSION"

# Verificar versión de Ubuntu soportada
if [[ "$UBUNTU_MAJOR" -lt 20 ]]; then
    print_error "APIDIAN 2025 no es compatible con Ubuntu versiones menores a 20.04"
    print_warning "Tu versión: Ubuntu $UBUNTU_VERSION"
    print_info "Se requiere mínimo Ubuntu 20.04 LTS"
    print_warning "Por favor actualiza tu Ubuntu antes de continuar"
    exit 1
elif [[ ! "$UBUNTU_VERSION" =~ ^(20.04|22.04|24.04) ]]; then
    print_warning "Ubuntu $UBUNTU_VERSION no ha sido testeada oficialmente"
    print_info "Se procederá con actualización (compatibilidad parcial)"
fi

print_success "Versión de Ubuntu soportada"

# Detectar directorio de instalación
print_step "Detectando instalación de APIDIAN"

APIDIAN_DIR=""
POSSIBLE_DIRS=(
    "/var/www/apidian"
    "/var/www/html/apidian"
    "/opt/apidian"
    "/root/apidian"
    "/home/*/apidian"
    "$(pwd)/apidian"
)

for dir in "${POSSIBLE_DIRS[@]}"; do
    if [ -d "$dir" ] && [ -f "$dir/.env" ] && [ -f "$dir/artisan" ]; then
        APIDIAN_DIR="$dir"
        break
    fi
done

if [ -z "$APIDIAN_DIR" ]; then
    print_error "No se encontró instalación de APIDIAN"
    print_info "Directorios buscados:"
    for dir in "${POSSIBLE_DIRS[@]}"; do
        echo "  - $dir"
    done
    echo ""
    read -p "Ingresa el directorio de APIDIAN: " CUSTOM_DIR
    if [ -d "$CUSTOM_DIR" ] && [ -f "$CUSTOM_DIR/.env" ]; then
        APIDIAN_DIR="$CUSTOM_DIR"
    else
        print_error "Directorio inválido o no contiene APIDIAN"
        exit 1
    fi
fi

print_success "APIDIAN encontrado en: $APIDIAN_DIR"

# Cambiar al directorio
cd "$APIDIAN_DIR" || exit 1

#===========================================================================================================
# ADVERTENCIAS Y CONFIRMACIÓN
#===========================================================================================================

echo ""
echo -e "${RED}╔════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║                    ADVERTENCIA - ACTUALIZACION CRITICA             ║${NC}"
echo -e "${RED}╚════════════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "${YELLOW}Este script realizará las siguientes acciones:${NC}"
echo ""
echo -e "  ${CYAN}1.${NC} Hacer backup del .env actual"
echo -e "  ${CYAN}2.${NC} Cambiar el repositorio Git a la versión 2025"
echo -e "  ${CYAN}3.${NC} Descargar cambios del nuevo repositorio"
echo -e "  ${CYAN}4.${NC} Actualizar dependencias con Composer"
echo -e "  ${CYAN}5.${NC} Ejecutar migraciones de base de datos"
echo -e "  ${CYAN}6.${NC} Limpiar cache y optimizar"
echo -e "  ${CYAN}7.${NC} Configurar OpenSSL legacy (si es necesario)"
echo ""
echo -e "${RED}IMPORTANTE:${NC}"
echo -e "  • Se realizará un BACKUP de tu .env"
echo -e "  • Se cambiará el repositorio Git"
echo -e "  • Se ejecutarán migraciones de base de datos"
echo -e "  • Se recomienda backup completo de la aplicación antes de continuar"
echo ""

read -p "¿Deseas continuar con la actualización? [s/N]: " CONFIRM
if [[ ! "$CONFIRM" =~ ^[sS]$ ]]; then
    print_warning "Actualización cancelada por el usuario"
    exit 0
fi

#===========================================================================================================
# VERIFICAR Y ACTUALIZAR PHP SI ES NECESARIO
#===========================================================================================================

print_step "Verificando Versión de PHP"

# Detectar versión actual de PHP
CURRENT_PHP_VERSION=$(php -v 2>/dev/null | grep -oP 'PHP \K\d+\.\d+' | head -1)

# Si no hay PHP instalado, las variables estarán vacías
if [ -z "$CURRENT_PHP_VERSION" ]; then
    print_warning "PHP no está instalado o no está en el PATH"
    CURRENT_PHP_MAJOR=""
    CURRENT_PHP_MINOR=""
    NEEDS_UPDATE=1
else
    CURRENT_PHP_MAJOR=$(echo "$CURRENT_PHP_VERSION" | cut -d. -f1)
    CURRENT_PHP_MINOR=$(echo "$CURRENT_PHP_VERSION" | cut -d. -f2)
    print_info "Versión actual de PHP: $CURRENT_PHP_VERSION"
fi

# Determinar versión de PHP requerida según Ubuntu
# Usar versiones nativas de cada Ubuntu para evitar problemas de repositorios
REQUIRED_PHP_VERSION="8.1"
if [[ "$UBUNTU_MAJOR" == "20" ]]; then
    REQUIRED_PHP_VERSION="7.4"   # Ubuntu 20.04 tiene PHP 7.4 nativo
elif [[ "$UBUNTU_MAJOR" == "22" ]]; then
    REQUIRED_PHP_VERSION="8.1"   # Ubuntu 22.04 tiene PHP 8.1 nativo (no 8.0)
elif [[ "$UBUNTU_MAJOR" == "24" ]]; then
    REQUIRED_PHP_VERSION="8.3"   # Ubuntu 24.04 tiene PHP 8.3 nativo
fi

print_info "Versión requerida de PHP: $REQUIRED_PHP_VERSION (nativa de Ubuntu $UBUNTU_VERSION)"

# Comparar versiones (solo si PHP ya está instalado)
REQUIRED_MAJOR=$(echo "$REQUIRED_PHP_VERSION" | cut -d. -f1)
REQUIRED_MINOR=$(echo "$REQUIRED_PHP_VERSION" | cut -d. -f2)

NEEDS_UPDATE=0
if [ -z "$CURRENT_PHP_VERSION" ]; then
    # PHP no instalado, necesita instalarse
    NEEDS_UPDATE=1
elif [ ! -z "$CURRENT_PHP_MAJOR" ] && [ ! -z "$REQUIRED_MAJOR" ]; then
    if [ "$CURRENT_PHP_MAJOR" -lt "$REQUIRED_MAJOR" ]; then
        NEEDS_UPDATE=1
    elif [ "$CURRENT_PHP_MAJOR" -eq "$REQUIRED_MAJOR" ] && [ ! -z "$CURRENT_PHP_MINOR" ] && [ ! -z "$REQUIRED_MINOR" ]; then
        if [ "$CURRENT_PHP_MINOR" -lt "$REQUIRED_MINOR" ]; then
            NEEDS_UPDATE=1
        fi
    fi
fi

if [ $NEEDS_UPDATE -eq 1 ]; then
    if [ -z "$CURRENT_PHP_VERSION" ]; then
        print_warning "PHP no está instalado - Se procederá a instalar PHP $REQUIRED_PHP_VERSION"
    else
        print_warning "PHP necesita ser actualizado: $CURRENT_PHP_VERSION → $REQUIRED_PHP_VERSION"
    fi

    print_info "Deteniendo servicios web..."

    systemctl stop apache2 2>/dev/null || systemctl stop nginx 2>/dev/null || true
    systemctl stop php-fpm 2>/dev/null || true

    # Solo intentar detener servicio PHP antiguo si existe
    if [ ! -z "$CURRENT_PHP_MAJOR" ] && [ ! -z "$CURRENT_PHP_MINOR" ]; then
        systemctl stop "php${CURRENT_PHP_MAJOR}.${CURRENT_PHP_MINOR}-fpm" 2>/dev/null || true
    fi

    print_info "Preparando instalación de PHP..."

    # Instalar software-properties-common si no está
    apt-get install -y software-properties-common apt-transport-https ca-certificates -qq 2>/dev/null

    # Verificar si el paquete PHP está disponible
    print_info "Verificando disponibilidad de PHP ${REQUIRED_MAJOR}.${REQUIRED_MINOR}..."
    apt-cache policy "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}" 2>/dev/null | grep -q "Candidate:" || {
        print_warning "PHP ${REQUIRED_MAJOR}.${REQUIRED_MINOR} no está en repositorios nativos"
        print_info "Agregando repositorio ondrej/php..."

        # Agregar repositorio ondrej/php
        LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php -y
        apt-get update -qq
        print_success "Repositorio ondrej/php agregado"
    }

    # Actualizar repositorios (con --allow-releaseinfo-change para evitar errores)
    print_info "Actualizando repositorios APT..."
    apt-get update --allow-releaseinfo-change -qq 2>/dev/null || apt-get update -qq

    # Desinstalar versión anterior completamente (solo si estaba instalada)
    if [ ! -z "$CURRENT_PHP_MAJOR" ] && [ ! -z "$CURRENT_PHP_MINOR" ]; then
        print_info "Removiendo PHP $CURRENT_PHP_MAJOR.$CURRENT_PHP_MINOR completamente..."
        apt-get remove -y "php${CURRENT_PHP_MAJOR}.${CURRENT_PHP_MINOR}*" 2>/dev/null || true
        apt-get autoremove -y -qq
        apt-get autoclean -y -qq

        # Limpiar alternativas antigas si existen
        update-alternatives --remove php "/usr/bin/php${CURRENT_PHP_MAJOR}.${CURRENT_PHP_MINOR}" 2>/dev/null || true
        update-alternatives --remove-all php 2>/dev/null || true
    else
        # Si no había PHP, limpiar cualquier instalación PHP residual
        print_info "Removiendo instalaciones PHP residuales..."
        apt-get remove -y 'php*' 2>/dev/null || true
        apt-get autoremove -y -qq
        apt-get autoclean -y -qq
    fi

    # Instalar nueva versión
    print_info "Instalando PHP $REQUIRED_MAJOR.$REQUIRED_MINOR y extensiones necesarias (esto puede tomar unos minutos)..."

    # Instalar paquetes PHP (sin pipe a grep para no causar errores)
    DEBIAN_FRONTEND=noninteractive apt-get install -y \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-cli" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-fpm" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-common" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-curl" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-gd" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-intl" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-mbstring" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-mysql" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-opcache" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-xml" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-zip" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-imap" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-soap" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-dev" \
        "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-bcmath" > /tmp/php_install.log 2>&1

    if [ $? -eq 0 ]; then
        print_success "Paquetes PHP instalados correctamente"
    else
        print_error "Error al instalar paquetes PHP"
        print_info "Últimas líneas del log de instalación:"
        tail -20 /tmp/php_install.log
        print_warning "Verifica que los paquetes php${REQUIRED_MAJOR}.${REQUIRED_MINOR} estén disponibles"
        exit 1
    fi

    # Esperar un momento para que se terminen de escribir archivos
    sleep 2

    # Verificar que el binario PHP existe
    if [ ! -f "/usr/bin/php${REQUIRED_MAJOR}.${REQUIRED_MINOR}" ]; then
        print_error "El binario /usr/bin/php${REQUIRED_MAJOR}.${REQUIRED_MINOR} no se instaló correctamente"
        print_info "Buscando PHP instalado..."
        find /usr -name "php${REQUIRED_MAJOR}.*" -type f 2>/dev/null
        exit 1
    fi

    # Crear symlinks explícitamente
    print_info "Configurando symlinks de PHP..."
    ln -sf "/usr/bin/php${REQUIRED_MAJOR}.${REQUIRED_MINOR}" /usr/bin/php
    print_success "Symlink /usr/bin/php -> /usr/bin/php${REQUIRED_MAJOR}.${REQUIRED_MINOR}"

    if [ -f "/usr/bin/php-fpm${REQUIRED_MAJOR}.${REQUIRED_MINOR}" ]; then
        ln -sf "/usr/bin/php-fpm${REQUIRED_MAJOR}.${REQUIRED_MINOR}" /usr/bin/php-fpm
        print_success "Symlink /usr/bin/php-fpm -> /usr/bin/php-fpm${REQUIRED_MAJOR}.${REQUIRED_MINOR}"
    fi

    # Actualizar alternativas de PHP
    update-alternatives --install /usr/bin/php php "/usr/bin/php${REQUIRED_MAJOR}.${REQUIRED_MINOR}" 100 >/dev/null 2>&1
    update-alternatives --set php "/usr/bin/php${REQUIRED_MAJOR}.${REQUIRED_MINOR}" >/dev/null 2>&1
    print_success "Alternativas de PHP actualizadas"

    # Configurar servidor web para usar PHP
    print_info "Configurando servidor web..."

    # Detectar si es Apache o Nginx
    if systemctl is-active --quiet apache2 || [ -d "/etc/apache2" ]; then
        print_info "Detectado: Apache2"

        # Deshabilitar módulos PHP antiguos
        if [ ! -z "$CURRENT_PHP_MAJOR" ] && [ ! -z "$CURRENT_PHP_MINOR" ]; then
            a2dismod "php${CURRENT_PHP_MAJOR}.${CURRENT_PHP_MINOR}" 2>/dev/null || true
        fi

        # Habilitar módulo PHP nuevo (si existe)
        if [ -f "/usr/lib/apache2/modules/libphp${REQUIRED_MAJOR}.${REQUIRED_MINOR}.so" ]; then
            a2enmod "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}" 2>/dev/null
            print_success "Módulo Apache PHP ${REQUIRED_MAJOR}.${REQUIRED_MINOR} habilitado"
        else
            # Si no hay módulo, configurar proxy a PHP-FPM
            print_info "Módulo PHP no disponible, configurando PHP-FPM con Apache"
            a2enmod proxy_fcgi setenvif 2>/dev/null
            a2enconf "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-fpm" 2>/dev/null
            print_success "PHP-FPM configurado con Apache"
        fi

    elif systemctl is-active --quiet nginx || [ -d "/etc/nginx" ]; then
        print_info "Detectado: Nginx (usa PHP-FPM automáticamente)"
    fi

    # Iniciar y habilitar PHP-FPM
    print_info "Iniciando servicios PHP-FPM..."
    systemctl enable "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-fpm" 2>/dev/null || true
    systemctl restart "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-fpm" 2>/dev/null || true

    # Verificar que PHP-FPM esté corriendo
    if systemctl is-active --quiet "php${REQUIRED_MAJOR}.${REQUIRED_MINOR}-fpm"; then
        print_success "PHP-FPM ${REQUIRED_MAJOR}.${REQUIRED_MINOR} está activo"
    else
        print_warning "PHP-FPM no se inició correctamente"
    fi

    # Reiniciar servidor web
    print_info "Reiniciando servidor web..."
    if systemctl restart apache2 2>/dev/null; then
        print_success "Apache2 reiniciado"
    elif systemctl restart nginx 2>/dev/null; then
        print_success "Nginx reiniciado"
    else
        print_warning "No se pudo reiniciar el servidor web automáticamente"
    fi

    # Esperar a que los servicios inicien
    sleep 3

    # Verificar nueva versión
    print_info "Verificando instalación de PHP..."
    if command -v php &> /dev/null; then
        NEW_PHP_VERSION=$(php -v 2>/dev/null | grep -oP 'PHP \K\d+\.\d+' | head -1)
        if [ ! -z "$NEW_PHP_VERSION" ]; then
            print_success "✓ PHP instalado correctamente: $NEW_PHP_VERSION"
            php -v | head -1
        else
            print_error "PHP comando existe pero no devuelve versión"
            ls -la /usr/bin/php*
            exit 1
        fi
    else
        print_error "Comando 'php' no disponible después de la instalación"
        print_info "Verificando archivos instalados..."
        ls -la "/usr/bin/php${REQUIRED_MAJOR}.${REQUIRED_MINOR}"* 2>/dev/null

        # Intentar agregar al PATH manualmente
        export PATH="/usr/bin:$PATH"
        if command -v php &> /dev/null; then
            print_success "PHP ahora disponible en PATH"
        else
            print_error "No se pudo configurar PHP correctamente"
            exit 1
        fi
    fi
else
    print_success "PHP ya está en versión compatible: $CURRENT_PHP_VERSION"
fi

#===========================================================================================================
# BACKUP DEL .ENV
#===========================================================================================================

print_step "Realizando Backup"

BACKUP_DIR="$APIDIAN_DIR/backups/update-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"

print_info "Creando backup en: $BACKUP_DIR"

# Backup del .env
if [ -f "$APIDIAN_DIR/.env" ]; then
    cp "$APIDIAN_DIR/.env" "$BACKUP_DIR/.env.backup"
    print_success "Backup de .env creado"
fi

# Backup de storage (omitido para evitar demoras - los datos están en la BD)
if [ -d "$APIDIAN_DIR/storage" ]; then
    print_info "Nota: Storage no se respalda (los XMLs están en la base de datos)"
    print_info "Si necesitas backup completo, cópialo manualmente antes de actualizar"
fi

print_success "Backups completados en: $BACKUP_DIR"

#===========================================================================================================
# CAMBIAR REPOSITORIO GIT
#===========================================================================================================

print_step "Cambiando Repositorio Git"

NEW_REPO="https://gitlab.torresoftware.com/TorreSoftware/apidian-laravel-8-s3.git"
CURRENT_REPO=$(cd "$APIDIAN_DIR" && git config --get remote.origin.url 2>/dev/null || echo "No encontrado")

print_info "Repositorio actual: $CURRENT_REPO"
print_info "Nuevo repositorio: $NEW_REPO"

# Cambiar URL del repositorio
if (cd "$APIDIAN_DIR" && git remote set-url origin "$NEW_REPO"); then
    print_success "Repositorio Git actualizado"
else
    print_error "Error al cambiar repositorio Git"
    exit 1
fi

# Verificar que el cambio se aplicó
VERIFY_REPO=$(cd "$APIDIAN_DIR" && git config --get remote.origin.url)
print_info "Verificación: $VERIFY_REPO"

#===========================================================================================================
# ACTUALIZAR REPOSITORIO
#===========================================================================================================

print_step "Descargando Cambios del Repositorio"

# Stash de cambios locales si los hay
print_info "Verificando cambios locales..."
cd "$APIDIAN_DIR" || exit 1
if ! git diff-index --quiet HEAD -- 2>/dev/null; then
    print_warning "Cambios locales detectados - Guardando cambios..."
    if git stash; then
        print_success "Cambios guardados temporalmente"
    else
        print_error "Error al guardar cambios locales"
        exit 1
    fi
fi
cd - > /dev/null || true

# Fetch del nuevo repositorio (interactivo para permitir entrada de credenciales)
print_info "Descargando del nuevo repositorio..."
if (cd "$APIDIAN_DIR" && git fetch --all --force); then
    print_success "Cambios descargados"
else
    print_error "Error al descargar del repositorio"
    exit 1
fi

# Reset a la rama master del nuevo repositorio (interactivo)
print_info "Aplicando cambios del nuevo repositorio..."
if (cd "$APIDIAN_DIR" && git reset --hard origin/master); then
    print_success "Cambios aplicados"
else
    print_error "Error al aplicar cambios del repositorio"
    exit 1
fi

print_success "Repositorio actualizado a la versión 2025"

#===========================================================================================================
# ACTUALIZAR DEPENDENCIAS COMPOSER
#===========================================================================================================

print_step "Actualizando Dependencias Composer"

# Detectar PHP executable - buscar versión específica si es necesario
PHP_BIN="php"
if ! command -v php &> /dev/null; then
    # Si no encuentra php en PATH, buscar la versión específica
    if [ ! -z "$REQUIRED_PHP_VERSION" ]; then
        REQUIRED_MAJOR=$(echo "$REQUIRED_PHP_VERSION" | cut -d. -f1)
        REQUIRED_MINOR=$(echo "$REQUIRED_PHP_VERSION" | cut -d. -f2)
        if [ -f "/usr/bin/php${REQUIRED_MAJOR}.${REQUIRED_MINOR}" ]; then
            PHP_BIN="/usr/bin/php${REQUIRED_MAJOR}.${REQUIRED_MINOR}"
            print_warning "PHP no está en PATH, usando: $PHP_BIN"
        else
            print_error "No se encontró PHP ejecutable"
            exit 1
        fi
    fi
fi

print_info "Usando PHP: $PHP_BIN"

# Actualizar composer
print_info "Actualizando Composer..."
if run_with_spinner "$PHP_BIN -d memory_limit=-1 $(which composer) self-update --quiet" "Actualizando Composer..." 120; then
    print_success "Composer actualizado"
else
    print_warning "Error al actualizar Composer, continuando..."
fi

# Remover lock file desactualizado (cambio de Laravel 7 a 8 requiere update)
print_info "Preparando actualización de dependencias..."
if [ -f "$APIDIAN_DIR/composer.lock" ]; then
    rm "$APIDIAN_DIR/composer.lock"
    print_success "Lock file anterior removido"
fi

# Actualizar dependencias (necesario para cambio de versiones principales)
print_info "Actualizando dependencias (esto puede tomar varios minutos)..."
if run_with_spinner "cd '$APIDIAN_DIR' && COMPOSER_ALLOW_SUPERUSER=1 $PHP_BIN -d memory_limit=-1 $(which composer) update --no-interaction --optimize-autoloader --with-all-dependencies --prefer-dist" "Instalando nuevas versiones de dependencias..." 900; then
    print_success "Dependencias actualizadas correctamente"
else
    print_warning "Error al actualizar - Intentando incluyendo paquetes de desarrollo..."
    # Si falla, intentar con paquetes dev (necesarios para algunos paquetes)
    if run_with_spinner "cd '$APIDIAN_DIR' && COMPOSER_ALLOW_SUPERUSER=1 $PHP_BIN -d memory_limit=-1 $(which composer) update --no-interaction --optimize-autoloader --with-all-dependencies" "Actualizando incluyendo dependencias de desarrollo..." 900; then
        print_success "Dependencias actualizadas con paquetes de desarrollo"
    else
        print_error "Error al actualizar dependencias"
        print_warning "Intentando limpieza y reinstalación completa..."

        # Limpiar completamente y intentar fresh install
        if run_with_spinner "cd '$APIDIAN_DIR' && rm -rf vendor && COMPOSER_ALLOW_SUPERUSER=1 $PHP_BIN -d memory_limit=-1 $(which composer) install --no-interaction --optimize-autoloader --with-all-dependencies" "Reinstalación completa de dependencias..." 900; then
            print_success "Dependencias reinstaladas exitosamente"
        else
            print_error "Error al instalar dependencias incluso después de limpieza"
            print_info "Revisa el archivo: /tmp/update_output.log"
            tail -30 /tmp/update_output.log
            exit 1
        fi
    fi
fi

#===========================================================================================================
# COPIAR ARCHIVOS URN Y PLANTILLAS
#===========================================================================================================

print_step "Copiando Archivos URN y Plantillas XML"

cd "$APIDIAN_DIR" || exit 1

# Copiar plantillas XML desde carpeta urn
if [ -d "resources/templates/xml/urn" ]; then
    print_info "Copiando plantillas XML..."
    cp resources/templates/xml/urn/*.* resources/templates/xml/ 2>/dev/null || true
    print_success "Plantillas XML copiadas"
else
    print_warning "No se encontró directorio resources/templates/xml/urn"
fi

# Copiar archivos XAdES desde carpeta urn
if [ -d "vendor/ubl21dian/torresoftware/src/XAdES/urn" ]; then
    print_info "Copiando archivos XAdES..."
    cp vendor/ubl21dian/torresoftware/src/XAdES/urn/*.* vendor/ubl21dian/torresoftware/src/XAdES/ 2>/dev/null || true
    print_success "Archivos XAdES copiados"
else
    print_warning "No se encontró directorio vendor/ubl21dian/torresoftware/src/XAdES/urn"
fi

# Copiar Request.php personalizado
if [ -f "resources/templates/xml/urn/Request.php" ]; then
    print_info "Copiando Request.php personalizado..."
    cp resources/templates/xml/urn/Request.php vendor/laravel/framework/src/Illuminate/Http/Request.php
    print_success "Request.php personalizado copiado al framework Laravel"
else
    print_warning "No se encontró resources/templates/xml/urn/Request.php"
fi

print_success "Archivos URN procesados"

#===========================================================================================================
# CONFIGURAR OPENSSL LEGACY (si es necesario)
#===========================================================================================================

print_step "Verificando OpenSSL"

OPENSSL_VERSION=$(openssl version | grep -oP '\d+\.\d+\.\d+' | head -n1)
OPENSSL_MAJOR=$(echo "$OPENSSL_VERSION" | cut -d. -f1)

print_info "OpenSSL version detectada: $OPENSSL_VERSION"

if [ "$OPENSSL_MAJOR" -ge 3 ]; then
    print_info "OpenSSL 3+ detectado - Configurando legacy provider..."

    OPENSSL_CNF="/etc/ssl/openssl.cnf"

    if [ ! -f "$OPENSSL_CNF" ]; then
        print_error "No se encontró $OPENSSL_CNF"
        exit 1
    fi

    # Crear backup
    if [ ! -f "${OPENSSL_CNF}.backup" ]; then
        cp $OPENSSL_CNF ${OPENSSL_CNF}.backup
        print_success "Backup creado: ${OPENSSL_CNF}.backup"
    fi

    # Verificar si ya está configurado
    if grep -q "^\[legacy_sect\]" $OPENSSL_CNF && grep -q "legacy = legacy_sect" $OPENSSL_CNF; then
        print_success "OpenSSL legacy ya configurado"
    else
        print_info "Configurando providers en $OPENSSL_CNF..."

        # Agregar configuración al inicio del archivo si no existe
        if ! grep -q "^openssl_conf = openssl_init" $OPENSSL_CNF; then
            sed -i '1i openssl_conf = openssl_init\n' $OPENSSL_CNF
        fi

        # Agregar sección [openssl_init] si no existe
        if ! grep -q "^\[openssl_init\]" $OPENSSL_CNF; then
            sed -i '/^openssl_conf = openssl_init/a \\n[openssl_init]\nproviders = provider_sect\n' $OPENSSL_CNF
        fi

        # Agregar [provider_sect]
        if ! grep -q "^\[provider_sect\]" $OPENSSL_CNF; then
            echo -e "\n[provider_sect]\ndefault = default_sect\nlegacy = legacy_sect\n" >> $OPENSSL_CNF
        fi

        # Agregar [default_sect]
        if ! grep -q "^\[default_sect\]" $OPENSSL_CNF; then
            echo -e "[default_sect]\nactivate = 1\n" >> $OPENSSL_CNF
        fi

        # Agregar [legacy_sect]
        if ! grep -q "^\[legacy_sect\]" $OPENSSL_CNF; then
            echo -e "[legacy_sect]\nactivate = 1" >> $OPENSSL_CNF
        fi

        print_success "OpenSSL legacy configurado"
    fi

    # Verificar providers
    print_info "Verificando providers de OpenSSL..."
    if openssl list -providers 2>/dev/null | grep -q "legacy"; then
        print_success "Provider legacy activado correctamente"
    else
        print_warning "Provider legacy configurado (se cargará al usar OpenSSL)"
    fi
else
    print_success "OpenSSL $OPENSSL_VERSION no requiere legacy provider"
fi

#===========================================================================================================
# CONFIGURACIÓN LARAVEL
#===========================================================================================================

print_step "Configurando Aplicación Laravel"

# Generar clave si no existe
print_info "Generando clave de aplicación..."
php "$APIDIAN_DIR/artisan" key:generate --force 2>/dev/null
print_success "Clave de aplicación generada"

# Limpiar cache
print_info "Limpiando cache..."
$PHP_BIN "$APIDIAN_DIR/artisan" config:clear 2>/dev/null
$PHP_BIN "$APIDIAN_DIR/artisan" cache:clear 2>/dev/null
$PHP_BIN "$APIDIAN_DIR/artisan" route:cache 2>/dev/null
$PHP_BIN "$APIDIAN_DIR/artisan" view:cache 2>/dev/null
print_success "Cache limpiado"

# Ejecutar migraciones
print_info "Ejecutando migraciones de base de datos..."
if $PHP_BIN "$APIDIAN_DIR/artisan" migrate --force 2>/dev/null; then
    print_success "Migraciones ejecutadas correctamente"
else
    print_warning "Algunas migraciones no se ejecutaron (pueden no ser necesarias)"
fi

# Configurar permisos correctos
print_info "Configurando permisos y propietario..."

# Detectar usuario del servidor web
WEB_USER="www-data"
if id "nginx" &>/dev/null 2>&1; then
    WEB_USER="nginx"
fi

# Cambiar propietario de todo el directorio al usuario del servidor web
chown -R $WEB_USER:$WEB_USER "$APIDIAN_DIR" 2>/dev/null
print_success "Propietario actualizado a $WEB_USER"

# Configurar permisos para storage
if [ -d "$APIDIAN_DIR/storage" ]; then
    chmod -R 775 "$APIDIAN_DIR/storage"
    chown -R $WEB_USER:$WEB_USER "$APIDIAN_DIR/storage"
    print_success "Permisos de storage configurados (775)"
fi

# Configurar permisos para bootstrap/cache
if [ -d "$APIDIAN_DIR/bootstrap/cache" ]; then
    chmod -R 775 "$APIDIAN_DIR/bootstrap/cache"
    chown -R $WEB_USER:$WEB_USER "$APIDIAN_DIR/bootstrap/cache"
    print_success "Permisos de bootstrap/cache configurados (775)"
fi

#===========================================================================================================
# REINICIAR SERVIDOR WEB
#===========================================================================================================

print_step "Reiniciando Servidor Web"

# Detectar y reiniciar el servidor web
if systemctl is-active --quiet apache2; then
    print_info "Reiniciando Apache2..."
    systemctl restart apache2
    if systemctl is-active --quiet apache2; then
        print_success "Apache2 reiniciado correctamente"
    else
        print_error "Error al reiniciar Apache2"
    fi
elif systemctl is-active --quiet nginx; then
    print_info "Reiniciando Nginx..."
    systemctl restart nginx
    systemctl restart php${PHP_VERSION}-fpm 2>/dev/null || systemctl restart php-fpm 2>/dev/null || true
    if systemctl is-active --quiet nginx; then
        print_success "Nginx reiniciado correctamente"
    else
        print_error "Error al reiniciar Nginx"
    fi
else
    print_warning "No se detectó Apache2 ni Nginx activo"
    print_info "Intenta reiniciar manualmente: systemctl restart apache2 o systemctl restart nginx"
fi

#===========================================================================================================
# VERIFICACIÓN FINAL
#===========================================================================================================

print_step "Verificación Final"

echo -e "${CYAN}Estado de la Actualización:${NC}"
echo ""

# Verificar que Git está en el nuevo repositorio
FINAL_REPO=$(cd "$APIDIAN_DIR" && git config --get remote.origin.url 2>/dev/null)
if [[ "$FINAL_REPO" == *"apidian-laravel-8-s3"* ]] || [[ "$FINAL_REPO" == *"apidian-laravel-8"* ]]; then
    FINAL_BRANCH=$(cd "$APIDIAN_DIR" && git rev-parse --abbrev-ref HEAD 2>/dev/null)
    echo -e "  ${GREEN}✓${NC} Repositorio Git: Actualizado (rama: $FINAL_BRANCH)"
else
    echo -e "  ${YELLOW}⚠${NC} Repositorio Git: $FINAL_REPO"
fi

# Verificar composer
if command -v composer &> /dev/null; then
    COMPOSER_VER=$(timeout 5 composer --version 2>/dev/null | head -n1 || echo "Instalado (versión no disponible)")
    echo -e "  ${GREEN}✓${NC} Composer: $COMPOSER_VER"
else
    echo -e "  ${RED}✗${NC} Composer: No instalado"
fi

# Verificar PHP
if command -v php &> /dev/null; then
    PHP_VER=$(timeout 3 php -v 2>/dev/null | head -n1 | cut -d' ' -f2 || echo "Instalado")
    echo -e "  ${GREEN}✓${NC} PHP: $PHP_VER"
else
    echo -e "  ${RED}✗${NC} PHP: No instalado"
fi

# Verificar archivo .env
if [ -f "$APIDIAN_DIR/.env" ]; then
    echo -e "  ${GREEN}✓${NC} Archivo .env: Presente"
else
    echo -e "  ${RED}✗${NC} Archivo .env: Faltante"
fi

# Verificar artisan
if [ -f "$APIDIAN_DIR/artisan" ]; then
    echo -e "  ${GREEN}✓${NC} Artisan: Accesible"
else
    echo -e "  ${RED}✗${NC} Artisan: No encontrado"
fi

echo ""

#===========================================================================================================
# RESUMEN Y SIGUIENTE PASOS
#===========================================================================================================

print_step "Resumen de la Actualización"

echo -e "${CYAN}${BOLD}Cambios Realizados:${NC}"
echo "  • Cambio de repositorio Git a versión 2025"
echo "  • Descarga de nuevo código fuente"
echo "  • Actualización de dependencias Composer"
echo "  • Ejecución de migraciones de base de datos"
echo "  • Limpieza de cache y optimización"
if [ "$OPENSSL_MAJOR" -ge 3 ]; then
    echo "  • Configuración de OpenSSL legacy provider"
fi
echo ""

echo -e "${CYAN}${BOLD}Ubicación de Backups:${NC}"
echo "  $BACKUP_DIR"
echo ""

echo -e "${CYAN}${BOLD}Siguientes Pasos Recomendados:${NC}"
echo "  1. Verificar que la aplicación funciona correctamente"
echo "  2. Revisar el archivo .env con las nuevas configuraciones"
echo "  3. Acceder a: http://$(hostname -I | awk '{print $1}')"
echo "  4. Si algo falla, usar los backups en: $BACKUP_DIR"
echo ""

print_success "Actualización completada exitosamente"

echo -e "${BLUE}Para más información o soporte, contacta a TorreSoftware${NC}"
echo ""
