#!/usr/bin/env bash
#
# Déploiement chaps-api (prod).
#
# Usage :
#   bash deploy.sh                 # déploie dev (branche de prod — décision 07/2026)
#   BRANCH=xxx bash deploy.sh      # déploie une autre branche
#   SKIP_BACKUP=1 bash deploy.sh   # saute le dump (déconseillé)
#
# Le répertoire de l'app est déduit de l'emplacement du script.
# ⚠️ Ce script ne déploie JAMAIS le .env : il est posé à la main sur le serveur.
#
# ─── LES 2 PIÈGES DE CE DÉPLOIEMENT ───────────────────────────────────────────
# 1. alcyon/identity est une dépendance "path" (../identity) : le dossier voisin
#    doit exister ET être à jour AVANT composer install (cf. docs DEPLOYMENT.md).
# 2. `metadata:regenerate-all --force` est OBLIGATOIRE après chaque déploiement :
#    sans lui, les métadonnées/CTA restent figés sur l'ancienne version du code.
# ──────────────────────────────────────────────────────────────────────────────

set -euo pipefail

APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# La prod livre `dev` (décision 07/2026) — aligné sur deploy-almalinux/install.sh.
BRANCH="${BRANCH:-dev}"
cd "$APP_DIR"

log()  { echo -e "\n\033[1;36m==> $*\033[0m"; }
die()  { echo -e "\n\033[1;31m✘ $*\033[0m" >&2; exit 1; }

[ -f .env ] || die ".env absent — il doit être posé à la main sur le serveur."
# Piège n°1 : composer attend le package identity dans le dossier voisin.
[ -d ../identity ] || die "../identity absent — cloner le package (branche dev) à côté de l'app."

# --- Sauvegarde de la base AVANT toute migration ------------------------------
if [ "${SKIP_BACKUP:-0}" != "1" ]; then
    log "Sauvegarde de la base"
    # tr -d '\r' : un .env aux fins de ligne Windows (CRLF) glisserait un \r
    # invisible dans le mot de passe → "Access denied" incompréhensible.
    DB_NAME=$(grep -E '^DB_DATABASE=' .env | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'" | tr -d '\r')
    DB_USER=$(grep -E '^DB_USERNAME=' .env | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'" | tr -d '\r')
    DB_PASS=$(grep -E '^DB_PASSWORD=' .env | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'" | tr -d '\r')
    mkdir -p backups
    mysqldump -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" | gzip > "backups/chaps-$(date +%F-%H%M%S).sql.gz" \
        || die "Sauvegarde échouée — déploiement interrompu."
    find backups -name 'chaps-*.sql.gz' -mtime +30 -delete 2>/dev/null || true
    echo "   → $(ls -1t backups/chaps-*.sql.gz | head -1)"
fi

CURRENT_SHA=$(git rev-parse HEAD)
log "Révision actuelle : $CURRENT_SHA  (rollback : git reset --hard $CURRENT_SHA)"

# --- Mode maintenance ---------------------------------------------------------
log "Mode maintenance"
php artisan down --retry=15 || true
trap 'php artisan up || true' EXIT

# --- Code ---------------------------------------------------------------------
log "Récupération du code ($BRANCH)"
git fetch origin
git rev-parse --verify "origin/$BRANCH" >/dev/null 2>&1 \
    || die "La branche '$BRANCH' n'existe pas sur origin."
git reset --hard "origin/$BRANCH"

log "Dépendances"
composer install --no-dev --prefer-dist --optimize-autoloader --no-interaction

log "Build CSS (tailwind)"
npm ci && npm run build:css || echo "   ! build CSS échoué (non bloquant) — dashboard sans styles"

# --- Base ---------------------------------------------------------------------
log "Migrations"
php artisan migrate --force

# --- Caches -------------------------------------------------------------------
log "Caches"
php artisan config:clear
# Cache APPLICATIF (store de données), distinct des caches de framework.
# Évite de servir des données périmées après déploiement (catalogue de modules,
# hiérarchie des rôles, etc.).
php artisan cache:clear || echo "   ! cache:clear échoué (non bloquant)"
php artisan config:cache
php artisan route:cache || echo "   ! route:cache échoué (non bloquant)"
php artisan view:cache

# --- Piège n°2 : régénération des métadonnées (TOUJOURS après un déploiement) --
log "Régénération des métadonnées"
php artisan metadata:regenerate-all --force

# --- Fin ----------------------------------------------------------------------
log "Sortie de maintenance"
php artisan up
trap - EXIT

log "Health check"
# /api/health = endpoint public dédié (HealthController) — chaps est en bootstrap
# legacy, il n'a PAS le /up natif de Laravel 12.
HEALTH_URL="${HEALTH_URL:-https://chaps.lebackyard-africa.com/api/health}"
# Pas de -f : on veut le code HTTP même en erreur (sinon -w et le fallback se concatènent).
CODE=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 10 "$HEALTH_URL" || echo "000")
[ "$CODE" = "200" ] || die "Health check KO (HTTP $CODE sur $HEALTH_URL) — rollback : git reset --hard $CURRENT_SHA"

log "Déploiement terminé — $(git rev-parse --short HEAD)"
