pipeline {
    agent { label 'appdev' }

    options {
        disableConcurrentBuilds()
        timestamps()
    }

    environment {
        PATH = "C:\\Program Files\\Microsoft SDKs\\Azure\\CLI2\\wbin;${env.PATH}"
    }

    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Restore & Build') {
            steps {
                bat 'dotnet restore PowderCoatingApp.sln'
                bat 'dotnet build PowderCoatingApp.sln -c Release --no-restore'
            }
        }

        stage('Test') {
            steps {
                bat 'dotnet test tests\\PowderCoating.UnitTests --no-build -c Release --logger "trx;LogFileName=results.trx" --results-directory TestResults'
            }
            post {
                always {
                    junit testResults: 'TestResults/*.trx', allowEmptyResults: true
                }
            }
        }

        stage('Run Migrations') {
            steps {
                bat 'dotnet tool install --global dotnet-ef 2>nul || dotnet tool update --global dotnet-ef 2>nul'
                withCredentials([string(credentialsId: 'pcl-prod-sql', variable: 'SQL_CONN')]) {
                    bat '"%USERPROFILE%\\.dotnet\\tools\\dotnet-ef.exe" database update --project src\\PowderCoating.Infrastructure --startup-project src\\PowderCoating.Web --configuration Release --no-build --context ApplicationDbContext --connection "%SQL_CONN%"'
                }
            }
        }

        stage('Publish') {
            steps {
                bat 'dotnet publish src\\PowderCoating.Web\\PowderCoating.Web.csproj -c Release -r linux-x64 --self-contained false -o publish'
                bat 'xcopy /E /Y /I src\\PowderCoating.Web\\wwwroot publish\\wwwroot\\'
            }
        }

        stage('Deploy to Azure') {
            steps {
                powershell '''
                    Add-Type -Assembly System.IO.Compression.FileSystem
                    if (Test-Path deploy.zip) { Remove-Item deploy.zip }
                    $publishDir = (Resolve-Path "publish").Path
                    $zip = [System.IO.Compression.ZipFile]::Open("deploy.zip", "Create")
                    Get-ChildItem -Path $publishDir -Recurse -File | ForEach-Object {
                        $entryName = $_.FullName.Substring($publishDir.Length + 1).Replace("\\", "/")
                        [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zip, $_.FullName, $entryName, "Optimal") | Out-Null
                    }
                    $zip.Dispose()
                    Write-Host "deploy.zip created with forward-slash entry paths"
                '''
                withCredentials([azureServicePrincipal(
                    credentialsId:          'azure-pcl',
                    subscriptionIdVariable: 'AZ_SUB_ID',
                    clientIdVariable:       'AZ_CLIENT_ID',
                    clientSecretVariable:   'AZ_CLIENT_SECRET',
                    tenantIdVariable:       'AZ_TENANT_ID'
                )]) {
                    bat 'az login --service-principal -u "%AZ_CLIENT_ID%" -p "%AZ_CLIENT_SECRET%" --tenant "%AZ_TENANT_ID%" --output none'
                    bat 'az account set --subscription "%AZ_SUB_ID%"'
                    bat 'az webapp deploy --resource-group rg-powdercoatinglogix-prod --name linuxpcl --src-path deploy.zip --type zip --async true'
                    bat 'az logout'
                }
            }
        }

        stage('Health Check') {
            steps {
                powershell '''
                    $url = "https://app.powdercoatinglogix.com/"
                    $timeout = 180
                    $elapsed = 0
                    Write-Host "Polling $url for up to $timeout seconds..."
                    do {
                        Start-Sleep -Seconds 10
                        $elapsed += 10
                        try {
                            $r = Invoke-WebRequest $url -UseBasicParsing -TimeoutSec 10
                            if ($r.StatusCode -lt 400) {
                                Write-Host "App responded HTTP $($r.StatusCode) after ${elapsed}s"
                                exit 0
                            }
                        } catch {
                            Write-Host "[${elapsed}s] Not yet responding: $_"
                        }
                    } while ($elapsed -lt $timeout)
                    Write-Error "App did not come healthy within $timeout seconds"
                    exit 1
                '''
            }
        }
    }

    post {
        success {
            echo "Production deployment #${BUILD_NUMBER} completed successfully."
        }
        failure {
            echo "Pipeline #${BUILD_NUMBER} FAILED — review the stage logs above."
        }
        always {
            cleanWs()
        }
    }
}
