#!/usr/bin/env bash
# =============================================================================
# Despliegue productivo — OneProject Pro (landing)
#
# Ubicación: /var/www/oneproject-pro.com/desplegar.sh
# Uso en la VM:
#   cd /var/www/oneproject-pro.com
#   sudo bash desplegar.sh
#
# Subir a la raíz /var/www/oneproject-pro.com/ el ZIP que quieras desplegar:
#   landing.zip
# Si el ZIP no está, el proyecto se omite.
# El ZIP (comprimir_landing.bat) no incluye .env ni node_modules; se conservan en el servidor.
# =============================================================================

set -Eeuo pipefail

BASE_DIR="/var/www/oneproject-pro.com"
DEPLOY_USER="${SUDO_USER:-$USER}"

PROCESADOS=0
OMITIDOS=0

trap 'echo "ERROR: el despliegue falló en la línea $LINENO."' ERR

echo "========================================"
echo " Iniciando despliegue de OneProject Pro"
echo " Base: $BASE_DIR"
echo " Usuario propietario: $DEPLOY_USER"
echo "========================================"

if [[ ! -d "$BASE_DIR" ]]; then
    echo "ERROR: no existe el directorio base: $BASE_DIR"
    exit 1
fi

# --- utilidades ---------------------------------------------------------------

prepare_writable() {
    local project_dir="$1"
    echo "Actualizando propietario ($DEPLOY_USER:www-data)..."
    sudo chown -R "$DEPLOY_USER:www-data" "$project_dir"
    echo "Aplicando permisos de escritura (775)..."
    sudo chmod -R 775 "$project_dir"
}

restore_apache_perms() {
    local project_dir="$1"
    echo "Restaurando permisos para Apache (www-data:www-data, 755)..."
    sudo chown -R www-data:www-data "$project_dir"
    sudo chmod -R 755 "$project_dir"
}

resolve_zip() {
    # Resuelve ZIP: preferir raíz BASE_DIR/NAME.zip; si no, NAME/NAME.zip.
    # Imprime SOLO la ruta del ZIP en stdout (mensajes a stderr).
    local name="$1"
    local project_dir="$BASE_DIR/$name"
    local upload_zip="$BASE_DIR/$name.zip"
    local project_zip="$project_dir/$name.zip"

    if [[ -f "$upload_zip" ]]; then
        echo "ZIP encontrado en la carpeta principal." >&2
        echo "Moviendo $name.zip a $project_dir..." >&2
        sudo mkdir -p "$project_dir"
        sudo mv -f -- "$upload_zip" "$project_zip"
        printf '%s\n' "$project_zip"
        return 0
    fi

    if [[ -f "$project_zip" ]]; then
        echo "ZIP encontrado dentro de $project_dir." >&2
        printf '%s\n' "$project_zip"
        return 0
    fi

    return 1
}

unzip_project() {
    local name="$1"
    local project_dir="$BASE_DIR/$name"
    local zip_path="$2"

    sudo mkdir -p "$project_dir"
    echo "Descomprimiendo $name.zip..."
    sudo unzip -o "$zip_path" -d "$project_dir"

    echo "Eliminando archivo ZIP..."
    sudo rm -- "$zip_path"
}

soft_systemctl() {
    # soft_systemctl <action> <unit> — no falla si el unit no existe
    local action="$1"
    local unit="$2"
    if sudo systemctl cat "$unit" &>/dev/null; then
        echo "systemctl $action $unit..."
        sudo systemctl "$action" "$unit" || echo "AVISO: systemctl $action $unit no completó con éxito."
    else
        echo "Omitido: servicio $unit no está instalado."
    fi
}

run_as_deploy_user() {
    # Ejecuta el comando como DEPLOY_USER (evita builds como root si se usó sudo bash).
    if [[ "$(id -u)" -eq 0 && -n "$DEPLOY_USER" && "$DEPLOY_USER" != "root" ]]; then
        sudo -u "$DEPLOY_USER" -H bash -lc "$*"
    else
        bash -lc "$*"
    fi
}

# --- landing ------------------------------------------------------------------

deploy_landing() {
    local name="landing"
    local project_dir="$BASE_DIR/$name"

    echo
    echo "----------------------------------------"
    echo " Revisando: $name"
    echo "----------------------------------------"

    if [[ ! -d "$project_dir" ]]; then
        echo "AVISO: no existe el directorio: $project_dir"
        echo "Se omitirá este proyecto."
        ((OMITIDOS += 1)) || true
        return 0
    fi

    local zip_path
    if ! zip_path="$(resolve_zip "$name")"; then
        echo "Sin cambios: no se encontró $name.zip."
        echo "Se omitirá $name."
        ((OMITIDOS += 1)) || true
        return 0
    fi

    unzip_project "$name" "$zip_path"
    prepare_writable "$project_dir"

    if [[ ! -f "$project_dir/package.json" ]]; then
        echo "ERROR: falta package.json en $project_dir"
        exit 1
    fi

    echo "Construyendo $name (npm run build)..."
    run_as_deploy_user "cd '$project_dir' && npm run build"

    restore_apache_perms "$project_dir"
    echo "$name fue desplegado correctamente."
    ((PROCESADOS += 1)) || true
}

# --- ejecución ----------------------------------------------------------------

deploy_landing

if [[ "$PROCESADOS" -gt 0 ]]; then
    echo
    echo "----------------------------------------"
    echo " Reiniciando servicios"
    echo "----------------------------------------"

    soft_systemctl reload apache2
    soft_systemctl reload php8.4-fpm
    soft_systemctl reload php8.1-fpm

    soft_systemctl restart apache2
    soft_systemctl restart php8.4-fpm
    soft_systemctl restart php8.1-fpm
fi

echo
echo "========================================"
echo " Despliegue finalizado"
echo "========================================"
echo " Proyectos procesados: $PROCESADOS"
echo " Proyectos omitidos:   $OMITIDOS"
echo "========================================"

if [[ "$PROCESADOS" -eq 0 ]]; then
    echo
    echo "AVISO: no se encontró landing.zip."
    echo "Genera con comprimir_landing.bat y súbelo a $BASE_DIR"
fi
