#!/usr/bin/env bash
# ============================================================
#  RecreaHUB — Setup Universal
#  Detecta o SO automaticamente e aplica a configuração correta
#
#  Uso:
#    bash setup-universal.sh [--dry-run] [--no-nginx] [--port 3000]
#
#  Sistemas suportados:
#    ✅ CentOS 7          → Node 18 LTS + yum + firewalld + SELinux
#    ✅ CentOS 8 / Stream → Node 20 LTS + dnf + firewalld + SELinux
#    ✅ RHEL 7/8/9        → Node 18/20  + yum/dnf
#    ✅ Rocky Linux 8/9   → Node 20 LTS + dnf
#    ✅ AlmaLinux 8/9     → Node 20 LTS + dnf
#    ✅ Ubuntu 20.04+     → Node 20 LTS + apt + ufw
#    ✅ Debian 11/12      → Node 20 LTS + apt
#    ✅ openSUSE Leap 15  → Node 20 LTS + zypper
#    ✅ Alpine 3.18+      → Node 20 LTS + apk
#    ⚠️  macOS            → Sugere Docker
#    ⚠️  glibc < 2.17     → Abortado com orientação
# ============================================================

set -euo pipefail

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

# ── Variáveis globais ──────────────────────────────────────────────────────────
OS_ID=""            # centos, ubuntu, debian, rocky, etc.
OS_VERSION=""       # versão principal: 7, 8, 22 …
OS_VERSION_FULL=""  # versão completa: 7.9, 22.04 …
OS_PRETTY=""        # nome legível
OS_FAMILY=""        # rhel | debian | suse | alpine | macos | unknown
PKG_MANAGER=""      # yum | dnf | apt | zypper | apk
PKG_UPDATE=""       # comando de update
PKG_INSTALL=""      # comando de install
NODE_VERSION=""     # 18 | 20 | unsupported
GLIBC_VERSION=""    # ex: 2.17, 2.35
FIREWALL_TYPE=""    # firewalld | ufw | iptables | none
SELINUX_ENABLED=0
SYSTEMD_AVAILABLE=0
NGINX_CONF_DIR=""   # /etc/nginx/conf.d ou /etc/nginx/sites-available
EPEL_NEEDED=0       # 1 se precisar do EPEL (RHEL-family)

# ── Configuração da app ────────────────────────────────────────────────────────
APP_NAME="recreahub-api"
APP_DIR="/opt/recreahub-api"
APP_USER="recreahub"
APP_PORT=3000
DRY_RUN=0
SKIP_NGINX=0
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
APP_SRC_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

# ── Parsear argumentos ─────────────────────────────────────────────────────────
while [[ $# -gt 0 ]]; do
    case "$1" in
        --dry-run)    DRY_RUN=1;          shift ;;
        --no-nginx)   SKIP_NGINX=1;       shift ;;
        --port)       APP_PORT="$2";      shift 2 ;;
        -h|--help)
            echo "Uso: bash setup-universal.sh [--dry-run] [--no-nginx] [--port 3000]"
            exit 0 ;;
        *) echo "Argumento desconhecido: $1"; exit 1 ;;
    esac
done

# ── Helpers ────────────────────────────────────────────────────────────────────
log()     { echo -e "${GREEN}[✔]${NC} $*"; }
info()    { echo -e "${BLUE}[ℹ]${NC} $*"; }
warn()    { echo -e "${YELLOW}[⚠]${NC} $*"; }
error()   { echo -e "${RED}[✘]${NC} $*" >&2; }
section() { echo -e "\n${BOLD}${CYAN}══ $* ══${NC}"; }
run()     {
    if [[ $DRY_RUN -eq 1 ]]; then
        echo -e "  ${YELLOW}[DRY-RUN]${NC} $*"
    else
        eval "$@"
    fi
}

# ── Verificar root ─────────────────────────────────────────────────────────────
check_root() {
    if [[ $EUID -ne 0 ]]; then
        error "Este script deve ser executado como root."
        echo "  Use: sudo bash $0"
        exit 1
    fi
}

# ── Detectar SO ───────────────────────────────────────────────────────────────
detect_os() {
    section "Detectando Sistema Operacional"

    # macOS
    if [[ "$(uname -s)" == "Darwin" ]]; then
        OS_ID="macos"; OS_FAMILY="macos"
        OS_PRETTY="macOS $(sw_vers -productVersion 2>/dev/null || echo '')"
        return
    fi

    # Linux — /etc/os-release (padrão moderno)
    if [[ -f /etc/os-release ]]; then
        # shellcheck source=/dev/null
        . /etc/os-release
        OS_ID="${ID:-unknown}"
        OS_VERSION_FULL="${VERSION_ID:-0}"
        OS_VERSION="${VERSION_ID%%.*}"
        OS_PRETTY="${PRETTY_NAME:-$ID $VERSION_ID}"

        # Determinar família
        local id_like_val="${ID_LIKE:-}"
        case "$OS_ID" in
            ubuntu|debian|linuxmint|pop|kali|raspbian)
                OS_FAMILY="debian" ;;
            centos|rhel|fedora|rocky|almalinux|ol|amzn)
                OS_FAMILY="rhel" ;;
            opensuse*|sles|suse)
                OS_FAMILY="suse" ;;
            alpine)
                OS_FAMILY="alpine" ;;
            arch|manjaro|endeavouros)
                OS_FAMILY="arch" ;;
            *)
                if   echo "$id_like_val" | grep -qi "debian"; then OS_FAMILY="debian"
                elif echo "$id_like_val" | grep -qi "rhel\|fedora\|centos"; then OS_FAMILY="rhel"
                else OS_FAMILY="unknown"
                fi ;;
        esac

    # Fallback: arquivos legados
    elif [[ -f /etc/centos-release ]]; then
        OS_ID="centos"; OS_FAMILY="rhel"
        OS_VERSION=$(grep -oP '\d+' /etc/centos-release | head -1)
        OS_VERSION_FULL="$OS_VERSION"
        OS_PRETTY="CentOS Linux $OS_VERSION"
    elif [[ -f /etc/redhat-release ]]; then
        OS_ID="rhel"; OS_FAMILY="rhel"
        OS_VERSION=$(grep -oP '\d+' /etc/redhat-release | head -1)
        OS_VERSION_FULL="$OS_VERSION"
        OS_PRETTY=$(cat /etc/redhat-release)
    else
        OS_ID="unknown"; OS_FAMILY="unknown"
        OS_PRETTY="Linux desconhecido"
    fi
}

# ── Detectar gerenciador de pacotes ───────────────────────────────────────────
detect_pkg_manager() {
    case "$OS_FAMILY" in
        debian)
            PKG_MANAGER="apt"
            PKG_UPDATE="apt-get update -qq"
            PKG_INSTALL="apt-get install -y" ;;
        rhel)
            if command -v dnf &>/dev/null; then
                PKG_MANAGER="dnf"
                PKG_UPDATE="dnf check-update -q || true"
                PKG_INSTALL="dnf install -y"
            else
                PKG_MANAGER="yum"
                PKG_UPDATE="yum check-update -q || true"
                PKG_INSTALL="yum install -y"
            fi ;;
        suse)
            PKG_MANAGER="zypper"
            PKG_UPDATE="zypper refresh -q"
            PKG_INSTALL="zypper install -y" ;;
        alpine)
            PKG_MANAGER="apk"
            PKG_UPDATE="apk update -q"
            PKG_INSTALL="apk add" ;;
        *)
            for pm in dnf yum apt zypper apk; do
                if command -v "$pm" &>/dev/null; then
                    PKG_MANAGER="$pm"; break
                fi
            done ;;
    esac
}

# ── Detectar versão do glibc ──────────────────────────────────────────────────
detect_glibc() {
    if command -v ldd &>/dev/null; then
        GLIBC_VERSION=$(ldd --version 2>&1 | head -1 | grep -oP '\d+\.\d+' | tail -1 || echo "0.0")
    elif [[ -f /lib/libc.so.6 ]]; then
        GLIBC_VERSION=$(/lib/libc.so.6 2>&1 | grep "GNU C Library" | grep -oP '\d+\.\d+' | head -1 || echo "0.0")
    else
        GLIBC_VERSION="0.0"
    fi
}

# ── Escolher versão do Node.js conforme glibc ─────────────────────────────────
detect_node_version() {
    local major minor
    major=$(echo "$GLIBC_VERSION" | cut -d. -f1)
    minor=$(echo "$GLIBC_VERSION" | cut -d. -f2)

    if   (( major >  2 )) || (( major == 2 && minor >= 28 )); then
        NODE_VERSION="20"   # Node 20 LTS — suporte até Abril 2026
    elif (( major == 2 && minor >= 17 )); then
        NODE_VERSION="18"   # Node 18 LTS — suporte até Abril 2025
    else
        NODE_VERSION="unsupported"
    fi

    # Alpine: Node via apk — sempre versão disponível no repositório
    [[ "$OS_FAMILY" == "alpine" ]] && NODE_VERSION="20"
    # macOS: qualquer versão via nvm/brew
    [[ "$OS_FAMILY" == "macos"  ]] && NODE_VERSION="20"
}

# ── Detectar firewall ─────────────────────────────────────────────────────────
detect_firewall() {
    if   systemctl is-active --quiet firewalld 2>/dev/null; then FIREWALL_TYPE="firewalld"
    elif command -v ufw &>/dev/null && ufw status 2>/dev/null | grep -q "Status: active"; then FIREWALL_TYPE="ufw"
    elif command -v ufw &>/dev/null; then FIREWALL_TYPE="ufw"
    elif systemctl is-active --quiet firewalld 2>/dev/null; then FIREWALL_TYPE="firewalld"
    elif command -v iptables &>/dev/null; then FIREWALL_TYPE="iptables"
    else FIREWALL_TYPE="none"
    fi
}

# ── Detectar SELinux ──────────────────────────────────────────────────────────
detect_selinux() {
    if command -v getenforce &>/dev/null && [[ "$(getenforce 2>/dev/null)" != "Disabled" ]]; then
        SELINUX_ENABLED=1
    fi
}

# ── Detectar systemd ──────────────────────────────────────────────────────────
detect_systemd() {
    if command -v systemctl &>/dev/null && systemctl list-units &>/dev/null 2>&1; then
        SYSTEMD_AVAILABLE=1
    fi
}

# ── Nginx: diretório de config ─────────────────────────────────────────────────
detect_nginx_conf_dir() {
    case "$OS_FAMILY" in
        rhel|suse|alpine) NGINX_CONF_DIR="/etc/nginx/conf.d" ;;
        *)                NGINX_CONF_DIR="/etc/nginx/sites-available" ;;
    esac
}

# ── EPEL necessário? ──────────────────────────────────────────────────────────
detect_epel_needed() {
    if [[ "$OS_FAMILY" == "rhel" ]]; then
        EPEL_NEEDED=1
    fi
}

# ── Exibir resultado da detecção ──────────────────────────────────────────────
print_detection_report() {
    echo ""
    echo -e "${BOLD}╔══════════════════════════════════════════════════════╗${NC}"
    echo -e "${BOLD}║       RecreaHUB — Relatório de Detecção de SO        ║${NC}"
    echo -e "${BOLD}╚══════════════════════════════════════════════════════╝${NC}"
    echo ""
    printf "  %-22s %s\n" "Sistema Operacional:"  "${BOLD}${OS_PRETTY}${NC}"
    printf "  %-22s %s\n" "Família:"              "$OS_FAMILY"
    printf "  %-22s %s\n" "ID:"                   "$OS_ID $OS_VERSION_FULL"
    printf "  %-22s %s\n" "Gerenciador pacotes:"  "$PKG_MANAGER"
    printf "  %-22s %s\n" "glibc versão:"         "$GLIBC_VERSION"
    printf "  %-22s %s\n" "Node.js selecionado:"  "${BOLD}Node ${NODE_VERSION} LTS${NC}"
    printf "  %-22s %s\n" "Firewall:"             "$FIREWALL_TYPE"
    printf "  %-22s %s\n" "SELinux:"              "$([ $SELINUX_ENABLED -eq 1 ] && echo 'ativo' || echo 'inativo')"
    printf "  %-22s %s\n" "systemd:"              "$([ $SYSTEMD_AVAILABLE -eq 1 ] && echo 'disponível' || echo 'não disponível')"
    printf "  %-22s %s\n" "Nginx conf dir:"       "$NGINX_CONF_DIR"
    echo ""

    # Compatibilidade de versões
    echo -e "  ${BOLD}Compatibilidade Node.js × glibc:${NC}"
    echo -e "  ┌─────────────┬──────────────┬─────────────────────────────────┐"
    echo -e "  │ Node.js     │ glibc mín.   │ Status neste SO                 │"
    echo -e "  ├─────────────┼──────────────┼─────────────────────────────────┤"
    local gv_major gv_minor
    gv_major=$(echo "$GLIBC_VERSION" | cut -d. -f1)
    gv_minor=$(echo "$GLIBC_VERSION" | cut -d. -f2)
    local n18_ok n20_ok
    (( gv_major > 2 || (gv_major == 2 && gv_minor >= 17) )) && n18_ok="${GREEN}✅ compatível${NC}" || n18_ok="${RED}❌ incompatível${NC}"
    (( gv_major > 2 || (gv_major == 2 && gv_minor >= 28) )) && n20_ok="${GREEN}✅ compatível${NC}" || n20_ok="${RED}❌ incompatível${NC}"
    printf "  │ %-11s │ %-12s │ %-41b │\n" "Node 18 LTS" "2.17+"  "$n18_ok"
    printf "  │ %-11s │ %-12s │ %-41b │\n" "Node 20 LTS" "2.28+"  "$n20_ok"
    echo -e "  └─────────────┴──────────────┴─────────────────────────────────┘"
    echo ""
}

# ── Avisos especiais por SO ───────────────────────────────────────────────────
print_os_warnings() {
    case "$OS_ID" in
        centos)
            if [[ "$OS_VERSION" == "7" ]]; then
                warn "CentOS 7 atingiu EOL em Junho/2024. Node 20 incompatível (glibc 2.17)."
                warn "Usando Node 18 LTS (suporte até Abril/2025)."
                warn "Recomendado migrar para Rocky Linux 8/9 ou AlmaLinux 8/9."
            elif [[ "$OS_VERSION" == "8" ]]; then
                warn "CentOS 8 atingiu EOL em Dezembro/2021. Use CentOS Stream 8, Rocky Linux ou AlmaLinux."
            fi ;;
        almalinux)
            if [[ "${OS_VERSION}" -ge 9 ]]; then
                log "AlmaLinux ${OS_VERSION_FULL} — Node 20 LTS totalmente suportado (glibc 2.34 ≥ 2.28). ✅"
                info "EPEL + CRB (CodeReady Builder) serão habilitados automaticamente."
                info "Suporte até: Maio 2032 (AlmaLinux 9)."
            else
                log "AlmaLinux ${OS_VERSION_FULL} — Node 20 LTS suportado. ✅"
                info "EPEL será habilitado automaticamente."
            fi ;;
        rocky)
            if [[ "${OS_VERSION}" -ge 9 ]]; then
                log "Rocky Linux ${OS_VERSION_FULL} — Node 20 LTS totalmente suportado (glibc 2.34). ✅"
                info "EPEL + CRB serão habilitados automaticamente."
            fi ;;
        rhel)
            if [[ "${OS_VERSION}" -ge 9 ]]; then
                info "RHEL ${OS_VERSION_FULL} — Node 20 LTS suportado."
                warn "CRB requer subscription ativa: subscription-manager repos --enable codeready-builder-for-rhel-9-x86_64-rpms"
            elif [[ "${OS_VERSION}" == "7" ]]; then
                warn "RHEL 7 em EOL. Usando Node 18 LTS (glibc 2.17)."
            fi ;;
        macos)
            error "macOS detectado. Este script suporta apenas Linux."
            echo ""
            echo "  Opções para macOS:"
            echo "    1. Docker:      docker compose up -d --build"
            echo "    2. Node local:  brew install node && npm start"
            exit 1 ;;
    esac

    if [[ "$NODE_VERSION" == "unsupported" ]]; then
        error "glibc $GLIBC_VERSION < 2.17 — Node.js não suportado neste SO."
        echo ""
        echo "  Soluções:"
        echo "    1. Usar Docker (contorna a limitação de glibc)"
        echo "    2. Atualizar o SO para uma versão mais recente"
        exit 1
    fi

    if [[ "$OS_FAMILY" == "unknown" ]]; then
        warn "SO não reconhecido. O script tentará continuar, mas pode falhar."
        read -rp "  Deseja continuar mesmo assim? [s/N]: " _ans
        [[ "${_ans,,}" == "s" ]] || exit 0
    fi
}

# ── Confirmação interativa ────────────────────────────────────────────────────
confirm_setup() {
    echo -e "${BOLD}Ações que serão executadas:${NC}"
    echo "  1. Instalar Node.js ${NODE_VERSION} LTS via NodeSource"
    echo "  2. Instalar PM2 (gerenciador de processos)"
    echo "  3. Copiar app para $APP_DIR"
    echo "  4. Criar usuário de sistema '$APP_USER'"
    echo "  5. Configurar PM2 startup (boot automático)"
    [[ $SELINUX_ENABLED -eq 1 ]]  && echo "  6. Configurar SELinux (httpd_can_network_connect)"
    [[ "$FIREWALL_TYPE" != "none" ]] && echo "  7. Abrir portas no $FIREWALL_TYPE (80, 443, $APP_PORT)"
    [[ $SKIP_NGINX -eq 0 ]]       && echo "  8. Instalar e configurar Nginx (proxy reverso)"
    [[ $DRY_RUN -eq 1 ]]          && echo ""  && warn "MODO DRY-RUN: nenhuma alteração será feita."
    echo ""

    read -rp "  Continuar? [S/n]: " _ans
    [[ "${_ans,,}" == "n" ]] && echo "Cancelado." && exit 0
}

# ── Instalar dependências base ────────────────────────────────────────────────
install_base_deps() {
    section "Instalando dependências base"
    run "$PKG_UPDATE"

    case "$OS_FAMILY" in
        debian) run "$PKG_INSTALL curl wget git build-essential" ;;
        rhel)
            # EPEL para pacotes extras (Nginx, certbot)
            if [[ $EPEL_NEEDED -eq 1 ]] && ! rpm -q epel-release &>/dev/null; then
                info "Instalando EPEL repository..."
                if [[ "$PKG_MANAGER" == "dnf" ]]; then
                    run "dnf install -y epel-release"
                else
                    run "yum install -y epel-release"
                fi
            fi
            # CRB (CodeReady Builder) — necessário para pacotes completos do EPEL no RHEL 9-family
            # AlmaLinux 9 / Rocky 9: crb  |  RHEL 9: subscription-manager
            if [[ "$PKG_MANAGER" == "dnf" && "${OS_VERSION}" -ge 9 ]]; then
                info "Habilitando CRB (CodeReady Builder)..."
                run "dnf config-manager --set-enabled crb 2>/dev/null \
                    || dnf config-manager --set-enabled powertools 2>/dev/null \
                    || true"
            fi
            run "$PKG_INSTALL curl wget git" ;;
        suse)   run "$PKG_INSTALL curl wget git gcc" ;;
        alpine) run "$PKG_INSTALL curl wget git bash" ;;
    esac
    log "Dependências base instaladas."
}

# ── Instalar Node.js ──────────────────────────────────────────────────────────
install_nodejs() {
    section "Instalando Node.js ${NODE_VERSION} LTS"

    if command -v node &>/dev/null; then
        local cur_ver
        cur_ver=$(node -v | grep -oP '\d+' | head -1)
        if [[ "$cur_ver" == "$NODE_VERSION" ]]; then
            log "Node.js $NODE_VERSION já instalado: $(node -v)"
            return
        fi
        warn "Node.js $(node -v) instalado. Será atualizado para v${NODE_VERSION}."
    fi

    case "$OS_FAMILY" in
        debian)
            run "curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash -"
            run "$PKG_INSTALL nodejs" ;;
        rhel)
            run "curl -fsSL https://rpm.nodesource.com/setup_${NODE_VERSION}.x | bash -"
            run "$PKG_INSTALL nodejs" ;;
        suse)
            run "curl -fsSL https://rpm.nodesource.com/setup_${NODE_VERSION}.x | bash -"
            run "$PKG_INSTALL nodejs${NODE_VERSION}" ;;
        alpine)
            run "$PKG_INSTALL nodejs npm" ;;
        *)
            error "Instalação automática de Node.js não suportada para $OS_FAMILY."
            echo "  Instale manualmente: https://nodejs.org/en/download"
            exit 1 ;;
    esac

    log "Node.js instalado: $(node -v 2>/dev/null || echo 'v${NODE_VERSION}.x')"
    log "npm instalado:     $(npm  -v 2>/dev/null || echo 'ok')"
}

# ── Instalar PM2 ──────────────────────────────────────────────────────────────
install_pm2() {
    section "Instalando PM2"
    if command -v pm2 &>/dev/null; then
        log "PM2 já instalado: $(pm2 -v)"
        return
    fi
    run "npm install -g pm2"
    log "PM2 instalado: $(pm2 -v 2>/dev/null || echo 'ok')"
}

# ── Deploy da aplicação ───────────────────────────────────────────────────────
deploy_app() {
    section "Implantando aplicação em $APP_DIR"

    run "mkdir -p $APP_DIR"
    run "cp -r ${APP_SRC_DIR}/. $APP_DIR/"
    run "cd $APP_DIR && npm install --omit=dev"

    # Criar .env a partir do example se não existir
    if [[ ! -f "$APP_DIR/.env" ]]; then
        run "cp $APP_DIR/.env.example $APP_DIR/.env"
        warn ".env criado a partir do .env.example — edite as credenciais antes de iniciar!"
        warn "  nano $APP_DIR/.env"
    fi

    # Criar usuário de sistema dedicado
    if ! id -u "$APP_USER" &>/dev/null; then
        run "useradd -r -s /sbin/nologin $APP_USER"
        log "Usuário '$APP_USER' criado."
    fi
    run "chown -R ${APP_USER}:${APP_USER} $APP_DIR"

    log "App implantada em $APP_DIR"
}

# ── Iniciar PM2 e configurar startup ─────────────────────────────────────────
configure_pm2_startup() {
    section "Configurando PM2 e startup automático"

    run "cd $APP_DIR && pm2 start ecosystem.config.js --env production"
    run "pm2 save"

    info "Gerando comando de startup para '$OS_ID'..."
    if [[ $DRY_RUN -eq 0 ]]; then
        local startup_cmd
        startup_cmd=$(pm2 startup systemd -u "$APP_USER" --hp "/home/$APP_USER" 2>/dev/null \
                        | grep "sudo env PATH" | head -1 || true)
        if [[ -n "$startup_cmd" ]]; then
            eval "$startup_cmd"
            log "Startup configurado automaticamente."
        else
            warn "Execute o comando abaixo para ativar o startup automático:"
            pm2 startup systemd 2>/dev/null || true
        fi
    else
        echo -e "  ${YELLOW}[DRY-RUN]${NC} pm2 startup systemd → executar e copiar o comando gerado"
    fi

    log "PM2 iniciado em modo cluster (todos os cores)."
}

# ── Configurar firewall ───────────────────────────────────────────────────────
configure_firewall() {
    [[ "$FIREWALL_TYPE" == "none" ]] && return
    section "Configurando firewall ($FIREWALL_TYPE)"

    case "$FIREWALL_TYPE" in
        firewalld)
            run "firewall-cmd --permanent --add-service=http"
            run "firewall-cmd --permanent --add-service=https"
            run "firewall-cmd --permanent --add-port=${APP_PORT}/tcp"
            run "firewall-cmd --reload"
            log "Portas 80, 443, $APP_PORT abertas no firewalld." ;;
        ufw)
            run "ufw allow 80/tcp"
            run "ufw allow 443/tcp"
            run "ufw allow ${APP_PORT}/tcp"
            log "Portas 80, 443, $APP_PORT abertas no ufw." ;;
        iptables)
            run "iptables -I INPUT -p tcp --dport 80  -j ACCEPT"
            run "iptables -I INPUT -p tcp --dport 443 -j ACCEPT"
            run "iptables -I INPUT -p tcp --dport ${APP_PORT} -j ACCEPT"
            warn "Regras iptables não persistidas. Instale iptables-persistent para persistir."
            log "Portas 80, 443, $APP_PORT abertas (iptables)." ;;
    esac
}

# ── Configurar SELinux ────────────────────────────────────────────────────────
configure_selinux() {
    [[ $SELINUX_ENABLED -eq 0 ]] && return
    section "Configurando SELinux"

    run "setsebool -P httpd_can_network_connect 1"
    log "SELinux: httpd_can_network_connect ativado (Nginx → Node.js)."
    info "Se ainda houver bloqueios, execute: audit2allow -a | grep recreahub"
}

# ── Instalar e configurar Nginx ───────────────────────────────────────────────
install_nginx() {
    [[ $SKIP_NGINX -eq 1 ]] && return
    section "Instalando Nginx"

    if ! command -v nginx &>/dev/null; then
        case "$OS_FAMILY" in
            debian) run "$PKG_INSTALL nginx" ;;
            rhel)
                # AlmaLinux/Rocky/RHEL 9+: nginx disponível no AppStream, não precisa EPEL
                # AlmaLinux/Rocky/RHEL 8 e CentOS 7: precisa EPEL (já instalado)
                run "$PKG_INSTALL nginx" ;;
            suse)   run "$PKG_INSTALL nginx" ;;
            alpine) run "$PKG_INSTALL nginx" ;;
        esac
    else
        log "Nginx já instalado: $(nginx -v 2>&1 | head -1)"
    fi

    # Instalar certbot — versão python3 para RHEL9+, python2 para RHEL7
    if ! command -v certbot &>/dev/null; then
        if [[ "$OS_FAMILY" == "rhel" ]]; then
            if [[ "${OS_VERSION}" -ge 9 ]]; then
                run "$PKG_INSTALL certbot python3-certbot-nginx"
            elif [[ "${OS_VERSION}" -ge 8 ]]; then
                run "$PKG_INSTALL certbot python3-certbot-nginx"
            else
                # CentOS 7 / RHEL 7 — usa python2
                run "$PKG_INSTALL certbot python2-certbot-nginx"
            fi
        elif [[ "$OS_FAMILY" == "debian" ]]; then
            run "$PKG_INSTALL certbot python3-certbot-nginx"
        fi
    fi

    # Escolher o arquivo de config correto para o SO
    local conf_src
    if [[ "$OS_FAMILY" == "rhel" && "${OS_VERSION}" -ge 9 ]]; then
        # AlmaLinux 9 / Rocky 9 / RHEL 9 — config com HTTP/2 e SSL moderno
        conf_src="$SCRIPT_DIR/setup-nginx-almalinux9.conf"
        [[ ! -f "$conf_src" ]] && conf_src="$SCRIPT_DIR/setup-nginx-centos7.conf"
    elif [[ "$OS_FAMILY" == "rhel" ]]; then
        conf_src="$SCRIPT_DIR/setup-nginx-centos7.conf"
    else
        conf_src="$SCRIPT_DIR/setup-nginx.conf"
    fi

    if [[ -f "$conf_src" ]]; then
        case "$OS_FAMILY" in
            rhel|suse|alpine)
                run "cp $conf_src /etc/nginx/conf.d/recreahub-api.conf" ;;
            debian)
                run "mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled"
                run "cp $conf_src /etc/nginx/sites-available/recreahub-api"
                run "ln -sf /etc/nginx/sites-available/recreahub-api /etc/nginx/sites-enabled/" ;;
        esac
    else
        warn "Config Nginx não encontrado: $conf_src — configure manualmente."
    fi

    run "nginx -t"
    run "systemctl enable nginx"
    run "systemctl start nginx"
    log "Nginx instalado e configurado como proxy reverso para :$APP_PORT"
}

# ── Resumo final ──────────────────────────────────────────────────────────────
print_summary() {
    echo ""
    echo -e "${BOLD}${GREEN}╔══════════════════════════════════════════════════════╗${NC}"
    echo -e "${BOLD}${GREEN}║           ✅  Setup concluído com sucesso!           ║${NC}"
    echo -e "${BOLD}${GREEN}╚══════════════════════════════════════════════════════╝${NC}"
    echo ""
    echo -e "  ${BOLD}Sistema:${NC}   $OS_PRETTY"
    echo -e "  ${BOLD}Node.js:${NC}   $(node -v 2>/dev/null || echo "v${NODE_VERSION}.x")"
    echo -e "  ${BOLD}PM2:${NC}       $(pm2 -v 2>/dev/null || echo 'instalado')"
    echo -e "  ${BOLD}App dir:${NC}   $APP_DIR"
    echo -e "  ${BOLD}API:${NC}       https://api.recreahub.com.br  (local: http://localhost:$APP_PORT)"
    echo -e "  ${BOLD}Health:${NC}    https://api.recreahub.com.br/health"
    echo ""
    echo -e "  ${YELLOW}⚠️  Lembre-se de editar o .env antes de usar em produção:${NC}"
    echo -e "     nano $APP_DIR/.env"
    echo ""
    echo -e "  ${BOLD}Comandos úteis:${NC}"
    echo -e "     pm2 status                → estado dos processos"
    echo -e "     pm2 logs $APP_NAME        → logs ao vivo"
    echo -e "     pm2 reload $APP_NAME      → reload zero-downtime"
    echo -e "     pm2 monit                 → dashboard interativo"
    [[ $SKIP_NGINX -eq 0 ]] && \
    echo -e "     systemctl status nginx    → status do Nginx"
    echo ""
}

# ── MAIN ──────────────────────────────────────────────────────────────────────
main() {
    echo ""
    echo -e "${BOLD}${BLUE}  RecreaHUB — Setup Universal de Backend Node.js${NC}"
    echo -e "  $(date '+%Y-%m-%d %H:%M:%S')"
    echo ""

    check_root

    # Fase 1: detectar tudo
    detect_os
    detect_pkg_manager
    detect_glibc
    detect_node_version
    detect_firewall
    detect_selinux
    detect_systemd
    detect_nginx_conf_dir
    detect_epel_needed

    # Fase 2: relatório + avisos
    print_detection_report
    print_os_warnings

    # Fase 3: confirmação
    confirm_setup

    # Fase 4: executar
    install_base_deps
    install_nodejs
    install_pm2
    deploy_app
    configure_pm2_startup
    configure_selinux
    configure_firewall
    install_nginx

    # Fase 5: resumo
    print_summary
}

main "$@"
