#!/usr/bin/env bash
#
# Arma los .zip que se suben al hosting (cPanel).
#
#   ./scripts/build-deploy.sh
#
# Genera en .deploy/ :
#   firmas-app.zip     → la aplicación (código + vendor de producción + assets de Vite)
#   firmas-assets.zip  → storage/app/private (plantillas y fuentes de las firmas)
#
# Van separados a propósito: el de la app se sube en cada deploy, el de assets
# solo la primera vez. Si se subiera siempre, pisaría las plantillas que hayan
# cargado desde el panel en producción.
#
set -euo pipefail

cd "$(dirname "$0")/.."
RAIZ="$PWD"
SALIDA="$RAIZ/.deploy"
STAGING="$SALIDA/staging"

rojo()  { printf '\033[31m%s\033[0m\n' "$*"; }
verde() { printf '\033[32m%s\033[0m\n' "$*"; }
info()  { printf '\033[36m▸\033[0m %s\n' "$*"; }

[ -f artisan ] || { rojo "No estoy en la raíz del proyecto Laravel."; exit 1; }

rm -rf "$STAGING"
mkdir -p "$STAGING"

# ─── 1. Assets de Vite ───────────────────────────────────────────────────────
# public/build está en .gitignore y el hosting no tiene Node, así que se compila
# acá y viaja dentro del zip.
info "Compilando assets de Vite…"
npm run build >/dev/null 2>&1 || { rojo "Falló 'npm run build'."; exit 1; }
[ -f public/build/manifest.json ] || { rojo "No se generó public/build/manifest.json."; exit 1; }
verde "  public/build listo"

# ─── 2. Copia del proyecto ───────────────────────────────────────────────────
info "Copiando el proyecto…"
rsync -a \
    --exclude '.git/' \
    --exclude '.deploy/' \
    --exclude 'node_modules/' \
    --exclude 'vendor/' \
    --exclude 'tests/' \
    --exclude 'docker/' \
    --exclude 'scripts/' \
    --exclude 'Dockerfile' \
    --exclude 'docker-compose*.yml' \
    --exclude '.env' \
    --exclude '.env.backup' \
    --exclude 'resources/js/' \
    --exclude 'resources/css/' \
    --exclude 'package*.json' \
    --exclude 'vite.config.js' \
    --exclude 'tailwind.config.js' \
    --exclude 'postcss.config.js' \
    --exclude 'phpunit.xml' \
    --exclude 'storage/app/private/' \
    --exclude 'public/storage' \
    --exclude 'storage/logs/*' \
    --exclude 'storage/framework/cache/*' \
    --exclude 'storage/framework/sessions/*' \
    --exclude 'storage/framework/views/*' \
    --exclude 'bootstrap/cache/*' \
    ./ "$STAGING/"

# La config cacheada de desarrollo apunta a la base local: si viaja, la app de
# producción ignora su propio .env y no conecta.
rm -f "$STAGING"/bootstrap/cache/*.php

# Directorios que Laravel necesita y que rsync no copia por estar vacíos.
for d in storage/app/private/templates storage/app/private/fonts \
         storage/framework/cache/data storage/framework/sessions \
         storage/framework/views storage/logs bootstrap/cache; do
    mkdir -p "$STAGING/$d"
    touch "$STAGING/$d/.gitkeep"
done

# ─── 3. Dependencias de producción ───────────────────────────────────────────
info "Instalando dependencias sin paquetes de desarrollo…"
(
    cd "$STAGING"
    composer install --no-dev --optimize-autoloader --no-interaction --no-progress \
        >/dev/null 2>&1
) || { rojo "Falló 'composer install'. Probá correrlo a mano en $STAGING"; exit 1; }
verde "  vendor/ de producción listo ($(find "$STAGING/vendor" -type f | wc -l) archivos)"

# ─── 4. Plantilla de .env ────────────────────────────────────────────────────
# El .env real nunca viaja en el zip: lleva credenciales y APP_KEY.
cat > "$STAGING/.env.produccion" <<'ENV'
APP_NAME="Generador de Firmas"
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://firma.gruposaavedra.com.bo

LOG_CHANNEL=stack
LOG_LEVEL=error

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=usuario_firmas
DB_USERNAME=usuario_firmas
DB_PASSWORD=

SESSION_DRIVER=database
CACHE_STORE=database
QUEUE_CONNECTION=sync

FILESYSTEM_DISK=local

MAIL_MAILER=smtp
MAIL_HOST=localhost
MAIL_PORT=587
MAIL_FROM_ADDRESS=firmas@gruposaavedra.com.bo
ENV

# ─── 5. Empaquetado ──────────────────────────────────────────────────────────
# Se usa ZipArchive de PHP porque el binario 'zip' no está en todos los equipos.
empaquetar() {
    local origen="$1" destino="$2"
    php -r '
        $origen  = rtrim($argv[1], "/");
        $destino = $argv[2];
        @unlink($destino);

        $zip = new ZipArchive();
        if ($zip->open($destino, ZipArchive::CREATE) !== true) {
            fwrite(STDERR, "No se pudo crear $destino\n");
            exit(1);
        }

        $items = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($origen, FilesystemIterator::SKIP_DOTS),
            RecursiveIteratorIterator::SELF_FIRST
        );

        $n = 0;
        foreach ($items as $item) {
            $relativo = substr($item->getPathname(), strlen($origen) + 1);

            if ($item->isDir()) {
                $zip->addEmptyDir($relativo);
                continue;
            }

            // Un symlink colgado (public/storage) haría fallar addFile en
            // silencio y el zip saldría incompleto sin avisar.
            if (! $item->isFile() || ! $item->isReadable()) {
                fwrite(STDERR, "  omitido (no es un archivo legible): $relativo\n");
                continue;
            }

            if (! $zip->addFile($item->getPathname(), $relativo)) {
                fwrite(STDERR, "No se pudo agregar $relativo\n");
                exit(1);
            }
            $n++;
        }

        $zip->close();
        echo $n, "\n";
    ' "$origen" "$destino"
}

info "Comprimiendo la aplicación…"
ARCHIVOS_APP=$(empaquetar "$STAGING" "$SALIDA/firmas-app.zip")

info "Comprimiendo plantillas y fuentes…"
ARCHIVOS_ASSETS=$(empaquetar "$RAIZ/storage/app/private" "$SALIDA/firmas-assets.zip")

rm -rf "$STAGING"

# ─── 6. Resumen ──────────────────────────────────────────────────────────────
echo
verde "Listo. Archivos en .deploy/"
printf '  %-22s %8s  %s archivos\n' "firmas-app.zip" \
    "$(du -h "$SALIDA/firmas-app.zip" | cut -f1)" "$ARCHIVOS_APP"
printf '  %-22s %8s  %s archivos\n' "firmas-assets.zip" \
    "$(du -h "$SALIDA/firmas-assets.zip" | cut -f1)" "$ARCHIVOS_ASSETS"
echo
cat <<'PASOS'
Para subirlo:

  1. firmas-app.zip     → descomprimir en  /home/USUARIO/firmas/
                          (FUERA de public_html, o quedan expuestos .env y vendor)
  2. firmas-assets.zip  → descomprimir en  /home/USUARIO/firmas/storage/app/private/
                          (solo en el primer deploy)
  3. Document root de los 4 dominios  →  /home/USUARIO/firmas/public
  4. Renombrar .env.produccion a .env y completar credenciales
  5. php artisan key:generate
     php artisan migrate --force
     php artisan db:seed --class=CompanySeeder --force
     php artisan db:seed --class=CityBranchSeeder --force
     php artisan db:seed --class=CompanyConfigSeeder --force
     php artisan config:cache && php artisan route:cache && php artisan view:cache
  6. chmod -R 775 storage bootstrap/cache

No corras 'db:seed' a secas: DatabaseSeeder crea un usuario de prueba.
Tampoco LocalTestSeeder, que reescribe los dominios a .local
PASOS
