# Fastfile pour GEOSECTOR Flutter App
# Version: 2.0
# Date: 2025-10-26
# Auteur: Pierre (avec l'aide de Claude)
#
# Usage depuis le Mac mini (après transfert depuis Debian):
#   cd /Users/pierre/dev/geosector/app_346
#   fastlane android build     # Build seulement (test local)
#   fastlane android release   # Build + Upload vers Play Store
#   fastlane ios build         # Build iOS seulement (test local)
#   fastlane ios release       # Build + Upload vers TestFlight

default_platform(:android)

# Configure PATH pour Homebrew (M1/M2/M4 Mac)
ENV['PATH'] = "/opt/homebrew/bin:#{ENV['PATH']}"

# =============================================================================
# ANDROID
# =============================================================================

platform :android do

  desc "Build Android AAB (bundle) en mode release - sans upload"
  lane :build do
    UI.header("🤖 Build Android Bundle")

    # Étape 1 : Nettoyer le projet
    UI.message("🧹 [1/6] Nettoyage du projet...")
    sh("cd .. && flutter clean")
    UI.success("Projet nettoyé")

    # Étape 2 : Récupérer les dépendances
    UI.message("📦 [2/6] Récupération des dépendances...")
    sh("cd .. && flutter pub get")
    UI.success("Dépendances récupérées")

    # Étape 3 : Patch nfc_manager
    UI.message("🔧 [3/6] Application du patch nfc_manager...")
    sh("cd .. && ./fastlane/scripts/commun/fix-nfc-manager.sh")
    UI.success("Patch nfc_manager appliqué")

    # Étape 4 : Analyser le code (non bloquant)
    UI.message("🔍 [4/6] Analyse du code...")
    begin
      sh("cd .. && flutter analyze --no-fatal-infos --no-fatal-warnings")
      UI.success("Analyse du code terminée")
    rescue => ex
      UI.important("⚠️  Des warnings détectés, mais on continue...")
    end

    # Étape 5 : Build du bundle AAB
    UI.message("🏗️  [5/6] Build du bundle Android (RELEASE)...")
    sh("cd .. && flutter build appbundle --release")
    UI.success("Bundle AAB généré")

    # Étape 6 : Copier le bundle avec version
    UI.message("📋 [6/6] Copie du bundle avec version...")
    version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
    version_code = version_info.split('+').last
    final_name = "geosector-#{version_code}.aab"

    sh("cd .. && cp build/app/outputs/bundle/release/app-release.aab #{final_name}")

    bundle_size = sh("cd .. && du -h #{final_name} | cut -f1").strip

    UI.success("✅ Build Android terminé avec succès!")
    UI.success("📦 Bundle: #{final_name}")
    UI.success("📊 Taille: #{bundle_size}")
  end

  desc "Build Android AAB + Upload vers Google Play Console (Internal Testing)"
  lane :release do
    UI.header("🚀 Build & Deploy Android vers Play Store")

    # Étape 1 : Nettoyer le projet
    UI.message("🧹 [1/7] Nettoyage du projet...")
    sh("cd .. && flutter clean")
    UI.success("Projet nettoyé")

    # Étape 2 : Récupérer les dépendances
    UI.message("📦 [2/7] Récupération des dépendances...")
    sh("cd .. && flutter pub get")
    UI.success("Dépendances récupérées")

    # Étape 3 : Patch nfc_manager
    UI.message("🔧 [3/7] Application du patch nfc_manager...")
    sh("cd .. && ./fastlane/scripts/commun/fix-nfc-manager.sh")
    UI.success("Patch nfc_manager appliqué")

    # Étape 4 : Analyser le code (non bloquant)
    UI.message("🔍 [4/7] Analyse du code...")
    begin
      sh("cd .. && flutter analyze --no-fatal-infos --no-fatal-warnings")
      UI.success("Analyse du code terminée")
    rescue => ex
      UI.important("⚠️  Des warnings détectés, mais on continue...")
    end

    # Étape 5 : Build du bundle AAB
    UI.message("🏗️  [5/7] Build du bundle Android (RELEASE)...")
    sh("cd .. && flutter build appbundle --release")
    UI.success("Bundle AAB généré")

    # Étape 6 : Récupérer les informations de version
    version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
    version_name = version_info.split('+').first
    version_code = version_info.split('+').last

    UI.message("📋 Version: #{version_name} (#{version_code})")

    # Étape 7 : Upload vers Google Play Console
    UI.message("📤 [6/7] Upload vers Google Play Console...")

    upload_to_play_store(
      json_key: '../android/google-play-api-key.json',  # Credentials Google Play API
      track: 'internal',                    # Track: internal, alpha, beta, ou production
      aab: '../build/app/outputs/bundle/release/app-release.aab',
      skip_upload_apk: true,                # On n'upload que l'AAB
      skip_upload_metadata: true,           # On ne met pas à jour les métadonnées
      skip_upload_images: true,             # On ne met pas à jour les images
      skip_upload_screenshots: true,        # On ne met pas à jour les screenshots
      release_status: 'completed',          # completed = publié immédiatement sur le track
      version_code: version_code.to_i,      # Version code explicite
      package_name: 'fr.geosector.app3'     # Package name explicite
    )

    UI.success("✅ Déploiement Android terminé avec succès!")
    UI.success("📦 Version: #{version_name} (Build #{version_code})")
    UI.success("🎯 Track: Internal Testing")
    UI.success("🌐 URL: https://play.google.com/console")
  end

  desc "Upload un AAB existant vers Google Play Console"
  lane :upload do
    UI.header("📤 Upload AAB vers Play Store")

    # Vérifier que le bundle existe
    aab_path = '../build/app/outputs/bundle/release/app-release.aab'

    if File.exist?(aab_path)
      # Récupérer la version
      version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
      version_code = version_info.split('+').last

      UI.message("📦 Upload du bundle existant...")

      upload_to_play_store(
        json_key: '../android/google-play-api-key.json',
        track: 'internal',
        aab: aab_path,
        skip_upload_apk: true,
        skip_upload_metadata: true,
        skip_upload_images: true,
        skip_upload_screenshots: true,
        release_status: 'completed',
        version_code: version_code.to_i,
        package_name: 'fr.geosector.app3'
      )

      UI.success("✅ Upload terminé!")
    else
      UI.user_error!("❌ Bundle introuvable: #{aab_path}")
      UI.message("💡 Lancez d'abord: fastlane android build")
    end
  end

end

# =============================================================================
# iOS
# =============================================================================

platform :ios do

  desc "Build iOS IPA en mode release - sans upload"
  lane :build do
    UI.header("🍎 Build iOS IPA")

    # Étape 1 : Vérifier le cache local (préparé sur Debian)
    UI.message("📦 [1/6] Vérification du cache local...")

    cache_path = File.expand_path("../.pub-cache-local")
    if !Dir.exist?(cache_path)
      UI.user_error!("❌ Cache local introuvable: #{cache_path}")
      UI.message("💡 Exécutez './deploy-app.sh' sur Debian pour préparer le projet")
    end

    ENV['PUB_CACHE'] = cache_path
    ENV['GRADLE_USER_HOME'] = File.expand_path("../.gradle-local")

    UI.success("Cache local configuré: #{cache_path}")
    UI.important("⚠️  flutter pub get et patchs déjà appliqués sur Debian")

    # Étape 2 : Nettoyer les artefacts de build
    UI.message("🧹 [2/6] Nettoyage des artefacts...")
    sh("cd .. && rm -rf build .dart_tool ios/Pods ios/.symlinks")
    UI.success("Artefacts nettoyés")

    # Étape 3 : Installation des pods
    UI.message("📦 [3/6] Installation des CocoaPods...")
    sh("cd ../ios && pod install")
    UI.success("CocoaPods installés")

    # Étape 4 : Analyser le code (non bloquant)
    UI.message("🔍 [4/6] Analyse du code...")
    begin
      sh("cd .. && flutter analyze --no-fatal-infos --no-fatal-warnings")
      UI.success("Analyse du code terminée")
    rescue => ex
      UI.important("⚠️  Des warnings détectés, mais on continue...")
    end

    # Étape 5 : Build Flutter iOS
    UI.message("🏗️  [5/6] Build Flutter iOS (RELEASE)...")
    sh("cd .. && flutter build ios --release --no-codesign")
    UI.success("Build Flutter iOS généré")

    # Étape 6 : Archive Xcode (gym)
    UI.message("📦 [6/6] Archive Xcode et export IPA...")

    build_ios_app(
      workspace: "./Runner.xcworkspace",
      scheme: "Runner",
      export_method: "app-store",
      export_options: {
        method: "app-store",
        teamID: "6WT84NWCTC",
        uploadBitcode: false,
        uploadSymbols: true,
        compileBitcode: false,
        signingStyle: "automatic",
        destination: "export",
        provisioningProfiles: {
          "fr.geosector.app3" => "match AppStore fr.geosector.app3"
        }
      },
      output_directory: "../build/ios/ipa",
      output_name: "Runner.ipa",
      clean: false,
      skip_profile_detection: true
    )

    UI.success("IPA généré")

    # Afficher les informations de version
    version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
    ipa_size = sh("cd .. && du -h build/ios/ipa/Runner.ipa | cut -f1").strip

    UI.success("✅ Build iOS terminé avec succès!")
    UI.success("📦 IPA: build/ios/ipa/Runner.ipa")
    UI.success("📊 Version: #{version_info}")
    UI.success("📊 Taille: #{ipa_size}")
  end

  desc "Build iOS IPA + Upload vers TestFlight"
  lane :release do
    UI.header("🚀 Build & Deploy iOS vers TestFlight")

    # Étape 1 : Vérifier le cache local (préparé sur Debian)
    UI.message("📦 [1/7] Vérification du cache local...")

    cache_path = File.expand_path("../.pub-cache-local")
    if !Dir.exist?(cache_path)
      UI.user_error!("❌ Cache local introuvable: #{cache_path}")
      UI.message("💡 Exécutez './deploy-app.sh' sur Debian pour préparer le projet")
    end

    ENV['PUB_CACHE'] = cache_path
    ENV['GRADLE_USER_HOME'] = File.expand_path("../.gradle-local")

    UI.success("Cache local configuré: #{cache_path}")
    UI.important("⚠️  flutter pub get et patchs déjà appliqués sur Debian")

    # Étape 2 : Nettoyer les artefacts de build
    UI.message("🧹 [2/7] Nettoyage des artefacts...")
    sh("cd .. && rm -rf build .dart_tool ios/Pods ios/.symlinks")
    UI.success("Artefacts nettoyés")

    # Étape 3 : Installation des pods
    UI.message("📦 [3/7] Installation des CocoaPods...")
    sh("cd ../ios && pod install")
    UI.success("CocoaPods installés")

    # Étape 4 : Récupérer les informations de version
    version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
    version_name = version_info.split('+').first
    version_code = version_info.split('+').last

    UI.message("📋 Version: #{version_name} (#{version_code})")

    # Étape 5 : Analyser le code (non bloquant)
    UI.message("🔍 [4/7] Analyse du code...")
    begin
      sh("cd .. && flutter analyze --no-fatal-infos --no-fatal-warnings")
      UI.success("Analyse du code terminée")
    rescue => ex
      UI.important("⚠️  Des warnings détectés, mais on continue...")
    end

    # Étape 6 : Build Flutter iOS
    UI.message("🏗️  [5/7] Build Flutter iOS (RELEASE)...")
    sh("cd .. && flutter build ios --release --no-codesign")
    UI.success("Build Flutter iOS généré")

    # Étape 7 : Archive Xcode
    UI.message("📦 [6/7] Archive Xcode...")

    build_ios_app(
      workspace: "./Runner.xcworkspace",
      scheme: "Runner",
      export_method: "app-store",
      export_options: {
        method: "app-store",
        teamID: "6WT84NWCTC",
        uploadBitcode: false,
        uploadSymbols: true,
        compileBitcode: false,
        signingStyle: "automatic",
        provisioningProfiles: {
          "fr.geosector.app3" => "match AppStore fr.geosector.app3"
        }
      },
      output_directory: "../build/ios/ipa",
      output_name: "Runner.ipa",
      clean: false,
      skip_profile_detection: true
    )

    UI.success("IPA généré")

    # Étape 7 : Upload vers TestFlight
    UI.message("📤 [7/7] Upload vers TestFlight...")

    upload_to_testflight(
      apple_id: "contact@d6soft.com",
      app_identifier: "fr.geosector.app3",
      team_id: "6WT84NWCTC",
      ipa: "../build/ios/ipa/Runner.ipa",
      skip_waiting_for_build_processing: true,
      skip_submission: true,
      distribute_external: false
    )

    UI.success("✅ Déploiement iOS terminé avec succès!")
    UI.success("📦 Version: #{version_name} (Build #{version_code})")
    UI.success("🎯 Track: TestFlight (Internal)")
    UI.success("🌐 URL: https://appstoreconnect.apple.com")
  end

  desc "Upload un IPA existant vers TestFlight"
  lane :upload do
    UI.header("📤 Upload IPA vers TestFlight")

    # Vérifier que l'IPA existe
    ipa_path = '../build/ios/ipa/Runner.ipa'

    if File.exist?(ipa_path)
      # Récupérer la version
      version_info = sh("cd .. && grep '^version:' pubspec.yaml | sed 's/version: //'").strip
      version_name = version_info.split('+').first
      version_code = version_info.split('+').last

      UI.message("📦 Upload de l'IPA existant...")

      upload_to_testflight(
        apple_id: "contact@d6soft.com",
        app_identifier: "fr.geosector.app3",
        team_id: "6WT84NWCTC",
        ipa: ipa_path,
        skip_waiting_for_build_processing: true,
        skip_submission: true,
        distribute_external: false
      )

      UI.success("✅ Upload terminé!")
      UI.success("📦 Version: #{version_name} (Build #{version_code})")
    else
      UI.user_error!("❌ IPA introuvable: #{ipa_path}")
      UI.message("💡 Lancez d'abord: fastlane ios build")
    end
  end

end
