#!/bin/bash

#-------------------------------------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}     Instalación / Renovación de Certificados SSL${NC}${CYAN}             ║${NC}"
    echo -e "${CYAN}║  ${BLUE}     Let's Encrypt - Certificado Wildcard (*.dominio)${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}"
}

print_header

#-------------------------------------VERIFICAR ROOT------------------------------------------------------------
if [ "$EUID" -ne 0 ]; then
    print_error "Este script debe ejecutarse como root"
    echo -e "${YELLOW}Usa: sudo bash $0 tu-dominio.com [subdominio-api]${NC}"
    exit 1
fi

print_success "Ejecutando como root"

# Información del sistema
UBUNTU_VERSION=$(lsb_release -rs)
print_info "Sistema: Ubuntu $UBUNTU_VERSION"

# Verificar versión de Ubuntu soportada
UBUNTU_MAJOR=$(echo "$UBUNTU_VERSION" | cut -d. -f1)

if [[ "$UBUNTU_MAJOR" -lt 20 ]]; then
    print_error "APIDIAN 2026 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"
    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 instalación de SSL (compatibilidad parcial)"
fi

print_success "Versión de Ubuntu compatible"

#-------------------------------------PARAMETRO OBLIGATORIO------------------------------------------------------------
HOST=${1:-'dominio'}
if [ "$HOST" = "dominio" ]; then
    print_error "No has ingresado el dominio"
    echo -e "${YELLOW}Uso: sudo bash $0 tu-dominio.com [subdominio-api]${NC}"
    echo -e "${CYAN}Ejemplo: sudo bash $0 miempresa.com api${NC}"
    echo ""
    echo -e "${BLUE}El subdominio API es opcional (por defecto: 'api')${NC}"
    exit 1
fi

print_success "Dominio configurado: ${BOLD}$HOST${NC}"

#-------------------------------------RUTA DE INSTALACION--------------------------------------------------------------
PATH_CURRENT=$(pwd)
DIR_API='apidian'
DIR_FACTURADOR='pro2'

#-------------------------------------VERIFICAR APLICACIONES INSTALADAS------------------------------------------------
print_step "Verificando aplicaciones instaladas"

API_INSTALLED=false
FACTURADOR_INSTALLED=false
DETECTED_SUBDOMAIN=""

if [ -d "$PATH_CURRENT/$DIR_API" ] && [ -f "$PATH_CURRENT/$DIR_API/.env" ]; then
    API_INSTALLED=true
    print_success "Aplicación API detectada en: $PATH_CURRENT/$DIR_API"

    # Detectar subdominio desde APP_URL en .env
    if grep -q "^APP_URL=" "$PATH_CURRENT/$DIR_API/.env"; then
        APP_URL=$(grep "^APP_URL=" "$PATH_CURRENT/$DIR_API/.env" | cut -d '=' -f2)
        # Extraer subdominio de la URL (ejemplo: http://apidian.sufacturae.com -> apidian)
        DETECTED_SUBDOMAIN=$(echo "$APP_URL" | sed 's|https\?://||' | sed 's|http://||' | cut -d '.' -f1)
        if [ -n "$DETECTED_SUBDOMAIN" ] && [ "$DETECTED_SUBDOMAIN" != "$HOST" ]; then
            print_info "Subdominio detectado desde .env: ${BOLD}$DETECTED_SUBDOMAIN${NC}"
        fi
    fi
else
    print_warning "Aplicación API no encontrada en: $PATH_CURRENT/$DIR_API"
fi

if [ -d "$PATH_CURRENT/$DIR_FACTURADOR" ] && [ -f "$PATH_CURRENT/$DIR_FACTURADOR/.env" ]; then
    FACTURADOR_INSTALLED=true
    print_success "Aplicación Facturador detectada en: $PATH_CURRENT/$DIR_FACTURADOR"
else
    print_info "Aplicación Facturador no encontrada (opcional)"
fi

if [ "$API_INSTALLED" = false ] && [ "$FACTURADOR_INSTALLED" = false ]; then
    print_error "No se encontró ninguna aplicación instalada"
    print_info "Asegúrate de ejecutar este script desde el directorio raíz de instalación"
    exit 1
fi

#-------------------------------------CONFIGURAR SUBDOMINIO API--------------------------------------------------------
# Prioridad: 1) Parámetro manual, 2) Detectado desde .env, 3) Por defecto 'api'
if [ -n "$2" ]; then
    API_SUBDOMAIN="$2"
    print_success "Subdominio API (manual): ${BOLD}$API_SUBDOMAIN.$HOST${NC}"
elif [ -n "$DETECTED_SUBDOMAIN" ]; then
    API_SUBDOMAIN="$DETECTED_SUBDOMAIN"
    print_success "Subdominio API (auto-detectado): ${BOLD}$API_SUBDOMAIN.$HOST${NC}"
else
    API_SUBDOMAIN="api"
    print_info "Subdominio API (por defecto): ${BOLD}$API_SUBDOMAIN.$HOST${NC}"
fi

#-------------------------------------VERIFICAR DOCKER-COMPOSE---------------------------------------------------------
if ! command -v docker-compose &> /dev/null; then
    print_error "Docker Compose no está instalado"
    exit 1
fi

print_success "Docker Compose detectado"

#-------------------------------------VERIFICAR CERTBOT----------------------------------------------------------------
if ! command -v certbot &> /dev/null; then
    print_warning "Certbot no está instalado, instalando..."
    apt-get update > /dev/null 2>&1
    apt-get install -y letsencrypt > /dev/null 2>&1
    print_success "Certbot instalado"
else
    print_success "Certbot detectado"
fi

#-------------------------------------CREAR DIRECTORIOS SI NO EXISTEN--------------------------------------------------
mkdir -p "$PATH_CURRENT/setup/certs"
print_success "Directorio de certificados verificado"

#-------------------------------------INSTALACION SSL------------------------------------------------------------------
echo ""
echo -e "${CYAN}${BOLD}╭─────────────────────────────────────────────────────────╮${NC}"
echo -e "${CYAN}${BOLD}│  🔒  Instalación de Certificado SSL                     │${NC}"
echo -e "${CYAN}${BOLD}╰─────────────────────────────────────────────────────────╯${NC}"
echo ""

read -p "$(echo -e ${YELLOW}¿Deseas instalar/renovar certificado SSL con Let\'s Encrypt? [s/n]: ${NC})" ssl

if [ "$ssl" != "s" ]; then
    print_info "Instalación SSL cancelada"
    exit 0
fi

print_step "Instalando certificado SSL"
print_warning "IMPORTANTE: Asegúrate de que el DNS apunte correctamente al servidor"
echo ""
echo -e "${YELLOW}${BOLD}⚠️  NOTA IMPORTANTE SOBRE RENOVACIÓN AUTOMÁTICA:${NC}"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${YELLOW}El método DNS manual NO permite renovación automática.${NC}"
echo -e "${YELLOW}Deberás repetir este proceso cada 90 días (recibirás email).${NC}"
echo -e "${YELLOW}Los registros TXT son de un solo uso, no los guardes.${NC}"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e "${YELLOW}┌───────────────────────────────────────────────────────┐${NC}"
echo -e "${YELLOW}│ ${BOLD}INSTRUCCIONES:${NC}${YELLOW}                                        │${NC}"
echo -e "${YELLOW}├───────────────────────────────────────────────────────┤${NC}"
echo -e "${YELLOW}│ 1. Copiar los 2 registros TXT que aparezcan           │${NC}"
echo -e "${RED}${BOLD}│ 2. NO usar [Ctrl+C] ya que cancelará el proceso       │${NC}"
echo -e "${YELLOW}│ 3. Ingresar tu correo electrónico                     │${NC}"
echo -e "${YELLOW}│ 4. Aceptar los términos y condiciones                 │${NC}"
echo -e "${YELLOW}│ 5. Los registros TXT son temporales (no permanentes)  │${NC}"
echo -e "${YELLOW}└───────────────────────────────────────────────────────┘${NC}"
echo ""

certbot certonly --manual -d *.$HOST -d $HOST --agree-tos --no-bootstrap --manual-public-ip-logging-ok --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory

print_info "Verificando certificados generados..."

if ! [ -f /etc/letsencrypt/live/$HOST/privkey.pem ]; then
    print_error "No se ha generado el certificado SSL"
    print_warning "Verifica que los registros DNS TXT se hayan propagado correctamente"
    exit 1
fi

print_success "Certificado SSL generado exitosamente"

#-------------------------------------COPIAR CERTIFICADOS--------------------------------------------------------------
print_step "Copiando certificados a directorio de configuración"

cp /etc/letsencrypt/live/$HOST/privkey.pem $PATH_CURRENT/setup/certs/$HOST.key
cp /etc/letsencrypt/live/$HOST/fullchain.pem $PATH_CURRENT/setup/certs/$HOST.crt

print_success "Certificados copiados a: $PATH_CURRENT/setup/certs/"

#-------------------------------------CONFIGURAR APLICACION API--------------------------------------------------------
if [ "$API_INSTALLED" = true ]; then
    print_step "Configurando aplicación API para HTTPS"

    cd "$PATH_CURRENT/$DIR_API"

    print_info "Actualizando configuración .env..."
    sed -i "/APP_URL=/c\APP_URL=https://$API_SUBDOMAIN.$HOST" .env
    sed -i '/FORCE_HTTPS=/c\FORCE_HTTPS=true' .env

    print_success "Configuración .env actualizada"

    print_info "Limpiando caché de Laravel..."
    docker-compose exec -T php_api php artisan config:cache > /dev/null 2>&1
    docker-compose exec -T php_api php artisan cache:clear > /dev/null 2>&1

    print_success "Aplicación API configurada para HTTPS"
fi

#-------------------------------------CONFIGURAR APLICACION FACTURADOR-------------------------------------------------
if [ "$FACTURADOR_INSTALLED" = true ]; then
    print_step "Configurando aplicación Facturador para HTTPS"

    cd "$PATH_CURRENT/$DIR_FACTURADOR"

    # Obtener APP_URL_BASE del .env actual o usar dominio por defecto
    APP_URL_BASE=$(grep "^APP_URL=" .env | cut -d '=' -f2 | sed 's/http:\/\///' | sed 's/https:\/\///')
    if [ -z "$APP_URL_BASE" ]; then
        APP_URL_BASE="$HOST"
    fi

    print_info "Actualizando configuración .env..."
    sed -i "/APP_URL=/c\APP_URL=https://$APP_URL_BASE" .env
    sed -i '/FORCE_HTTPS=/c\FORCE_HTTPS=true' .env

    # Actualizar URL del servicio API si existe
    if grep -q "SERVICE_FACT=" .env; then
        sed -i "/SERVICE_FACT=/c\SERVICE_FACT=https://$API_SUBDOMAIN.$HOST/api/" .env
        print_success "URL del servicio API actualizada"
    fi

    print_success "Configuración .env actualizada"

    print_info "Limpiando caché de Laravel..."
    docker-compose exec -T fpm_app php artisan config:cache > /dev/null 2>&1
    docker-compose exec -T fpm_app php artisan cache:clear > /dev/null 2>&1

    print_success "Aplicación Facturador configurada para HTTPS"
fi

#-------------------------------------REINICIAR SERVICIOS--------------------------------------------------------------
print_step "Reiniciando servicios para aplicar cambios"

cd "$PATH_CURRENT"

print_info "Reiniciando proxy y nginx..."
docker-compose restart proxy nginx_api > /dev/null 2>&1
sleep 5

print_success "Servicios reiniciados correctamente"

#-------------------------------------VERIFICACION FINAL---------------------------------------------------------------
print_step "Verificación de instalación"

echo -e "${BLUE}📋 Resumen de configuración:${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}✓ Dominio:${NC} $HOST"
echo -e "${GREEN}✓ Certificados:${NC} /etc/letsencrypt/live/$HOST/"
echo -e "${GREEN}✓ Certificados copiados:${NC} $PATH_CURRENT/setup/certs/"

if [ "$API_INSTALLED" = true ]; then
    echo -e "${GREEN}✓ API configurada:${NC} https://$API_SUBDOMAIN.$HOST"
fi

if [ "$FACTURADOR_INSTALLED" = true ]; then
    APP_URL_BASE=$(grep "^APP_URL=" "$PATH_CURRENT/$DIR_FACTURADOR/.env" | cut -d '=' -f2 | sed 's/http:\/\///' | sed 's/https:\/\///')
    echo -e "${GREEN}✓ Facturador configurado:${NC} https://$APP_URL_BASE"
fi

echo -e "${RED}⚠ Renovación:${NC} ${BOLD}MANUAL cada 90 días${NC} (método DNS manual)"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
echo -e "${YELLOW}${BOLD}📧 IMPORTANTE - Renovación de Certificados:${NC}"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${YELLOW}• El método DNS manual NO permite renovación automática${NC}"
echo -e "${YELLOW}• Recibirás emails 30 días antes de que expire (26 Feb 2026)${NC}"
echo -e "${YELLOW}• Para renovar: ejecuta nuevamente este script${NC}"
echo -e "${YELLOW}• Los registros TXT serán DIFERENTES en cada renovación${NC}"
echo -e "${YELLOW}• NO guardes los registros TXT actuales, son de un solo uso${NC}"
echo -e "${YELLOW}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""

# Verificar conectividad
if [ "$API_INSTALLED" = true ]; then
    print_info "Verificando acceso HTTPS a API..."
    sleep 3
    HTTP_CODE=$(curl -k -s -o /dev/null -w "%{http_code}" https://$API_SUBDOMAIN.$HOST 2>/dev/null || echo "000")
    if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "302" ] || [ "$HTTP_CODE" = "301" ]; then
        print_success "Sitio web API accesible (HTTPS $HTTP_CODE)"
    else
        print_warning "API no responde inmediatamente (puede necesitar 1-2 minutos)"
        print_info "Si persiste, ejecuta: docker-compose restart"
    fi
fi

echo ""
echo -e "${GREEN}${BOLD}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}${BOLD}║                                                               ║${NC}"
echo -e "${GREEN}${BOLD}║  ✓  CERTIFICADOS SSL INSTALADOS EXITOSAMENTE                  ║${NC}"
echo -e "${GREEN}${BOLD}║                                                               ║${NC}"
echo -e "${GREEN}${BOLD}╚═══════════════════════════════════════════════════════════════╝${NC}"
echo ""

echo -e "${CYAN}${BOLD}📅 Para renovar (antes del 26 Feb 2026):${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}1.${NC} Ejecuta: ${BOLD}sudo bash InstallSSL.sh $HOST${NC}"
echo -e "${GREEN}2.${NC} Copia los nuevos registros TXT (serán diferentes)"
echo -e "${GREEN}3.${NC} El proceso es el mismo que esta instalación"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
print_info "Certbot enviará emails recordatorios a: nomail@nomail.com"
print_warning "El script de renovación automática NO funcionará con método DNS manual"
echo ""
