/**
 * ============================================================================
 * PIPELINE CI/CD - THÉ TIP TOP FRONTEND
 * ============================================================================
 *
 * Ce pipeline automatise le processus de déploiement continu du frontend.
 *
 * ÉTAPES DU PIPELINE :
 * 1. Init          - Détection de l'environnement (dev/preprod/prod)
 * 2. Checkout      - Récupération du code source depuis Git
 * 3. Install       - Installation des dépendances Node.js
 * 4. Lint & Tests  - ESLint + Jest avec couverture de code
 * 5. SonarQube     - Analyse statique avec rapport de couverture
 * 6. Build         - Construction de l'image Docker (avec variables env)
 * 7. Push          - Envoi de l'image vers le registre Docker privé
 * 8. Deploy        - Déploiement sur le serveur cible
 *
 * ENVIRONNEMENTS :
 * - dev     : Développement (branche dev)
 * - preprod : Pré-production (branche preprod)
 * - prod    : Production (branche main)
 *
 * TECHNOLOGIE : Next.js 14 avec React 18
 *
 * ============================================================================
 */

pipeline {
    agent any

    // =========================================================================
    // DÉCLENCHEUR : Vérifie les changements Git chaque minute
    // =========================================================================
    triggers {
        pollSCM('* * * * *')
    }

    // =========================================================================
    // PARAMÈTRES : Permet de choisir manuellement l'environnement
    // =========================================================================
    parameters {
        choice(
            name: 'ENV',
            choices: ['dev', 'preprod', 'prod'],
            description: 'Choisir l environnement de deploiement'
        )
    }

    // =========================================================================
    // VARIABLES D'ENVIRONNEMENT GLOBALES
    // =========================================================================
    environment {
        REGISTRY_URL = "registry.wk-archi-o24a-15m-g3.fr"
        IMAGE_NAME = "the-tip-top-frontend"
        NPM_CACHE = "/var/jenkins_home/npm-cache"
    }

    stages {

        // =====================================================================
        // ÉTAPE 1 : INITIALISATION
        // ---------------------------------------------------------------------
        // But : Détecter automatiquement l'environnement selon la branche Git
        // - Branche 'dev'     → Environnement dev
        // - Branche 'preprod' → Environnement preprod
        // - Branche 'main'    → Environnement prod
        // =====================================================================
        stage('🧭 Init - Détection environnement') {
            steps {
                script {
                    def currentBranch = sh(script: "git rev-parse --abbrev-ref HEAD", returnStdout: true).trim()
                    echo "🧭 Branche détectée : ${currentBranch}"

                    if (["dev", "preprod", "main"].contains(currentBranch)) {
                        env.ENV = (currentBranch == "main") ? "prod" : currentBranch
                    } else {
                        env.ENV = params.ENV ?: "dev"
                    }

                    env.TAG = "${env.ENV}-latest"
                    env.DEPLOY_PATH = "/srv/devops/the-tip-top/${env.ENV}"

                    echo """
                    ╔══════════════════════════════════════════╗
                    ║         CONFIGURATION PIPELINE           ║
                    ╠══════════════════════════════════════════╣
                    ║ 🌍 Environnement    : ${env.ENV.padRight(18)} ║
                    ║ 🏷️  Tag Docker       : ${env.TAG.padRight(18)} ║
                    ║ 📂 Chemin déploie.  : ${env.DEPLOY_PATH.take(18).padRight(18)} ║
                    ╚══════════════════════════════════════════╝
                    """
                }
            }
        }

        // =====================================================================
        // ÉTAPE 2 : CHECKOUT
        // ---------------------------------------------------------------------
        // But : Récupérer le code source depuis le dépôt Gitea
        // Action : Clone ou pull du code selon l'état du workspace
        // =====================================================================
        stage('📦 Checkout - Récupération code source') {
            steps {
                echo "📦 Récupération du code source depuis Gitea..."
                checkout scm
                echo "✅ Code source récupéré avec succès"
            }
        }

        // =====================================================================
        // ÉTAPE 3 : INSTALLATION DES DÉPENDANCES
        // ---------------------------------------------------------------------
        // But : Installer les packages Node.js nécessaires
        // Container : node:20 (requis pour Next.js 14)
        // Commande : npm ci (installation propre depuis package-lock.json)
        // Cache : Utilise un cache NPM partagé pour accélérer les builds
        // =====================================================================
        stage('📦 Install - Dépendances Node.js') {
            agent {
                docker {
                    image 'node:20'
                    args "-u root -v ${NPM_CACHE}:/root/.npm"
                }
            }
            steps {
                echo "📦 Installation des dépendances Node.js..."
                sh 'npm ci --prefer-offline'
                stash includes: 'node_modules/**', name: 'node_modules'
                echo "✅ Dépendances installées avec succès"
            }
        }

        // =====================================================================
        // ÉTAPE 4 : SONARQUBE - Qualité de code
        // ---------------------------------------------------------------------
        // Analyse statique du code pour détecter :
        // - Bugs potentiels
        // - Vulnérabilités de sécurité
        // - Code smells (mauvaises pratiques)
        // - Duplications de code
        // =====================================================================
        stage('📊 SonarQube Analysis') {
            agent {
                docker {
                    image 'sonarsource/sonar-scanner-cli:latest'
                    args '-u root'
                }
            }
            steps {
                echo "📊 Analyse SonarQube - Qualité de code..."
                withSonarQubeEnv('SonarQube') {
                    sh """
                        sonar-scanner
                    """
                }
                echo "✅ Analyse SonarQube terminée"
            }
        }

        // =====================================================================
        // ÉTAPE 5 : LINT & TESTS
        // ---------------------------------------------------------------------
        // ESLint : Vérifie le style et les erreurs de code
        // Jest : Exécute les tests unitaires React/Next.js
        // Couverture : Génère un rapport de couverture (lcov)
        // =====================================================================
        stage('🧪 Lint & Tests') {
            agent {
                docker {
                    image 'node:20'
                    args "-u root -v ${NPM_CACHE}:/root/.npm"
                }
            }
            steps {
                unstash 'node_modules'
                echo "🧪 Lancement ESLint et Jest..."
                script {
                    def lintStatus = sh(script: 'npm run lint', returnStatus: true)
                    def testStatus = sh(script: 'npm test -- --coverage', returnStatus: true)

                    if (lintStatus != 0) {
                        error "❌ ESLint a échoué - Corrigez les erreurs de style"
                    }
                    if (testStatus != 0) {
                        error "❌ Les tests ont échoué - Vérifiez les tests unitaires"
                    }
                    echo "✅ Lint et tests passés avec succès"
                }
            }
        }

        // =====================================================================
        // ÉTAPE 6 : BUILD IMAGE DOCKER
        // ---------------------------------------------------------------------
        // But : Construire l'image Docker du frontend Next.js
        // Spécificité : Injection des variables NEXT_PUBLIC_* au build time
        // Variables lues depuis : .env.{dev|preprod|prod}
        // Tags créés :
        // - {env}-latest (ex: dev-latest, prod-latest)
        // - latest
        // =====================================================================
        stage('🐳 Build - Image Docker') {
            steps {
                echo "🐳 Construction de l'image Docker frontend Next.js..."
                script {
                    // Lecture des variables d'environnement NEXT_PUBLIC_*
                    def envFile = ".env.${env.ENV}"
                    def envVars = sh(script: "cat ${envFile} | grep -E '^NEXT_PUBLIC_' | xargs", returnStdout: true).trim()

                    // Construction des arguments de build Docker
                    def buildArgs = ""
                    envVars.split().each { envVar ->
                        def parts = envVar.split('=', 2)
                        if (parts.size() == 2) {
                            buildArgs += "--build-arg ${parts[0]}='${parts[1]}' "
                        }
                    }

                    sh """
                        docker build ${buildArgs} -t ${REGISTRY_URL}/${IMAGE_NAME}:${env.TAG} .
                        docker tag ${REGISTRY_URL}/${IMAGE_NAME}:${env.TAG} ${REGISTRY_URL}/${IMAGE_NAME}:latest
                    """
                }
                echo "✅ Image Docker construite : ${REGISTRY_URL}/${IMAGE_NAME}:${env.TAG}"
            }
        }

        // =====================================================================
        // ÉTAPE 7 : PUSH VERS LE REGISTRE
        // ---------------------------------------------------------------------
        // But : Envoyer l'image Docker vers le registre privé
        // Registre : registry.wk-archi-o24a-15m-g3.fr
        // Authentification : Credentials Jenkins sécurisés
        // =====================================================================
        stage('📤 Push - Registre Docker') {
            steps {
                echo "📤 Envoi de l'image vers le registre Docker privé..."
                withCredentials([usernamePassword(credentialsId: 'registry-credentials', usernameVariable: 'REG_USER', passwordVariable: 'REG_PASS')]) {
                    sh """
                        echo "$REG_PASS" | docker login ${REGISTRY_URL} -u "$REG_USER" --password-stdin
                        docker push ${REGISTRY_URL}/${IMAGE_NAME}:${env.TAG}
                        docker push ${REGISTRY_URL}/${IMAGE_NAME}:latest
                    """
                }
                echo "✅ Image envoyée avec succès vers ${REGISTRY_URL}"
            }
        }

        // =====================================================================
        // ÉTAPE 8 : DÉPLOIEMENT
        // ---------------------------------------------------------------------
        // But : Déployer le frontend sur le serveur cible
        // Actions :
        // 1. Pull de la nouvelle image depuis le registre
        // 2. Recréation du container avec la nouvelle image
        // Option : --no-deps pour ne pas redémarrer le backend
        // Chemins : /srv/devops/the-tip-top/{dev|preprod|prod}
        // =====================================================================
        stage('🚀 Deploy - Mise en production') {
            steps {
                echo "🚀 Déploiement du frontend sur l'environnement ${env.ENV}..."
                sh """
                    cd "${env.DEPLOY_PATH}"
                    docker compose pull frontend
                    docker compose up -d --no-deps --force-recreate frontend
                """
                echo "✅ Frontend déployé avec succès sur ${env.ENV}"
            }
        }
    }

    // =========================================================================
    // ACTIONS POST-PIPELINE
    // =========================================================================
    post {
        success {
            echo """
            ╔══════════════════════════════════════════╗
            ║     ✅ PIPELINE TERMINÉ AVEC SUCCÈS     ║
            ╠══════════════════════════════════════════╣
            ║ Environnement : ${env.ENV.padRight(23)} ║
            ║ Image         : ${IMAGE_NAME.padRight(23)} ║
            ║ Tag           : ${env.TAG.padRight(23)} ║
            ╚══════════════════════════════════════════╝
            """
            emailext(
                to: 'soufiane.baali99@gmail.com',
                subject: "✅ Pipeline Frontend SUCCÈS - ${env.ENV}",
                body: """
                    <h2 style="color: green;">✅ Pipeline Frontend terminé avec succès</h2>
                    <table border="1" cellpadding="10" style="border-collapse: collapse;">
                        <tr><td><strong>Projet</strong></td><td>${env.JOB_NAME}</td></tr>
                        <tr><td><strong>Build</strong></td><td>#${env.BUILD_NUMBER}</td></tr>
                        <tr><td><strong>Environnement</strong></td><td>${env.ENV}</td></tr>
                        <tr><td><strong>Image</strong></td><td>${IMAGE_NAME}:${env.TAG}</td></tr>
                        <tr><td><strong>Durée</strong></td><td>${currentBuild.durationString}</td></tr>
                    </table>
                    <p>🔗 <a href="${env.BUILD_URL}">Voir les détails du build</a></p>
                """,
                mimeType: 'text/html'
            )
        }
        failure {
            echo """
            ╔══════════════════════════════════════════╗
            ║        ❌ ÉCHEC DU PIPELINE             ║
            ╠══════════════════════════════════════════╣
            ║ Environnement : ${env.ENV.padRight(23)} ║
            ║ Vérifiez les logs pour plus de détails  ║
            ╚══════════════════════════════════════════╝
            """
            emailext(
                to: 'soufiane.baali99@gmail.com',
                subject: "❌ Pipeline Frontend ÉCHEC - ${env.ENV}",
                body: """
                    <h2 style="color: red;">❌ Pipeline Frontend a échoué</h2>
                    <table border="1" cellpadding="10" style="border-collapse: collapse;">
                        <tr><td><strong>Projet</strong></td><td>${env.JOB_NAME}</td></tr>
                        <tr><td><strong>Build</strong></td><td>#${env.BUILD_NUMBER}</td></tr>
                        <tr><td><strong>Environnement</strong></td><td>${env.ENV}</td></tr>
                        <tr><td><strong>Durée</strong></td><td>${currentBuild.durationString}</td></tr>
                    </table>
                    <p>🔗 <a href="${env.BUILD_URL}">Voir les logs du build</a></p>
                    <p>🔗 <a href="${env.BUILD_URL}console">Console Output</a></p>
                """,
                mimeType: 'text/html'
            )
        }
    }
}
