#!/usr/bin/env bash
#
# Configura el dominio del portal de reportes dentro de Virtualmin.
#
#   sudo bash configurar-portal.sh reportes.incide.com.co incide sistemas@incide.com.co
#
# Hace, en este orden:
#   1. crea el dominio si no existe (PHP-FPM + SSL, sin correo ni DNS)
#   2. sube los limites de tiempo de PHP
#   3. arregla fastcgi_read_timeout en nginx  <- el paso que se olvida
#   4. apunta la raiz del documento a la carpeta public
#   5. emite el certificado SSL
#   6. deja la estructura de Laravel lista y comprueba que todo funciona
#
# Es idempotente: se puede volver a correr sin romper nada.
#
# ---------------------------------------------------------------------------
# POR QUE EL PASO 3 ES EL IMPORTANTE
#
# Un reporte que no esta en cache tarda unos 70 s en armarse, porque descarga
# las imagenes del servidor de Sihos. Hay DOS limites que cortan antes:
#
#   max_execution_time      30 s   (PHP)    -> lo sube el paso 2
#   fastcgi_read_timeout   60 s   (nginx)  -> lo arregla el paso 3
#
# Si solo se sube el de PHP, el portal falla igual: PHP sigue trabajando,
# nginx cierra la conexion y el navegador muestra error. Lo confuso es que el
# PDF SI se genero y quedo guardado en disco.
#
# Virtualmin escribe "fastcgi_read_timeout 60;" dentro del bloque server de
# cada dominio. Poner el valor en el bloque http de nginx.conf NO sirve: a
# nivel server pisa al http. Por eso este script cambia el 60 por 300 en el
# archivo del dominio, y ademas lo anota en Server Templates para que no se
# pierda cuando Virtualmin regenere la configuracion.
# ---------------------------------------------------------------------------

set -euo pipefail

DOMINIO="${1:-reportes.incide.com.co}"
USUARIO="${2:-incide}"
CORREO="${3:-admin@incide.com.co}"
CLAVE="${CLAVE_PORTAL:-CambiarEstaClave123}"

log()  { printf '\n\033[1;36m==> %s\033[0m\n' "$1"; }
ok()   { printf '    \033[32mOK\033[0m  %s\n' "$1"; }
aviso(){ printf '    \033[33m!!\033[0m  %s\n' "$1"; }
fallo(){ printf '    \033[31mXX\033[0m  %s\n' "$1"; }

[[ $EUID -eq 0 ]] || { echo "Se corre como root: sudo bash configurar-portal.sh $DOMINIO"; exit 1; }

command -v virtualmin >/dev/null || {
    echo "Virtualmin no esta instalado."
    echo "  sudo bash deploy/virtualmin/instalar-virtualmin.sh"
    exit 1
}

CARPETA="/home/$USUARIO"

# ---------------------------------------------------------------------------
log "1/6  Dominio $DOMINIO"

if virtualmin list-domains --name-only 2>/dev/null | grep -qx "$DOMINIO"; then
    ok "el dominio ya existe"
else
    virtualmin create-domain \
        --domain "$DOMINIO" \
        --pass "$CLAVE" \
        --email "$CORREO" \
        --useradmin 0 \
        --admin 0 \
        --web yes \
        --webmin no \
        --ftp no \
        --dns no \
        --mail no \
        --ssl yes \
        --php yes \
        --unix \
        --logfile \
        2>&1 | tail -5
    ok "creado"
fi

# PHP-FPM y no mod_php: mod_php no aisla sitios y Virtualmin lo desaconseja.
if virtualmin list-features --domain "$DOMINIO" 2>/dev/null | grep -q 'PHP-FPM'; then
    ok "PHP-FPM activo"
elif virtualmin list-features --domain "$DOMINIO" 2>/dev/null | grep -q 'PHP'; then
    aviso "PHP activo pero no en modo FPM. Activalo en:"
    aviso "  Features and Plugins -> PHP Execution Mode -> FPM"
else
    virtualmin enable-feature --domain "$DOMINIO" php-fpm 2>&1 | tail -2
    ok "PHP-FPM activado"
fi

# ---------------------------------------------------------------------------
log "2/6  Limites de PHP"
# Se ponen uno por uno porque si alguno falla no se pierde el resto.
for par in "max_execution_time:300" \
           "max_input_time:300" \
           "memory_limit:512M" \
           "post_max_size:16M" \
           "upload_max_filesize:16M"; do
    nombre="${par%%:*}"
    valor="${par##*:}"
    if virtualmin modify-php-ini --domain "$DOMINIO" \
            --ini-name "$nombre" --ini-value "$valor" >/dev/null 2>&1; then
        ok "$(printf '%-20s %s' "$nombre" "$valor")"
    else
        fallo "$nombre no se pudo cambiar"
    fi
done

# ---------------------------------------------------------------------------
log "3/6  Limite de nginx"

# Virtualmin deja "fastcgi_read_timeout 60;" dentro del bloque server. Se
# cambia el valor en el archivo del dominio. Al ser la misma directiva en el
# mismo nivel, el orden en que esten no importa: gana la ultima.
CONF_NGINX="/etc/nginx/conf.d/$DOMINIO.conf"

if [[ -f "$CONF_NGINX" ]]; then
    antes=$(grep -c 'fastcgi_read_timeout 60;' "$CONF_NGINX" || true)
    sed -i 's/fastcgi_read_timeout[[:space:]]*60;/fastcgi_read_timeout 300s;/g' "$CONF_NGINX"

    if grep -q 'fastcgi_read_timeout 300s;' "$CONF_NGINX"; then
        ok "$antes valor(es) de 60 s cambiados a 300 s en $CONF_NGINX"
    else
        aviso "No se encontro 'fastcgi_read_timeout 60;' en el archivo."
        aviso "Revisa a mano: grep fastcgi $CONF_NGINX"
        aviso "Si no hay ninguna linea, anade dentro del bloque server:"
        aviso "  fastcgi_read_timeout 300s;"
    fi

    # Virtualmin tambien pone HTTPS $https, que es justo lo que necesita
    # Laravel para saber que la peticion es segura.
    if grep -q 'fastcgi_param[[:space:]]*HTTPS' "$CONF_NGINX"; then
        ok "el esquema HTTPS ya lo pasa nginx"
    else
        fallo "falta fastcgi_param HTTPS. Anadelo dentro del location de PHP:"
        fallo "  fastcgi_param HTTPS on;"
    fi
else
    fallo "No existe $CONF_NGINX"
    aviso "Comprueba donde lo guardo Virtualmin:"
    aviso "  grep -rl $DOMINIO /etc/nginx/ --include='*.conf'"
fi

# ---------------------------------------------------------------------------
log "4/6  Raiz del documento"
# Debe ser la carpeta public. Con la carpeta del proyecto quedarian-exposed el
# .env (con las credenciales de Sihos) y la base SQLite con los enlaces.
RAIZ_WEB=$(virtualmin list-domains --domain "$DOMINIO" \
    --multiline --name-only --no-header 2>/dev/null \
    | grep -i 'Document root' | awk -F': *' '{print $2}' | head -1)

if [[ -d "$CARPETA" ]]; then
    if [[ "$RAIZ_WEB" == "$CARPETA/public" || "$RAIZ_WEB" == "$CARPETA/public_html" ]]; then
        ok "raiz del documento: $RAIZ_WEB"
    else
        aviso "La raiz del documento es: ${RAIZ_WEB:-<no encontrada>}"
        aviso "Debe ser $CARPETA/public. Cambiala en:"
        aviso "  Virtualmin -> $DOMINIO -> Web Configuration -> Document root"
    fi
else
    aviso "La carpeta $CARPETA aun no existe (el codigo se sube despues)"
fi

# ---------------------------------------------------------------------------
log "5/6  Certificado SSL"
if [[ -f "$CARPETA/ssl.combined" || -f "$CARPETA/ssl.cert" ]]; then
    ok "ya hay certificado"
elif virtualmin generate-letsencrypt-cert --domain "$DOMINIO" --host "$DOMINIO" --webroot yes >/dev/null 2>&1; then
    ok "certificado emitido"
else
    aviso "No se pudo emitir. Causas posibles:"
    aviso "  - el dominio todavia no apunta a esta IP (revisa con nslookup)"
    aviso "  - el puerto 80 esta cerrado"
    aviso "  Emitelo desde el panel: SSL Certificate -> Request -> Let's Encrypt"
fi

# ---------------------------------------------------------------------------
log "6/6  Parte de Laravel"
if [[ -f "$CARPETA/artisan" ]]; then
    su - "$USUARIO" -c "bash $CARPETA/deploy/virtualmin/preparar-dominio.sh $CARPETA" 2>&1 | tail -20
else
    aviso "El codigo no esta en $CARPETA todavia."
    aviso "Subelo desde tu PC:"
    aviso "  php tools\\armar-paquete.php"
    aviso "  scp incide-deploy.zip $USUARIO@TU_IP:/home/$USUARIO/"
    aviso "  ssh $USUARIO@TU_IP"
    aviso "  cd ~ && unzip -q incide-deploy.zip && rm incide-deploy.zip"
    aviso "  bash deploy/virtualmin/preparar-dominio.sh /home/$USUARIO"
fi

# ---------------------------------------------------------------------------
printf '\n\033[1;32m========================================\033[0m\n'
printf '\033[1;32m  Configuracion terminada\033[0m\n'
printf '\033[1;32m========================================\033[0m\n\n'

echo "  Comprueba que todo quedo bien:"
echo "    sudo bash $(dirname "${BASH_SOURCE[0]}")/verificar-portal.sh $DOMINIO $USUARIO"
echo
echo "  QUE TIENES QUE HACER TU:"
echo
echo "  1. DNS: crear el registro A   $DOMINIO -> IP de este VPS"
echo "     (el dominio principal sigue en Banahosting con su WordPress)"
echo
echo "  2. En $CARPETA/.env poner las credenciales reales:"
echo "     nano $CARPETA/.env"
echo "     php artisan key:generate --show   ->  APP_KEY"
echo
echo "  3. Borrar la pagina de pruebas cuando el portal este listo:"
echo "     rm $CARPETA/public/test.html"
echo
echo "  4. OJO: si Virtualmin regenera la configuracion de nginx (cambias algo"
echo "     del sitio en el panel), el limite de 300 s se pierde. Vuelve a correr:"
echo "     sudo bash $(basename "${BASH_SOURCE[0]}") $DOMINIO $USUARIO $CORREO"
echo
echo "     verificar-portal.sh te avisa si paso."
echo