#!/usr/bin/env bash
# ==============================================================================
# KutStudio - Instalador Profesional para VPS (Debian / Ubuntu)
# ==============================================================================
# Automatiza el endurecimiento de seguridad (SSH, Firewall UFW, Fail2ban,
# parámetros de kernel Sysctl, actualizaciones desatendidas) y despliega el
# stack web completo (Nginx, PHP 8.3 FPM, Certbot SSL, SQLite, FFmpeg) junto
# con las aplicaciones de KutStudio:
#   - KutPod    (Servidor de Podcasts Federado · ActivityPub · OP3)
#   - KutFast   (Grabación y Transmisión Rápida de Episodios · PWA)
#   - KutBlog   (CMS Flat-File Ágil · Editor Triple · Comentarios Mastodon)
#   - KutSocial (Nodo de Microblogging Federado · ActivityPub · Mastodon API)
# ==============================================================================

set -uo pipefail

# ── Colores y Formato ─────────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
BOLD='\033[1m'
DIM='\033[2m'
RESET='\033[0m'

LOG_FILE="/var/log/kutstudio_installer.log"
SUMMARY_FILE="/root/kutstudio_install_summary.txt"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# ── Funciones de Salida ───────────────────────────────────────────────────────
log() {
    if [[ -w "$LOG_FILE" || ( ! -e "$LOG_FILE" && -w "$(dirname "$LOG_FILE" 2>/dev/null)" ) ]]; then
        local level="$1"
        shift
        local msg="$*"
        local timestamp
        timestamp="$(date '+%Y-%m-%d %H:%M:%S')"
        echo "[$timestamp] [$level] $msg" >> "$LOG_FILE" 2>/dev/null || true
    fi
}

msg_info() {
    echo -e "${CYAN}ℹ  $*${RESET}"
    log "INFO" "$*"
}

msg_success() {
    echo -e "${GREEN}✓  $*${RESET}"
    log "SUCCESS" "$*"
}

msg_warn() {
    echo -e "${YELLOW}⚠  $*${RESET}"
    log "WARN" "$*"
}

msg_error() {
    echo -e "${RED}✖  $*${RESET}" >&2
    log "ERROR" "$*"
}

msg_step() {
    echo ""
    echo -e "${PURPLE}${BOLD}──▶  $*${RESET}"
    echo -e "${DIM}------------------------------------------------------------${RESET}"
    log "STEP" "$*"
}

banner() {
    clear 2>/dev/null || true
    echo -e "${CYAN}${BOLD}"
    cat << "EOF"
  _  __      _   ____  _             _ _       
 | |/ /_   _| |_/ ___|| |_ _   _  __| (_) ___  
 | ' /| | | | __\___ \| __| | | |/ _` | |/ _ \ 
 | . \| |_| | |_ ___) | |_| |_| | (_| | | (_) |
 |_|\_\\__,_|\__|____/ \__|\__,_|\__,_|_|\___/  
        INSTALADOR PROFESIONAL PARA VPS
EOF
    echo -e "${RESET}"
    echo -e "${DIM}  Endurecimiento de Seguridad + Nginx + PHP 8.3 + KutApps${RESET}"
    echo -e "${DIM}  Versión: 2.5 · Compatible con Debian 11/12/13 y Ubuntu 20/22/24${RESET}"
    echo "============================================================"
    echo ""
}

# ── Ayuda y Uso ───────────────────────────────────────────────────────────────
show_help() {
    cat << EOF
Uso: sudo ./kutstudio_installer.sh [OPCIONES]

Instalador automatizado para desplegar la suite KutStudio en un VPS con Ubuntu o Debian.

Opciones:
  -h, --help       Muestra esta pantalla de ayuda y sale.

El script te guiará paso a paso para:
  1. Configurar la seguridad (Cambio de puerto SSH, UFW Firewall, Fail2ban, Sysctl).
  2. Instalar el stack de software (Nginx, PHP 8.3 FPM, Certbot SSL, FFmpeg, SQLite).
  3. Desplegar e inicializar las aplicaciones elegidas:
     - KutPod    (pod.tudominio.com)
     - KutFast   (fast.tudominio.com)
     - KutBlog   (blog.tudominio.com)
     - KutSocial (social.tudominio.com)
  4. Generar certificados SSL automáticos con Let's Encrypt.
EOF
    exit 0
}

# ── Verificación de Privilegios y Sistema ─────────────────────────────────────
check_environment() {
    if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
        msg_error "Este script debe ejecutarse con privilegios de root (ejecuta: sudo $0)."
        exit 1
    fi

    # Crear archivo de log inicial
    touch "$LOG_FILE" 2>/dev/null || true
    chmod 600 "$LOG_FILE" 2>/dev/null || true

    if [[ ! -f /etc/os-release ]]; then
        msg_error "No se pudo identificar la distribución del sistema operativo (/etc/os-release no encontrado)."
        exit 1
    fi

    # shellcheck disable=SC1091
    source /etc/os-release
    OS_ID="${ID:-unknown}"
    OS_VERSION_ID="${VERSION_ID:-unknown}"

    if [[ "$OS_ID" != "debian" && "$OS_ID" != "ubuntu" ]]; then
        msg_warn "Distribución detectada: $OS_ID $OS_VERSION_ID."
        msg_warn "Este instalador está optimizado para Ubuntu y Debian. ¿Deseas continuar de todas formas? (s/N)"
        read -r cont
        if [[ ! "$cont" =~ ^[sS]$ ]]; then
            msg_error "Instalación cancelada."
            exit 1
        fi
    else
        msg_info "Sistema operativo validado: ${NAME:-Linux} ${VERSION:-} ($OS_ID $OS_VERSION_ID)"
    fi
}

# ── Asistente de Configuración Interactivo ───────────────────────────────────
run_wizard() {
    banner

    # 1. Seguridad y SSH
    msg_step "1/4. Configuración de Seguridad y Acceso SSH"
    
    # Detección del puerto SSH actual
    CURRENT_SSH_PORT=$(sshd -T 2>/dev/null | grep -i '^port ' | awk '{print $2}' || true)
    [[ -z "$CURRENT_SSH_PORT" ]] && CURRENT_SSH_PORT=22

    echo -e "El puerto SSH actual es: ${BOLD}${CURRENT_SSH_PORT}${RESET}"
    echo -e "Cambiar el puerto por defecto (22) ayuda a mitigar el 99% del escaneo automatizado por bots."
    read -rp "Ingresa el nuevo puerto SSH [Presiona Enter para mantener $CURRENT_SSH_PORT]: " INPUT_SSH_PORT
    SSH_PORT="${INPUT_SSH_PORT:-$CURRENT_SSH_PORT}"

    # Validar número de puerto
    while ! [[ "$SSH_PORT" =~ ^[0-9]+$ ]] || [ "$SSH_PORT" -lt 1 ] || [ "$SSH_PORT" -gt 65535 ]; do
        msg_warn "Puerto inválido. Debe ser un número entre 1 y 65535."
        read -rp "Ingresa el puerto SSH [$CURRENT_SSH_PORT]: " INPUT_SSH_PORT
        SSH_PORT="${INPUT_SSH_PORT:-$CURRENT_SSH_PORT}"
    done

    # Acceso Root
    echo ""
    echo -e "Configuración de inicio de sesión de root en SSH:"
    echo -e "  [1] prohibit-password (Permitir solo con Llave SSH - ${GREEN}Recomendado${RESET})"
    echo -e "  [2] yes (Permitir root con contraseña y llave)"
    echo -e "  [3] no (Deshabilitar completamente el acceso directo como root)"
    read -rp "Selecciona una opción [1]: " ROOT_OPT
    case "$ROOT_OPT" in
        2) ROOT_LOGIN_VAL="yes" ;;
        3) ROOT_LOGIN_VAL="no" ;;
        *) ROOT_LOGIN_VAL="prohibit-password" ;;
    esac

    # Autenticación por contraseña
    PASS_AUTH_VAL="yes"
    if [[ -f /root/.ssh/authorized_keys ]] && [[ -s /root/.ssh/authorized_keys ]]; then
        echo ""
        echo -e "${GREEN}✓ Se detectó llave SSH configurada en /root/.ssh/authorized_keys.${RESET}"
        read -rp "¿Deseas desactivar la autenticación por contraseña para máxima seguridad? (s/N): " DISABLE_PW
        if [[ "$DISABLE_PW" =~ ^[sS]$ ]]; then
            PASS_AUTH_VAL="no"
        fi
    fi

    # Opciones de Firewall y Defensas
    echo ""
    msg_info "Opciones de defensa perimetral:"
    ENABLE_UFW=true
    ENABLE_FAIL2BAN=true
    ENABLE_SYSCTL_HARDENING=true
    ENABLE_AUTO_UPDATES=true
    echo -e "  ✓ UFW Firewall (Cierra todo y abre únicamente SSH: $SSH_PORT, HTTP: 80, HTTPS: 443)"
    echo -e "  ✓ Fail2ban (Protección contra fuerza bruta en SSH y sondas maliciosas en Nginx)"
    echo -e "  ✓ Sysctl Hardening (Protección contra SYN floods, Spoofing de IP y paquetes malformados)"
    echo -e "  ✓ Unattended Upgrades (Actualizaciones automáticas de parches de seguridad de Linux)"

    # 2. Selección de Aplicaciones
    msg_step "2/4. Selección de Productos KutStudio"
    echo -e "Elige qué aplicaciones deseas instalar en este VPS:"
    echo -e "  ${BOLD}[1] Instalar Suite Completa (KutPod + KutFast + KutBlog + KutSocial) [Recomendado]${RESET}"
    echo -e "  [2] KutPod    - Servidor de Podcasts Federado (ActivityPub + OP3 Tracker + Audio CDN)"
    echo -e "  [3] KutFast   - Transmisión, Edición Ligera y Grabación Rápida de Episodios (PWA)"
    echo -e "  [4] KutBlog   - CMS Flat-File Ultrarrápido (Editor Markdown/WYSIWYG + Comentarios Mastodon)"
    echo -e "  [5] KutSocial - Nodo de Microblogging Federado (ActivityPub + Mastodon API + Web SPA)"
    echo -e "  [6] Personalizado (Seleccionar uno a uno)"
    read -rp "Selecciona una opción [1]: " APP_CHOICE

    INSTALL_KUTPOD=false
    INSTALL_KUTFAST=false
    INSTALL_KUTBLOG=false
    INSTALL_KUTSOCIAL=false

    case "$APP_CHOICE" in
        2) INSTALL_KUTPOD=true ;;
        3) INSTALL_KUTFAST=true ;;
        4) INSTALL_KUTBLOG=true ;;
        5) INSTALL_KUTSOCIAL=true ;;
        6)
            read -rp "¿Instalar KutPod? (s/N): " q_kp
            [[ "$q_kp" =~ ^[sS]$ ]] && INSTALL_KUTPOD=true
            read -rp "¿Instalar KutFast? (s/N): " q_kf
            [[ "$q_kf" =~ ^[sS]$ ]] && INSTALL_KUTFAST=true
            read -rp "¿Instalar KutBlog? (s/N): " q_kb
            [[ "$q_kb" =~ ^[sS]$ ]] && INSTALL_KUTBLOG=true
            read -rp "¿Instalar KutSocial? (s/N): " q_ks
            [[ "$q_ks" =~ ^[sS]$ ]] && INSTALL_KUTSOCIAL=true
            ;;
        *)
            INSTALL_KUTPOD=true
            INSTALL_KUTFAST=true
            INSTALL_KUTBLOG=true
            INSTALL_KUTSOCIAL=true
            ;;
    esac

    if ! $INSTALL_KUTPOD && ! $INSTALL_KUTFAST && ! $INSTALL_KUTBLOG && ! $INSTALL_KUTSOCIAL; then
        msg_error "No se seleccionó ninguna aplicación para instalar."
        exit 1
    fi

    # 3. Dominios y Credenciales
    msg_step "3/4. Configuración de Dominios y Credenciales"
    echo -e "${YELLOW}Nota:${RESET} Para que la federación de ActivityPub y los certificados SSL funcionen"
    echo -e "correctamente, cada servicio debe contar con un dominio o subdominio apuntado a este VPS."
    echo ""

    KUTPOD_DOMAIN=""
    KUTFAST_DOMAIN=""
    KUTBLOG_DOMAIN=""
    KUTSOCIAL_DOMAIN=""

    if $INSTALL_KUTPOD; then
        read -rp "Dominio para KutPod (ej. pod.tudominio.com): " KUTPOD_DOMAIN
        while [[ -z "$KUTPOD_DOMAIN" ]]; do
            msg_warn "El dominio para KutPod es obligatorio."
            read -rp "Dominio para KutPod: " KUTPOD_DOMAIN
        done
        KUTPOD_DOMAIN="${KUTPOD_DOMAIN#https://}"
        KUTPOD_DOMAIN="${KUTPOD_DOMAIN#http://}"
        KUTPOD_DOMAIN="${KUTPOD_DOMAIN%/}"
    fi

    if $INSTALL_KUTFAST; then
        read -rp "Dominio para KutFast (ej. fast.tudominio.com): " KUTFAST_DOMAIN
        while [[ -z "$KUTFAST_DOMAIN" ]]; do
            msg_warn "El dominio para KutFast es obligatorio."
            read -rp "Dominio para KutFast: " KUTFAST_DOMAIN
        done
        KUTFAST_DOMAIN="${KUTFAST_DOMAIN#https://}"
        KUTFAST_DOMAIN="${KUTFAST_DOMAIN#http://}"
        KUTFAST_DOMAIN="${KUTFAST_DOMAIN%/}"
    fi

    if $INSTALL_KUTBLOG; then
        read -rp "Dominio para KutBlog (ej. blog.tudominio.com): " KUTBLOG_DOMAIN
        while [[ -z "$KUTBLOG_DOMAIN" ]]; do
            msg_warn "El dominio para KutBlog es obligatorio."
            read -rp "Dominio para KutBlog: " KUTBLOG_DOMAIN
        done
        KUTBLOG_DOMAIN="${KUTBLOG_DOMAIN#https://}"
        KUTBLOG_DOMAIN="${KUTBLOG_DOMAIN#http://}"
        KUTBLOG_DOMAIN="${KUTBLOG_DOMAIN%/}"
    fi

    if $INSTALL_KUTSOCIAL; then
        read -rp "Dominio para KutSocial (ej. social.tudominio.com): " KUTSOCIAL_DOMAIN
        while [[ -z "$KUTSOCIAL_DOMAIN" ]]; do
            msg_warn "El dominio para KutSocial es obligatorio."
            read -rp "Dominio para KutSocial: " KUTSOCIAL_DOMAIN
        done
        KUTSOCIAL_DOMAIN="${KUTSOCIAL_DOMAIN#https://}"
        KUTSOCIAL_DOMAIN="${KUTSOCIAL_DOMAIN#http://}"
        KUTSOCIAL_DOMAIN="${KUTSOCIAL_DOMAIN%/}"
    fi

    echo ""
    read -rp "Correo electrónico del Administrador (para SSL Let's Encrypt y avisos): " ADMIN_EMAIL
    while [[ -z "$ADMIN_EMAIL" || ! "$ADMIN_EMAIL" =~ ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]]; do
        msg_warn "Ingresa un email válido (ej. admin@tudominio.com)."
        read -rp "Correo electrónico del Administrador: " ADMIN_EMAIL
    done

    # Contraseña maestra de administración
    echo ""
    echo -e "Establece la contraseña de Administrador para las aplicaciones:"
    while true; do
        read -rsp "Contraseña (mínimo 8 caracteres): " ADMIN_PASS
        echo ""
        if [ ${#ADMIN_PASS} -lt 8 ]; then
            msg_warn "La contraseña debe tener al menos 8 caracteres."
            continue
        fi
        read -rsp "Confirma la contraseña: " ADMIN_PASS_CONFIRM
        echo ""
        if [ "$ADMIN_PASS" != "$ADMIN_PASS_CONFIRM" ]; then
            msg_warn "Las contraseñas no coinciden. Intenta de nuevo."
        else
            break
        fi
    done

    # 4. Confirmación
    msg_step "4/4. Resumen y Confirmación"
    echo -e "  Puerto SSH:             ${BOLD}${SSH_PORT}${RESET}"
    echo -e "  Root SSH:               ${BOLD}${ROOT_LOGIN_VAL}${RESET}"
    echo -e "  Password Auth SSH:      ${BOLD}${PASS_AUTH_VAL}${RESET}"
    echo -e "  Email Admin:            ${BOLD}${ADMIN_EMAIL}${RESET}"
    if $INSTALL_KUTPOD; then echo -e "  KutPod:                 ${GREEN}Sí${RESET} (https://${KUTPOD_DOMAIN})"; fi
    if $INSTALL_KUTFAST; then echo -e "  KutFast:                ${GREEN}Sí${RESET} (https://${KUTFAST_DOMAIN})"; fi
    if $INSTALL_KUTBLOG; then echo -e "  KutBlog:                ${GREEN}Sí${RESET} (https://${KUTBLOG_DOMAIN})"; fi
    if $INSTALL_KUTSOCIAL; then echo -e "  KutSocial:              ${GREEN}Sí${RESET} (https://${KUTSOCIAL_DOMAIN})"; fi
    echo ""
    read -rp "¿Comenzar la instalación y configuración del VPS? (S/n): " CONFIRM
    if [[ "$CONFIRM" =~ ^[nN]$ ]]; then
        msg_error "Operación cancelada por el usuario."
        exit 0
    fi
}

# ── Endurecimiento de Seguridad del Sistema ──────────────────────────────────
apply_security_hardening() {
    msg_step "Aplicando endurecimiento de seguridad en el Sistema Operativo"

    # 1. Parámetros de Kernel (Sysctl) anti-ataques
    msg_info "Configurando parámetros de kernel sysctl anti-ataques (SYN Flood, Spoofing, ICMP)..."
    cat > /etc/sysctl.d/99-kutstudio-security.conf << 'EOF'
# ==============================================================================
# KutStudio - Endurecimiento de Red y Kernel
# ==============================================================================

# Protección contra SYN Floods y agotamiento de sockets
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5

# Protección contra Spoofing de IP y enrutamiento malicioso
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

# Deshabilitar redirecciones ICMP (evitar ataques Man-in-the-Middle)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# Ignorar broadcast ICMP (evita ataques Smurf)
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1

# Registrar paquetes sospechosos (Martians)
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1

# Aumentar límites de descriptores de archivos para alto tráfico
fs.file-max = 2097152
net.core.somaxconn = 4096
net.core.netdev_max_backlog = 10000
EOF
    sysctl -p /etc/sysctl.d/99-kutstudio-security.conf >> "$LOG_FILE" 2>&1 || sysctl --system >> "$LOG_FILE" 2>&1 || true
    msg_success "Parámetros sysctl aplicados correctamente."

    # 2. Configuración Segura de SSH
    msg_info "Configurando SSH (Puerto: $SSH_PORT, Root: $ROOT_LOGIN_VAL, PasswordAuth: $PASS_AUTH_VAL)..."
    
    # Soporte para /etc/ssh/sshd_config.d o fallback a /etc/ssh/sshd_config
    local sshd_conf_file="/etc/ssh/sshd_config"
    local use_dropin=false

    if [[ -d /etc/ssh/sshd_config.d ]] && grep -Eq "^\s*Include\s+/etc/ssh/sshd_config.d/\*.conf" "$sshd_conf_file" 2>/dev/null; then
        use_dropin=true
    fi

    if $use_dropin; then
        cat > /etc/ssh/sshd_config.d/99-kutstudio.conf << EOF
# Configuración segura KutStudio
Port $SSH_PORT
PermitRootLogin $ROOT_LOGIN_VAL
PasswordAuthentication $PASS_AUTH_VAL
MaxAuthTries 4
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
EOF
        chmod 600 /etc/ssh/sshd_config.d/99-kutstudio.conf
    else
        cp "$sshd_conf_file" "${sshd_conf_file}.bak.$(date +%F_%T)"
        # Modificar o añadir directivas
        sed -i -E "s/^\s*#?\s*Port\s+[0-9]+/Port $SSH_PORT/" "$sshd_conf_file" || echo "Port $SSH_PORT" >> "$sshd_conf_file"
        sed -i -E "s/^\s*#?\s*PermitRootLogin\s+.+/PermitRootLogin $ROOT_LOGIN_VAL/" "$sshd_conf_file" || echo "PermitRootLogin $ROOT_LOGIN_VAL" >> "$sshd_conf_file"
        sed -i -E "s/^\s*#?\s*PasswordAuthentication\s+.+/PasswordAuthentication $PASS_AUTH_VAL/" "$sshd_conf_file" || echo "PasswordAuthentication $PASS_AUTH_VAL" >> "$sshd_conf_file"
        sed -i -E "s/^\s*#?\s*MaxAuthTries\s+[0-9]+/MaxAuthTries 4/" "$sshd_conf_file" || echo "MaxAuthTries 4" >> "$sshd_conf_file"
    fi

    # Validar sintaxis de sshd antes de reiniciar
    if sshd -t >> "$LOG_FILE" 2>&1; then
        msg_success "Sintaxis de configuración SSH verificada con éxito."
    else
        msg_warn "Advertencia al validar sshd. Se mantendrán precauciones para no interrumpir la sesión actual."
    fi

    # 3. Configuración de Firewall UFW
    msg_info "Configurando Firewall UFW (abriendo estrictamente puertos necesarios)..."
    export DEBIAN_FRONTEND=noninteractive
    apt-get update -y -qq >> "$LOG_FILE" 2>&1
    apt-get install -y -qq ufw >> "$LOG_FILE" 2>&1

    # REGLA DE ORO: Permitir puerto SSH antes de habilitar firewall para no perder conexión
    ufw default deny incoming >> "$LOG_FILE" 2>&1
    ufw default allow outgoing >> "$LOG_FILE" 2>&1
    ufw allow "$SSH_PORT"/tcp comment 'KutStudio SSH' >> "$LOG_FILE" 2>&1
    ufw allow 80/tcp comment 'Nginx HTTP' >> "$LOG_FILE" 2>&1
    ufw allow 443/tcp comment 'Nginx HTTPS' >> "$LOG_FILE" 2>&1

    # Habilitar UFW sin pedir confirmación interactiva
    echo "y" | ufw enable >> "$LOG_FILE" 2>&1
    msg_success "Firewall UFW activado: Solo puertos $SSH_PORT, 80 y 443 permitidos."

    # Reiniciar servicio SSH de forma segura
    systemctl restart ssh >> "$LOG_FILE" 2>&1 || systemctl restart sshd >> "$LOG_FILE" 2>&1 || true

    # 4. Fail2ban para mitigar ataques de fuerza bruta
    msg_info "Instalando y configurando Fail2ban con cárceles para SSH y Nginx..."
    apt-get install -y -qq fail2ban >> "$LOG_FILE" 2>&1

    cat > /etc/fail2ban/jail.d/kutstudio.local << EOF
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 4
banaction = ufw

[sshd]
enabled  = true
port     = $SSH_PORT
logpath  = %(sshd_log)s
backend  = %(sshd_backend)s

[nginx-http-auth]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/*error.log

[nginx-botsearch]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/*error.log
maxretry = 2
EOF
    systemctl enable fail2ban >> "$LOG_FILE" 2>&1 || true
    systemctl restart fail2ban >> "$LOG_FILE" 2>&1 || true
    msg_success "Fail2ban configurado y activo."

    # 5. Actualizaciones automáticas de seguridad
    msg_info "Activando actualizaciones automáticas de seguridad (unattended-upgrades)..."
    apt-get install -y -qq unattended-upgrades update-notifier-common >> "$LOG_FILE" 2>&1
    echo 'APT::Periodic::Update-Package-Lists "1";' > /etc/apt/apt.conf.d/20auto-upgrades
    echo 'APT::Periodic::Unattended-Upgrade "1";' >> /etc/apt/apt.conf.d/20auto-upgrades
    systemctl enable unattended-upgrades >> "$LOG_FILE" 2>&1 || true
    msg_success "Actualizaciones automáticas de seguridad activadas."
}

# ── Instalación del Stack Web (Nginx + PHP 8.3 + Certbot + FFmpeg) ────────────
install_web_stack() {
    msg_step "Instalando Nginx, PHP 8.3 FPM, Certbot, FFmpeg y SQLite3"
    export DEBIAN_FRONTEND=noninteractive

    # Instalar utilidades esenciales
    apt-get install -y -qq curl wget git unzip tar software-properties-common ca-certificates lsb-release apt-transport-https cron >> "$LOG_FILE" 2>&1

    # Repositorio de PHP (Sury para Debian/Ubuntu si es necesario)
    if [[ "$OS_ID" == "ubuntu" ]]; then
        LC_ALL=C.UTF-8 add-apt-repository -y ppa:ondrej/php >> "$LOG_FILE" 2>&1 || true
    elif [[ "$OS_ID" == "debian" ]]; then
        if [[ ! -f /etc/apt/trusted.gpg.d/php.gpg ]]; then
            wget -qO /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg >> "$LOG_FILE" 2>&1 || true
            echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list
        fi
    fi

    apt-get update -y -qq >> "$LOG_FILE" 2>&1

    # Paquetes del stack
    msg_info "Instalando paquetes de PHP 8.3 y extensiones requeridas por KutStudio..."
    apt-get install -y -qq \
        nginx \
        certbot \
        python3-certbot-nginx \
        ffmpeg \
        sqlite3 \
        php8.3-fpm \
        php8.3-cli \
        php8.3-sqlite3 \
        php8.3-curl \
        php8.3-xml \
        php8.3-mbstring \
        php8.3-zip \
        php8.3-gd \
        php8.3-intl \
        php8.3-bcmath \
        php8.3-opcache >> "$LOG_FILE" 2>&1

    # Si PHP 8.3 falló por alguna razón de distribución, intentar php-fpm nativo
    if ! command -v php >/dev/null 2>&1; then
        msg_warn "Intentando instalación de paquetes PHP por defecto de la distribución..."
        apt-get install -y -qq nginx certbot python3-certbot-nginx ffmpeg sqlite3 \
            php-fpm php-cli php-sqlite3 php-curl php-xml php-mbstring php-zip php-gd php-intl php-bcmath php-opcache >> "$LOG_FILE" 2>&1
    fi

    # Detectar socket de PHP-FPM
    PHP_SOCK=""
    for s in /run/php/php8.3-fpm.sock /run/php/php8.2-fpm.sock /run/php/php8.4-fpm.sock /run/php/php*-fpm.sock; do
        if compgen -G "$s" > /dev/null; then
            # Tomar el primer match existente o expandido
            PHP_SOCK="$(ls -1 $s 2>/dev/null | head -n 1)"
            break
        fi
    done

    if [[ -z "$PHP_SOCK" ]]; then
        PHP_SOCK="/run/php/php8.3-fpm.sock"
    fi
    msg_info "Socket PHP-FPM detectado: $PHP_SOCK"

    # Optimización de php.ini para subidas de audio/vídeo pesadas (1024M)
    msg_info "Optimizando parámetros de php.ini para podcasts y medios pesados..."
    for ini in /etc/php/*/fpm/php.ini /etc/php/*/cli/php.ini; do
        if [[ -f "$ini" ]]; then
            sed -i 's/^upload_max_filesize = .*/upload_max_filesize = 1024M/' "$ini"
            sed -i 's/^post_max_size = .*/post_max_size = 1024M/' "$ini"
            sed -i 's/^memory_limit = .*/memory_limit = 512M/' "$ini"
            sed -i 's/^max_execution_time = .*/max_execution_time = 360/' "$ini"
            sed -i 's/^max_input_time = .*/max_input_time = 360/' "$ini"
        fi
    done

    # Ajuste global de Nginx
    if grep -q "client_max_body_size" /etc/nginx/nginx.conf; then
        sed -i 's/client_max_body_size .*/client_max_body_size 1024M;/' /etc/nginx/nginx.conf
    else
        sed -i '/http {/a \    client_max_body_size 1024M;\n    server_tokens off;' /etc/nginx/nginx.conf
    fi

    systemctl enable nginx >> "$LOG_FILE" 2>&1 || true
    systemctl restart nginx >> "$LOG_FILE" 2>&1 || true
    systemctl restart "php*-fpm" >> "$LOG_FILE" 2>&1 || true

    msg_success "Stack Nginx + PHP + SQLite + FFmpeg instalado y optimizado."
}

# ── Funciones de Clonación / Despliegue de Código ─────────────────────────────
deploy_repo() {
    local app_name="$1"
    local target_dir="$2"
    local github_url="$3"

    msg_info "Desplegando $app_name en $target_dir..."
    mkdir -p "$target_dir"

    # Si se ejecuta dentro de un repositorio de KutStudio con las carpetas locales existentes:
    if [[ -d "$SCRIPT_DIR/$app_name" && "$(ls -A "$SCRIPT_DIR/$app_name" 2>/dev/null)" ]]; then
        msg_info "Copiando archivos locales de $app_name..."
        cp -a "$SCRIPT_DIR/$app_name/." "$target_dir/"
    else
        msg_info "Clonando $app_name desde GitHub ($github_url)..."
        rm -rf "${target_dir:?}"/* "${target_dir:?}"/.[!.]* 2>/dev/null || true
        git clone --depth 1 "$github_url" "$target_dir" >> "$LOG_FILE" 2>&1
    fi
}

# ── Despliegue e Instalación de KutPod ─────────────────────────────────────────
setup_kutpod() {
    local domain="$1"
    local target="/var/www/kutpod"
    msg_step "Instalando KutPod en https://$domain"

    deploy_repo "KutPod" "$target" "https://github.com/ernestoacostame/kutpod.git"

    # Estructura de carpetas requeridas
    mkdir -p "$target/storage/uploads" "$target/storage/pages" "$target/storage/geoip" "$target/storage/backups"
    mkdir -p "$target/media/audio" "$target/media/covers"

    # Permisos
    chown -R www-data:www-data "$target"
    find "$target" -type d -exec chmod 775 {} \;
    find "$target" -type f -exec chmod 664 {} \;
    chmod +x "$target/cli/"*.php 2>/dev/null || true

    # Ejecución del instalador CLI con stdin automático
    msg_info "Inicializando base de datos SQLite y usuario owner de KutPod..."
    printf "%s\n%s\n%s\n%s\n%s\n" \
        "KutPod" \
        "$domain" \
        "Admin" \
        "$ADMIN_EMAIL" \
        "$ADMIN_PASS" | php "$target/cli/install.php" >> "$LOG_FILE" 2>&1 || true

    # Asegurar permisos de la base de datos y lock creados
    chown -R www-data:www-data "$target/storage" "$target/media" "$target/.env" 2>/dev/null || true

    # Configurar Nginx Vhost
    msg_info "Generando configuración Nginx para KutPod ($domain)..."
    cat > "/etc/nginx/sites-available/$domain.conf" << EOF
# KutPod Nginx VirtualHost
server {
    listen 80;
    listen [::]:80;
    server_name $domain;

    root $target;
    index site.php;

    charset utf-8;
    client_max_body_size 1024M;

    # Cabeceras de seguridad
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

    access_log /var/log/nginx/kutpod_access.log;
    error_log  /var/log/nginx/kutpod_error.log warn;

    # Proteger archivos y directorios internos
    location ~ /\\.(?!well-known) { deny all; }
    location ~ ^/(pages|includes|api/handlers|public)/ { deny all; return 404; }
    location ~ ^/cli/(?!install\\.php).+\\.php$ { deny all; return 404; }

    location ^~ /storage/ {
        location ~* \\.(db|db-wal|db-shm|sql|env|lock|log)$ { deny all; return 404; }
        deny all;
        return 404;
    }

    # Exponer media pública (audios y carátulas)
    location ^~ /media/ {
        allow all;
        try_files \$uri =404;
    }

    # Instalador
    location = /install  { return 302 /cli/install.php; }
    location = /install/ { return 302 /cli/install.php; }

    # OP3 Tracker
    rewrite ^/r/([^/]+)/([^/]+)(?:/.*)?$  /r.php?show=\$1&ep=\$2  last;

    # SEO dinámico
    rewrite ^/robots\\.txt$    /robots-sitemap.php?type=robots  last;
    rewrite ^/sitemap\\.xml$   /robots-sitemap.php?type=sitemap last;

    # Feeds RSS
    rewrite ^/feed/([a-zA-Z0-9\\-]+)\\.xml$  /feed.php?slug=\$1  last;
    rewrite ^/feed\\.xml$                /feed.php?slug=all last;

    # API REST
    rewrite ^/api/(.*)$  /api/index.php?route=\$1  last;

    # ActivityPub / Mastodon Fediverse
    location = /.well-known/webfinger { rewrite ^ /activitypub.php?ap=webfinger last; }
    location = /.well-known/host-meta { rewrite ^ /activitypub.php?ap=host-meta last; }

    rewrite ^/users/([a-z0-9\\-]+)/inbox$     /activitypub.php?ap=inbox&slug=\$1    last;
    rewrite ^/users/([a-z0-9\\-]+)/outbox$    /activitypub.php?ap=outbox&slug=\$1    last;
    rewrite ^/users/([a-z0-9\\-]+)/followers$ /activitypub.php?ap=followers&slug=\$1 last;
    rewrite ^/users/([a-z0-9\\-]+)/notes/([^/]+)/?$ /activitypub.php?ap=notes/\$2&slug=\$1 last;
    rewrite ^/users/([a-z0-9\\-]+)/?$        /activitypub.php?ap=actor&slug=\$1    last;

    # Panel Admin
    location = /admin  { rewrite ^ /index.php last; }
    location = /admin/ { rewrite ^ /index.php last; }
    rewrite ^/admin/podcast/([a-z0-9\\-]+)/edit/?$  /index.php?page=edit-podcast&id=\$1  last;
    rewrite ^/admin/podcast/([a-z0-9\\-]+)/?$       /index.php?page=podcast&id=\$1       last;
    rewrite ^/admin/([a-z0-9\\-]+)/?$                /index.php?page=\$1                last;

    location = /logout { return 302 /admin?action=logout; }

    # Reglas públicas y reproductores
    rewrite ^/embed/@([a-z0-9\\-]+)/([a-z0-9\\-]+)/?$ /site.php?r=embed&show=\$1&ep=\$2 last;
    rewrite ^/embed/([a-z0-9\\-]+)/?$                /site.php?r=embed&ep=\$1          last;
    rewrite ^/audio/@([a-z0-9\\-]+)/(.+)\\.mp3$ /r.php?show=\$1&ep=\$2 last;
    rewrite ^/@([a-z0-9\\-]+)/episodes/([a-z0-9\\-]+)/?$ /@\$1/\$2 permanent;
    rewrite ^/@([a-z0-9\\-]+)/?$              /site.php?r=show&id=\$1           last;
    rewrite ^/@([a-z0-9\\-]+)/([a-z0-9\\-]+)/?$ /site.php?r=episode&show=\$1&ep=\$2 last;
    rewrite ^/shows/?$                       /site.php?r=shows                last;
    rewrite ^/p/([a-z0-9\\-]+)/?$            /site.php?r=page&id=\$1           last;
    rewrite ^/about/?$                       /site.php?r=about                last;

    location = / { rewrite ^ /site.php last; }

    # Assets estáticos
    location ^~ /assets/ {
        expires 30d; add_header Cache-Control "public, immutable"; try_files \$uri =404;
    }

    location ~* \\.(?:ico|gif|jpe?g|png|webp|svg|woff2?|ttf|eot|otf|map)\$ {
        expires 30d; add_header Cache-Control "public, immutable"; try_files \$uri =404;
    }

    # Fallback
    location / { try_files \$uri \$uri/ /site.php?r=home; }

    # FastCGI PHP
    location ~ \\.php\$ {
        fastcgi_split_path_info ^(.+\\.php)(/.+)\$;
        fastcgi_pass unix:$PHP_SOCK;
        fastcgi_index site.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        fastcgi_param PATH_INFO       \$fastcgi_path_info;
        fastcgi_param HTTP_X_REAL_IP  \$remote_addr;
        fastcgi_param HTTP_X_FORWARDED_FOR \$proxy_add_x_forwarded_for;
        fastcgi_read_timeout 360;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
    }

    # Audio acelerado interno
    location /protected_media/ {
        internal;
        alias $target/media/audio/;
    }
}
EOF
    ln -sf "/etc/nginx/sites-available/$domain.conf" "/etc/nginx/sites-enabled/$domain.conf"

    # Cron para OP3 Worker
    msg_info "Programando tarea cron para el worker OP3 de KutPod..."
    (crontab -u www-data -l 2>/dev/null | grep -v 'op3-worker.php' || true; echo "*/15 * * * * php $target/cli/op3-worker.php >/dev/null 2>&1") | crontab -u www-data -

    msg_success "KutPod configurado exitosamente."
}

# ── Despliegue e Instalación de KutFast ────────────────────────────────────────
setup_kutfast() {
    local domain="$1"
    local target="/var/www/kutfast"
    msg_step "Instalando KutFast en https://$domain"

    deploy_repo "KutFast" "$target" "https://github.com/ernestoacostame/kutfast.git"

    mkdir -p "$target/tmp"

    # Conexión con KutPod si está instalado o configurado
    local kutpod_endpoint=""
    if [[ -n "$KUTPOD_DOMAIN" ]]; then
        kutpod_endpoint="https://$KUTPOD_DOMAIN"
    else
        kutpod_endpoint="https://pod.example.com"
    fi

    # Generación de config.php
    msg_info "Generando config.php de KutFast..."
    cat > "$target/config.php" << EOF
<?php
// KutFast - Configuración autogenerada por KutStudio VPS Installer
define('APP_PASSWORD',        '$ADMIN_PASS');
define('KUTPOD_URL',           '$kutpod_endpoint');
define('KUTPOD_API_USER',      '$ADMIN_EMAIL');
define('KUTPOD_API_PASSWORD',  '$ADMIN_PASS');
define('KUTPOD_PODCAST_SLUG',  '');
define('PODCASTS_FILE',        __DIR__ . '/podcasts.json');
define('DRAFTS_FILE',          __DIR__ . '/local_drafts.json');
define('TEMPLATES_FILE',       __DIR__ . '/templates.json');
define('UPLOAD_TMP_DIR',       __DIR__ . '/tmp');
define('MAX_AUDIO_SIZE',       500 * 1024 * 1024);
date_default_timezone_set('UTC');
define('KUTPOD_DEBUG',         false);
EOF

    # Permisos
    chown -R www-data:www-data "$target"
    find "$target" -type d -exec chmod 775 {} \;
    find "$target" -type f -exec chmod 664 {} \;

    # Configurar Nginx Vhost
    msg_info "Generando configuración Nginx para KutFast ($domain)..."
    cat > "/etc/nginx/sites-available/$domain.conf" << EOF
# KutFast Nginx VirtualHost
server {
    listen 80;
    listen [::]:80;
    server_name $domain;

    root $target;
    index index.php index.html;

    client_max_body_size 520M;

    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    access_log /var/log/nginx/kutfast_access.log;
    error_log  /var/log/nginx/kutfast_error.log warn;

    # Proteger archivos sensibles
    location ~ ^/(config|auth|kutpod|drafts_store|templates_store|podcasts_store)\\.php$ {
        deny all;
        return 404;
    }

    location ~ \\.json$ {
        deny all;
        return 404;
    }

    location ^~ /tmp/ {
        deny all;
        return 404;
    }

    location / {
        try_files \$uri \$uri/ /index.php?\$query_string;
    }

    location ~ \\.php$ {
        fastcgi_split_path_info ^(.+\\.php)(/.+)\$;
        fastcgi_pass unix:$PHP_SOCK;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 600;
        fastcgi_send_timeout 600;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
    }

    location ~* \\.(?:ico|css|js|gif|jpe?g|png|webp|svg|woff2?|webmanifest)\$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
        try_files \$uri =404;
    }
}
EOF
    ln -sf "/etc/nginx/sites-available/$domain.conf" "/etc/nginx/sites-enabled/$domain.conf"
    msg_success "KutFast configurado exitosamente."
}

# ── Despliegue e Instalación de KutBlog ────────────────────────────────────────
setup_kutblog() {
    local domain="$1"
    local target="/var/www/kutblog"
    msg_step "Instalando KutBlog en https://$domain"

    deploy_repo "KutBlog" "$target" "https://github.com/ernestoacostame/kutblog.git"

    # Crear directorios de contenido y almacenamiento
    mkdir -p "$target/content/articles" "$target/content/pages" "$target/uploads" "$target/cache" "$target/media"

    # Generar configuración vía PHP seguro
    msg_info "Inicializando almacenamiento Flat-File y usuario de KutBlog..."
    php -r "
        \$hash = password_hash('$ADMIN_PASS', PASSWORD_BCRYPT);
        \$config = [
            'site_title' => 'KutBlog',
            'base_url' => 'https://$domain',
            'admin_user' => 'admin',
            'admin_pass' => \$hash,
            'theme' => 'default',
            'theme_color' => '#6366f1',
            'installed_at' => date('c'),
            'version' => '2.1.11',
            'active_plugins' => ['fediverse'],
            'fediverse_username' => 'blog'
        ];
        file_put_contents('$target/config.json', json_encode(\$config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
        file_put_contents('$target/.installed', date('c'));
    " >> "$LOG_FILE" 2>&1

    # Artículos de bienvenida de demostración
    php -r "
        \$article = [
            'title' => 'Bienvenido a KutBlog',
            'content' => '<p>¡Felicidades! Tu nuevo blog ultrarrápido sin base de datos SQL está listo.</p><p>Puedes editar este artículo o publicar nuevas historias desde el panel de administración en <code>/admin/</code>.</p>',
            'excerpt' => 'Bienvenido a tu nueva instalación de KutBlog.',
            'status' => 'published',
            'categories' => ['General'],
            'tags' => ['kutblog', 'bienvenida'],
            'date' => date('Y-m-d H:i:s')
        ];
        file_put_contents('$target/content/articles/bienvenido-a-kutblog.json', json_encode(\$article, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
    " >> "$LOG_FILE" 2>&1 || true

    # Permisos
    chown -R www-data:www-data "$target"
    find "$target" -type d -exec chmod 775 {} \;
    find "$target" -type f -exec chmod 664 {} \;

    # Configurar Nginx Vhost
    msg_info "Generando configuración Nginx para KutBlog ($domain)..."
    cat > "/etc/nginx/sites-available/$domain.conf" << EOF
# KutBlog Nginx VirtualHost
server {
    listen 80;
    listen [::]:80;
    server_name $domain;

    root $target;
    index index.php index.html;

    client_max_body_size 1024M;

    access_log /var/log/nginx/kutblog_access.log;
    error_log  /var/log/nginx/kutblog_error.log warn;

    # Proteger directorios sensibles
    location ~* ^/(core|cache|content)(/|\$) {
        deny all;
        return 404;
    }

    location ~ /\\.(?!well-known) {
        deny all;
    }

    # Media pública
    location ^~ /media/ {
        location ~* \\.php\$ { deny all; return 404; }
        try_files \$uri =404;
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
    }

    location ^~ /uploads/ {
        location ~* \\.php\$ { deny all; return 404; }
        try_files \$uri =404;
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
    }

    # Panel admin
    location ^~ /admin/ {
        try_files \$uri \$uri/ /admin/index.php?\$query_string;
        location ~ \\.php\$ {
            fastcgi_split_path_info ^(.+\\.php)(/.+)\$;
            fastcgi_pass unix:$PHP_SOCK;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
            include fastcgi_params;
            fastcgi_read_timeout 300;
        }
    }

    # URLs limpias front-end
    location / {
        try_files \$uri \$uri/ /index.php?\$query_string;
    }

    location ~ \\.php\$ {
        fastcgi_split_path_info ^(.+\\.php)(/.+)\$;
        fastcgi_pass unix:$PHP_SOCK;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_read_timeout 300;
    }

    location ~* \\.(?:css|js|ico|gif|jpe?g|png|webp|svg|woff2?)\$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
        try_files \$uri =404;
    }
}
EOF
    ln -sf "/etc/nginx/sites-available/$domain.conf" "/etc/nginx/sites-enabled/$domain.conf"
    msg_success "KutBlog configurado exitosamente."
}

# ── Despliegue e Instalación de KutSocial ──────────────────────────────────────
setup_kutsocial() {
    local domain="$1"
    local target="/var/www/kutsocial"
    msg_step "Instalando KutSocial en https://$domain"

    deploy_repo "KutSocial" "$target" "https://github.com/ernestoacostame/kutsocial.git"

    mkdir -p "$target/data" "$target/data/uploads"

    # Permisos iniciales
    chown -R www-data:www-data "$target"
    find "$target" -type d -exec chmod 775 {} \;
    find "$target" -type f -exec chmod 664 {} \;

    # Instalador CLI oficial de KutSocial
    msg_info "Ejecutando instalador CLI de KutSocial..."
    php "$target/install.php" \
        --username="admin" \
        --email="$ADMIN_EMAIL" \
        --password="$ADMIN_PASS" \
        --domain="$domain" >> "$LOG_FILE" 2>&1 || true

    # Asegurar permisos post-instalación
    chown -R www-data:www-data "$target/data" "$target/config.php" 2>/dev/null || true

    # Cron Worker para entrega en cola y federación
    msg_info "Programando cron worker para la cola federada de KutSocial..."
    (crontab -u www-data -l 2>/dev/null | grep -v 'kutsocial/cron.php' || true; echo "* * * * * php $target/cron.php >/dev/null 2>&1") | crontab -u www-data -

    # Configurar Nginx Vhost (Con soporte Server-Sent Events / SSE y búfer deshabilitado)
    msg_info "Generando configuración Nginx para KutSocial ($domain)..."
    cat > "/etc/nginx/sites-available/$domain.conf" << EOF
# KutSocial Nginx VirtualHost
server {
    listen 80;
    listen [::]:80;
    server_name $domain;

    root $target;
    index index.php;

    charset utf-8;
    client_max_body_size 1024M;

    access_log /var/log/nginx/kutsocial_access.log;
    error_log  /var/log/nginx/kutsocial_error.log warn;

    # Archivos multimedia subidos por usuarios
    location ^~ /data/uploads/ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }

    # Proteger carpetas internas
    location ~ ^/(data|src)/ {
        deny all;
        return 404;
    }

    location ~ /\\.(?!well-known) {
        deny all;
    }

    # Enrutamiento front controller y API Mastodon
    location / {
        try_files \$uri \$uri/ /index.php\$is_args\$args;
    }

    # FastCGI PHP con streaming en tiempo real (SSE)
    location ~ \\.php\$ {
        fastcgi_split_path_info ^(.+\\.php)(/.+)\$;
        fastcgi_pass unix:$PHP_SOCK;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;

        # Desactivar buffering para Server-Sent Events (SSE) y streaming instantáneo
        fastcgi_buffering off;
        gzip off;

        fastcgi_read_timeout 600s;
        fastcgi_send_timeout 600s;
    }

    location ~* \\.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|otf)\$ {
        expires 30d;
        access_log off;
    }
}
EOF
    ln -sf "/etc/nginx/sites-available/$domain.conf" "/etc/nginx/sites-enabled/$domain.conf"
    msg_success "KutSocial configurado exitosamente."
}

# ── Certificados SSL (Certbot) ────────────────────────────────────────────────
setup_ssl_certificates() {
    msg_step "Configuración de Certificados SSL HTTPS (Let's Encrypt)"

    # Obtener IP pública del servidor
    SERVER_IP=$(curl -4 -s --max-time 5 ifconfig.me || curl -4 -s --max-time 5 icanhazip.com || true)
    [[ -n "$SERVER_IP" ]] && msg_info "IP pública del VPS detectada: $SERVER_IP"

    local domains=()
    if $INSTALL_KUTPOD; then domains+=("$KUTPOD_DOMAIN"); fi
    if $INSTALL_KUTFAST; then domains+=("$KUTFAST_DOMAIN"); fi
    if $INSTALL_KUTBLOG; then domains+=("$KUTBLOG_DOMAIN"); fi
    if $INSTALL_KUTSOCIAL; then domains+=("$KUTSOCIAL_DOMAIN"); fi

    for dom in "${domains[@]}"; do
        echo ""
        msg_info "Verificando resolución DNS para: $dom..."
        local dom_ip
        dom_ip=$(getent ahosts "$dom" 2>/dev/null | awk '{print $1}' | head -n 1 || true)

        if [[ -n "$dom_ip" && -n "$SERVER_IP" && "$dom_ip" == "$SERVER_IP" ]]; then
            msg_info "DNS validado ($dom -> $dom_ip). Solicitando certificado SSL gratuito a Let's Encrypt..."
            if certbot --nginx -d "$dom" --non-interactive --agree-tos -m "$ADMIN_EMAIL" --redirect >> "$LOG_FILE" 2>&1; then
                msg_success "Certificado SSL activado correctamente para $dom"
            else
                msg_warn "Certbot no pudo completar la emisión para $dom. Se mantendrá accesible vía HTTP."
            fi
        else
            msg_warn "El dominio $dom apunta a '${dom_ip:-vacío}' (IP de este VPS: '${SERVER_IP:-desconocida}')."
            msg_warn "Configuración HTTP activa. Cuando apuntes tus DNS a este VPS, emite el SSL ejecutando:"
            echo -e "      ${BOLD}certbot --nginx -d $dom${RESET}"
        fi
    done
}

# ── Verificación Final y Resumen ─────────────────────────────────────────────
finalize_installation() {
    msg_step "Verificando servicios y generando reporte"

    # Deshabilitar default site de nginx si existe
    rm -f /etc/nginx/sites-enabled/default 2>/dev/null || true

    # Probar configuración Nginx
    if nginx -t >> "$LOG_FILE" 2>&1; then
        systemctl reload nginx >> "$LOG_FILE" 2>&1
        msg_success "Nginx recargado con todas las configuraciones válidas."
    else
        msg_error "Error en la configuración de Nginx. Revisa /var/log/nginx/error.log"
    fi

    # Generar archivo de resumen
    cat > "$SUMMARY_FILE" << EOF
================================================================================
 KutStudio - Reporte de Instalación y Credenciales del VPS
 Generado: $(date '+%Y-%m-%d %H:%M:%S')
================================================================================

1. SEGURIDAD Y ACCESO SSH
--------------------------------------------------------------------------------
Puerto SSH:              $SSH_PORT
Acceso Root SSH:         $ROOT_LOGIN_VAL
Password Auth SSH:       $PASS_AUTH_VAL
Firewall UFW:            Activo (Puertos abiertos: $SSH_PORT/tcp, 80/tcp, 443/tcp)
Fail2ban:                Activo (Cárceles para SSH y Nginx habilitadas)
Sysctl Anti-DDoS:        Activo (/etc/sysctl.d/99-kutstudio-security.conf)
Actualizaciones Auto:    Activo (unattended-upgrades de seguridad)

2. SERVICIOS INSTALADOS
--------------------------------------------------------------------------------
Stack Web:               Nginx + PHP 8.3-FPM + SQLite3 + FFmpeg + Certbot
Socket PHP:              $PHP_SOCK
Límite de subida:        1024 MB (Optimizado para audio/vídeo de podcasts)

3. APLICACIONES Y CREDENCIALES
--------------------------------------------------------------------------------
Usuario Admin General:   admin / $ADMIN_EMAIL
Contraseña Admin:        $ADMIN_PASS

EOF

    if $INSTALL_KUTPOD; then
        cat >> "$SUMMARY_FILE" << EOF
[ KutPod ]
  URL:                   https://$KUTPOD_DOMAIN
  Panel Admin:           https://$KUTPOD_DOMAIN/admin
  Ruta en VPS:           /var/www/kutpod
  Base de Datos:         /var/www/kutpod/storage/kutpod.db (SQLite)
  Cron OP3:              */15 * * * * (Worker de estadísticas y bots)

EOF
    fi

    if $INSTALL_KUTFAST; then
        cat >> "$SUMMARY_FILE" << EOF
[ KutFast ]
  URL:                   https://$KUTFAST_DOMAIN
  Ruta en VPS:           /var/www/kutfast
  Contraseña de Acceso:  $ADMIN_PASS
  KutPod Vinculado:      ${KUTPOD_DOMAIN:-Configurar en config.php}

EOF
    fi

    if $INSTALL_KUTBLOG; then
        cat >> "$SUMMARY_FILE" << EOF
[ KutBlog ]
  URL:                   https://$KUTBLOG_DOMAIN
  Panel Admin:           https://$KUTBLOG_DOMAIN/admin
  Ruta en VPS:           /var/www/kutblog
  Almacenamiento:        Flat-File JSON (/var/www/kutblog/content)

EOF
    fi

    if $INSTALL_KUTSOCIAL; then
        cat >> "$SUMMARY_FILE" << EOF
[ KutSocial ]
  URL:                   https://$KUTSOCIAL_DOMAIN
  Ruta en VPS:           /var/www/kutsocial
  Base de Datos:         /var/www/kutsocial/data/kutsocial.sqlite (SQLite)
  Cron Worker Cola:      * * * * * (Worker federado y entregas)

EOF
    fi

    cat >> "$SUMMARY_FILE" << EOF
--------------------------------------------------------------------------------
Archivo de log completo: $LOG_FILE
Guarda este reporte en un lugar seguro: $SUMMARY_FILE
================================================================================
EOF
    chmod 600 "$SUMMARY_FILE"

    # Mostrar resumen en pantalla
    echo ""
    echo -e "${GREEN}${BOLD}============================================================${RESET}"
    echo -e "${GREEN}${BOLD}     ¡INSTALACIÓN DE KUTSTUDIO COMPLETADA CON ÉXITO!${RESET}"
    echo -e "${GREEN}${BOLD}============================================================${RESET}"
    echo ""
    cat "$SUMMARY_FILE"
    echo ""
    echo -e "${YELLOW}${BOLD}⚠  IMPORTANTE ANTES DE DESCONECTARTE:${RESET}"
    echo -e "   1. Tu puerto SSH ahora es: ${BOLD}${SSH_PORT}${RESET}"
    echo -e "      Para conectarte nuevamente usa: ${CYAN}ssh -p $SSH_PORT usuario@tu-ip${RESET}"
    echo -e "   2. No cierres esta terminal sin abrir una nueva sesión para comprobar"
    echo -e "      que puedes entrar con el nuevo puerto SSH."
    echo -e "   3. El resumen completo se guardó en: ${CYAN}$SUMMARY_FILE${RESET}"
    echo ""
}

# ── Ejecución Principal ───────────────────────────────────────────────────────
main() {
    if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
        show_help
    fi

    check_environment
    run_wizard
    apply_security_hardening
    install_web_stack

    if $INSTALL_KUTPOD; then setup_kutpod "$KUTPOD_DOMAIN"; fi
    if $INSTALL_KUTFAST; then setup_kutfast "$KUTFAST_DOMAIN"; fi
    if $INSTALL_KUTBLOG; then setup_kutblog "$KUTBLOG_DOMAIN"; fi
    if $INSTALL_KUTSOCIAL; then setup_kutsocial "$KUTSOCIAL_DOMAIN"; fi

    setup_ssl_certificates
    finalize_installation
}

main "$@"
