#!/bin/bash

# Script de déploiement iOS automatisé pour GEOSECTOR
# Version: 1.0
# Date: 2025-12-05
# Auteur: Pierre (avec l'aide de Claude)
#
# Usage:
#   ./deploy-ios-full-auto.sh                    # Utilise ../VERSION
#   ./deploy-ios-full-auto.sh 3.6.0             # Version spécifique
#   ./deploy-ios-full-auto.sh 3.6.0 --skip-build # Skip Flutter build si déjà fait

set -euo pipefail

# =====================================
# Configuration
# =====================================

# Couleurs pour les messages
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Configuration Mac mini
MAC_MINI_HOST="minipi4"  # Nom défini dans ~/.ssh/config
MAC_BASE_DIR="/Users/pierre/dev/geosector"

# Timestamp pour logs et archives
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="./logs/deploy-ios-${TIMESTAMP}.log"
mkdir -p ./logs

# Variables globales pour le rapport
STEP_START_TIME=0
TOTAL_START_TIME=$(date +%s)
ERRORS_COUNT=0
WARNINGS_COUNT=0

# =====================================
# Fonctions utilitaires
# =====================================

log() {
    echo -e "$1" | tee -a "${LOG_FILE}"
}

log_step() {
    STEP_START_TIME=$(date +%s)
    log "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    log "${CYAN}▶ $1${NC}"
    log "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}

log_substep() {
    log "${MAGENTA}  ➜ $1${NC}"
}

log_info() {
    log "${BLUE}ℹ ${NC}$1"
}

log_success() {
    local elapsed=$(($(date +%s) - STEP_START_TIME))
    log "${GREEN}✓${NC} $1 ${CYAN}(${elapsed}s)${NC}"
}

log_warning() {
    ((WARNINGS_COUNT++))
    log "${YELLOW}⚠ ${NC}$1"
}

log_error() {
    ((ERRORS_COUNT++))
    log "${RED}✗${NC} $1"
}

log_fatal() {
    log_error "$1"
    log "\n${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    log "${RED}DÉPLOIEMENT ÉCHOUÉ${NC}"
    log "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    log_error "Consultez le log: ${LOG_FILE}"
    exit 1
}

# Fonction pour exécuter une commande et capturer les erreurs
safe_exec() {
    local cmd="$1"
    local error_msg="$2"

    if ! eval "$cmd" >> "${LOG_FILE}" 2>&1; then
        log_fatal "$error_msg"
    fi
}

# Fonction pour exécuter une commande SSH avec gestion d'erreurs
ssh_exec() {
    local cmd="$1"
    local error_msg="$2"

    if ! ssh "$MAC_MINI_HOST" "$cmd" >> "${LOG_FILE}" 2>&1; then
        log_fatal "$error_msg"
    fi
}

# =====================================
# En-tête
# =====================================

clear
log "${BLUE}╔════════════════════════════════════════════════════════╗${NC}"
log "${BLUE}║                                                        ║${NC}"
log "${BLUE}║       ${GREEN}🍎 DÉPLOIEMENT iOS AUTOMATISÉ${BLUE}                 ║${NC}"
log "${BLUE}║           ${CYAN}GEOSECTOR - Full Automation${BLUE}                ║${NC}"
log "${BLUE}║                                                        ║${NC}"
log "${BLUE}╚════════════════════════════════════════════════════════╝${NC}"
log ""
log_info "Démarrage: $(date '+%Y-%m-%d %H:%M:%S')"
log_info "Log file: ${LOG_FILE}"
log ""

# =====================================
# Étape 1 : Gestion de la version
# =====================================

log_step "ÉTAPE 1/8 : Gestion de la version"

# Déterminer la version à utiliser
if [ "${1:-}" != "" ] && [[ ! "${1}" =~ ^-- ]]; then
    VERSION="$1"
    log_info "Version fournie en argument: ${VERSION}"
else
    # Lire depuis ../VERSION
    if [ ! -f ../VERSION ]; then
        log_fatal "Fichier ../VERSION introuvable et aucune version fournie"
    fi
    VERSION=$(cat ../VERSION | tr -d '\n\r ' | tr -d '[:space:]')
    log_info "Version lue depuis ../VERSION: ${VERSION}"
fi

# Vérifier le format de version
if ! [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
    log_fatal "Format de version invalide: ${VERSION} (attendu: x.x.x)"
fi

# Calculer le build number
BUILD_NUMBER=$(echo $VERSION | tr -d '.')
FULL_VERSION="${VERSION}+${BUILD_NUMBER}"

log_success "Version configurée"
log_info "  Version name: ${GREEN}${VERSION}${NC}"
log_info "  Build number: ${GREEN}${BUILD_NUMBER}${NC}"
log_info "  Full version: ${GREEN}${FULL_VERSION}${NC}"

# =====================================
# Étape 2 : Mise à jour pubspec.yaml
# =====================================

log_step "ÉTAPE 2/8 : Mise à jour pubspec.yaml"

# Backup du pubspec.yaml
cp pubspec.yaml pubspec.yaml.backup

# Mise à jour de la version
sed -i "s/^version: .*/version: $FULL_VERSION/" pubspec.yaml

# Vérifier la mise à jour
UPDATED_VERSION=$(grep "^version:" pubspec.yaml | sed 's/version: //' | tr -d ' ')
if [ "$UPDATED_VERSION" != "$FULL_VERSION" ]; then
    log_fatal "Échec de la mise à jour de pubspec.yaml (attendu: $FULL_VERSION, obtenu: $UPDATED_VERSION)"
fi

log_success "pubspec.yaml mis à jour"

# =====================================
# Étape 3 : Préparation du projet
# =====================================

SKIP_BUILD=false
if [[ "${2:-}" == "--skip-build" ]]; then
    SKIP_BUILD=true
    log_warning "Mode --skip-build activé, Flutter build sera ignoré"
fi

if [ "$SKIP_BUILD" = false ]; then
    log_step "ÉTAPE 3/8 : Préparation du projet Flutter"

    log_substep "Configuration du cache local"
    export PUB_CACHE="$PWD/.pub-cache-local"
    export GRADLE_USER_HOME="$PWD/.gradle-local"
    mkdir -p "$PUB_CACHE" "$GRADLE_USER_HOME"
    log_info "  Cache Pub: $PUB_CACHE"
    log_info "  Cache Gradle: $GRADLE_USER_HOME"

    log_substep "Nettoyage du projet"
    safe_exec "flutter clean" "Échec du nettoyage Flutter"

    log_substep "Récupération des dépendances"
    safe_exec "flutter pub get" "Échec de flutter pub get"

    log_substep "Application du patch nfc_manager"
    safe_exec "./fastlane/scripts/commun/fix-nfc-manager.sh" "Échec du patch nfc_manager"

    log_substep "Application du patch permission_handler (si nécessaire)"
    if [ -f "./fastlane/scripts/commun/fix-permission-handler.sh" ]; then
        safe_exec "./fastlane/scripts/commun/fix-permission-handler.sh" "Échec du patch permission_handler"
    fi

    log_substep "Génération des fichiers Hive"
    safe_exec "dart run build_runner build --delete-conflicting-outputs" "Échec de la génération de code"

    log_success "Projet préparé (dépendances + patchs + génération de code)"
    log_info "  ⚠️  Build iOS sera fait sur le Mac mini via Fastlane"
else
    log_step "ÉTAPE 3/8 : Préparation du projet (BUILD SKIPPED)"

    log_substep "Configuration du cache local uniquement"
    export PUB_CACHE="$PWD/.pub-cache-local"
    export GRADLE_USER_HOME="$PWD/.gradle-local"

    if [ ! -d "$PUB_CACHE" ]; then
        log_warning "Cache local introuvable, le build pourrait échouer sur le Mac mini"
    fi

    log_success "Cache configuré (build Flutter ignoré)"
fi

# =====================================
# Étape 4 : Vérification de la connexion Mac mini
# =====================================

log_step "ÉTAPE 4/8 : Connexion au Mac mini"

log_substep "Test de connexion SSH à ${MAC_MINI_HOST}"

if ! ssh "$MAC_MINI_HOST" "echo 'Connection OK'" >> "${LOG_FILE}" 2>&1; then
    log_fatal "Impossible de se connecter au Mac mini (${MAC_MINI_HOST})"
fi

log_success "Connexion SSH établie"

# Vérifier l'environnement Mac
log_substep "Vérification de l'environnement Mac"
MAC_INFO=$(ssh "$MAC_MINI_HOST" "sw_vers -productVersion && xcodebuild -version | head -1 && flutter --version | head -1" 2>/dev/null || echo "N/A")
log_info "$(echo "$MAC_INFO" | head -1 | xargs -I {} echo "  macOS: {}")"
log_info "$(echo "$MAC_INFO" | sed -n '2p' | xargs -I {} echo "  Xcode: {}")"
log_info "$(echo "$MAC_INFO" | sed -n '3p' | xargs -I {} echo "  Flutter: {}")"

# =====================================
# Étape 5 : Transfert vers Mac mini
# =====================================

log_step "ÉTAPE 5/8 : Transfert du projet vers Mac mini"

DEST_DIR="${MAC_BASE_DIR}/app_${BUILD_NUMBER}"

log_substep "Création du dossier de destination: ${DEST_DIR}"
ssh_exec "mkdir -p ${DEST_DIR}" "Impossible de créer le dossier ${DEST_DIR} sur le Mac mini"

log_substep "Transfert rsync (peut prendre 2-5 minutes)"
TRANSFER_START=$(date +%s)

rsync -avz --progress \
  --exclude='build/' \
  --exclude='.dart_tool/' \
  --exclude='ios/Pods/' \
  --exclude='ios/.symlinks/' \
  --exclude='macos/Pods/' \
  --exclude='linux/flutter/ephemeral/' \
  --exclude='windows/flutter/ephemeral/' \
  --exclude='android/build/' \
  --exclude='*.aab' \
  --exclude='*.apk' \
  --exclude='logs/' \
  --exclude='*.log' \
  ./ "${MAC_MINI_HOST}:${DEST_DIR}/" >> "${LOG_FILE}" 2>&1 || log_fatal "Échec du transfert rsync"

TRANSFER_TIME=$(($(date +%s) - TRANSFER_START))

log_success "Transfert terminé"
log_info "  Destination: ${DEST_DIR}"
log_info "  Durée: ${TRANSFER_TIME}s"

# =====================================
# Étape 6 : Build et Archive avec Fastlane
# =====================================

log_step "ÉTAPE 6/8 : Build et Archive iOS avec Fastlane"

log_info "Cette étape peut prendre 15-25 minutes"
log_info "Fastlane va :"
log_info "  1. Nettoyer les artefacts"
log_info "  2. Installer les CocoaPods"
log_info "  3. Analyser le code"
log_info "  4. Build Flutter iOS"
log_info "  5. Archive Xcode (gym)"
log_info "  6. Export IPA"
log_info ""
log_substep "Lancement de: cd ${DEST_DIR} && fastlane ios build"

FASTLANE_START=$(date +%s)

# Créer un fichier temporaire pour capturer la sortie Fastlane
FASTLANE_LOG="/tmp/fastlane-ios-${TIMESTAMP}.log"

# Exécuter Fastlane en temps réel avec affichage des étapes importantes
ssh -t "$MAC_MINI_HOST" "cd ${DEST_DIR} && /opt/homebrew/bin/fastlane ios build" 2>&1 | tee -a "${LOG_FILE}" | tee "${FASTLANE_LOG}" | while IFS= read -r line; do
    # Afficher les lignes importantes
    if echo "$line" | grep -qE "(🧹|📦|🔧|🔍|🏗️|✓|✗|Error|error:|ERROR|Build succeeded|Build failed)"; then
        echo -e "${CYAN}  ${line}${NC}"
    fi
done

# Vérifier le code de retour de Fastlane
FASTLANE_EXIT_CODE=${PIPESTATUS[0]}
FASTLANE_TIME=$(($(date +%s) - FASTLANE_START))

if [ $FASTLANE_EXIT_CODE -ne 0 ]; then
    log_error "Fastlane a échoué (code: ${FASTLANE_EXIT_CODE})"
    log_error "Analyse des erreurs..."

    # Extraire les erreurs du log Fastlane
    if [ -f "${FASTLANE_LOG}" ]; then
        log ""
        log "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        log "${RED}ERREURS DÉTECTÉES :${NC}"
        log "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        grep -i "error:\|Error:\|ERROR:\|❌\|✗" "${FASTLANE_LOG}" | head -20 | while IFS= read -r error_line; do
            log "${RED}  ${error_line}${NC}"
        done
        log "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
    fi

    log_fatal "Build iOS échoué via Fastlane. Consultez ${FASTLANE_LOG} pour plus de détails."
fi

log_success "Build et Archive iOS réussis"
log_info "  Durée totale Fastlane: ${FASTLANE_TIME}s ($((FASTLANE_TIME/60))m $((FASTLANE_TIME%60))s)"

# Vérifier que l'IPA existe
log_substep "Vérification de l'IPA généré"
IPA_EXISTS=$(ssh "$MAC_MINI_HOST" "test -f ${DEST_DIR}/build/ios/ipa/Runner.ipa && echo 'YES' || echo 'NO'")

if [ "$IPA_EXISTS" != "YES" ]; then
    log_fatal "IPA non trouvé dans ${DEST_DIR}/build/ios/ipa/Runner.ipa"
fi

IPA_SIZE=$(ssh "$MAC_MINI_HOST" "du -h ${DEST_DIR}/build/ios/ipa/Runner.ipa | cut -f1")
log_info "  IPA trouvé: ${GREEN}${IPA_SIZE}${NC}"

# =====================================
# Étape 7 : Upload vers TestFlight (optionnel)
# =====================================

log_step "ÉTAPE 7/8 : Upload vers TestFlight"

log ""
log_info "${YELLOW}Voulez-vous uploader l'IPA vers TestFlight maintenant ?${NC}"
log_info "  [Y] Oui - Upload automatique via fastlane ios upload"
log_info "  [N] Non - Je ferai l'upload manuellement plus tard"
log ""

read -p "$(echo -e ${CYAN}Votre choix [Y/n]: ${NC})" -n 1 -r UPLOAD_CHOICE
echo
log ""

if [[ $UPLOAD_CHOICE =~ ^[Yy]$ ]] || [ -z "$UPLOAD_CHOICE" ]; then
    log_substep "Lancement de: fastlane ios upload"
    log_info "Upload vers TestFlight (peut prendre 5-10 minutes)"

    UPLOAD_START=$(date +%s)

    ssh -t "$MAC_MINI_HOST" "cd ${DEST_DIR} && /opt/homebrew/bin/fastlane ios upload" 2>&1 | tee -a "${LOG_FILE}"
    UPLOAD_EXIT_CODE=${PIPESTATUS[0]}
    UPLOAD_TIME=$(($(date +%s) - UPLOAD_START))

    if [ $UPLOAD_EXIT_CODE -ne 0 ]; then
        log_error "Upload TestFlight échoué (code: ${UPLOAD_EXIT_CODE})"
        log_warning "L'IPA est disponible sur le Mac mini, vous pouvez réessayer manuellement"
        log_info "  Commande: ssh $MAC_USER@$MAC_MINI_IP \"cd ${DEST_DIR} && fastlane ios upload\""
    else
        log_success "Upload TestFlight réussi"
        log_info "  Durée: ${UPLOAD_TIME}s"
        log_info "  URL: ${CYAN}https://appstoreconnect.apple.com${NC}"
    fi
else
    log_info "Upload ignoré. Pour uploader manuellement plus tard :"
    log_info "  ${CYAN}ssh $MAC_MINI_HOST \"cd ${DEST_DIR} && /opt/homebrew/bin/fastlane ios upload\"${NC}"
fi

# =====================================
# Étape 8 : Nettoyage et archivage
# =====================================

log_step "ÉTAPE 8/8 : Nettoyage et archivage"

log_substep "Voulez-vous archiver le dossier de build ?"
log_info "  [Y] Oui - Créer une archive ${DEST_DIR}.tar.gz"
log_info "  [N] Non - Garder le dossier tel quel (défaut)"
log ""

read -p "$(echo -e ${CYAN}Votre choix [y/N]: ${NC})" -n 1 -r ARCHIVE_CHOICE
echo
log ""

if [[ $ARCHIVE_CHOICE =~ ^[Yy]$ ]]; then
    log_substep "Création de l'archive..."
    ssh_exec "cd ${MAC_BASE_DIR} && tar -czf app_${BUILD_NUMBER}.tar.gz app_${BUILD_NUMBER}" \
        "Échec de la création de l'archive"

    ARCHIVE_SIZE=$(ssh "$MAC_MINI_HOST" "du -h ${MAC_BASE_DIR}/app_${BUILD_NUMBER}.tar.gz | cut -f1")
    log_success "Archive créée"
    log_info "  Archive: ${MAC_BASE_DIR}/app_${BUILD_NUMBER}.tar.gz (${ARCHIVE_SIZE})"

    log_substep "Suppression du dossier de build"
    ssh_exec "rm -rf ${DEST_DIR}" "Échec de la suppression du dossier"
    log_success "Dossier de build supprimé"
else
    log_info "Dossier conservé: ${DEST_DIR}"
fi

# Restaurer le pubspec.yaml original (optionnel)
log_substep "Restauration de pubspec.yaml local"
mv pubspec.yaml.backup pubspec.yaml
log_info "  pubspec.yaml local restauré à son état initial"

# =====================================
# Rapport final
# =====================================

TOTAL_TIME=$(($(date +%s) - TOTAL_START_TIME))
TOTAL_MINUTES=$((TOTAL_TIME / 60))
TOTAL_SECONDS=$((TOTAL_TIME % 60))

log ""
log "${GREEN}╔════════════════════════════════════════════════════════╗${NC}"
log "${GREEN}║                                                        ║${NC}"
log "${GREEN}║       ✓ DÉPLOIEMENT iOS TERMINÉ AVEC SUCCÈS           ║${NC}"
log "${GREEN}║                                                        ║${NC}"
log "${GREEN}╚════════════════════════════════════════════════════════╝${NC}"
log ""
log "${CYAN}📊 RAPPORT DE DÉPLOIEMENT${NC}"
log "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
log ""
log "  ${BLUE}Version déployée:${NC}    ${GREEN}${VERSION} (Build ${BUILD_NUMBER})${NC}"
log "  ${BLUE}Destination:${NC}         ${DEST_DIR}"
log "  ${BLUE}IPA généré:${NC}          ${GREEN}${IPA_SIZE}${NC}"
log "  ${BLUE}Durée totale:${NC}        ${GREEN}${TOTAL_MINUTES}m ${TOTAL_SECONDS}s${NC}"
log ""
if [ $WARNINGS_COUNT -gt 0 ]; then
    log "  ${YELLOW}⚠  Avertissements:${NC}    ${WARNINGS_COUNT}"
fi
if [ $ERRORS_COUNT -gt 0 ]; then
    log "  ${RED}✗  Erreurs:${NC}           ${ERRORS_COUNT}"
fi
log ""
log "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
log ""
log "${BLUE}📱 PROCHAINES ÉTAPES${NC}"
log "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
log ""

if [[ $UPLOAD_CHOICE =~ ^[Yy]$ ]] || [ -z "$UPLOAD_CHOICE" ]; then
    if [ $UPLOAD_EXIT_CODE -eq 0 ]; then
        log "  1. ${GREEN}✓${NC} IPA uploadé sur TestFlight"
        log "  2. Accéder à App Store Connect:"
        log "     ${CYAN}https://appstoreconnect.apple.com${NC}"
        log "  3. Attendre le traitement Apple (5-15 min)"
        log "  4. Configurer la conformité export si demandée"
        log "  5. Ajouter des testeurs internes"
        log "  6. Installer via TestFlight sur iPhone"
    else
        log "  1. ${YELLOW}⚠${NC} Upload TestFlight a échoué"
        log "  2. Réessayer manuellement:"
        log "     ${CYAN}ssh $MAC_USER@$MAC_MINI_IP \"cd ${DEST_DIR} && fastlane ios upload\"${NC}"
    fi
else
    log "  1. L'IPA est prêt sur le Mac mini"
    log "  2. Pour uploader vers TestFlight:"
    log "     ${CYAN}ssh $MAC_USER@$MAC_MINI_IP \"cd ${DEST_DIR} && fastlane ios upload\"${NC}"
    log "  3. Ou distribuer l'IPA manuellement via Xcode"
fi

log ""
log "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
log ""
log "  ${BLUE}Log complet:${NC}  ${LOG_FILE}"
log "  ${BLUE}Fin:${NC}          $(date '+%Y-%m-%d %H:%M:%S')"
log ""

# Nettoyer le log Fastlane temporaire
rm -f "${FASTLANE_LOG}"

exit 0
