# EN: DISABLED — CI/CD moved to Gitea Actions (gitea.techbi.org)
# VI: DA TAT — CI/CD chuyen sang Gitea Actions (gitea.techbi.org)
# See: .gitea/workflows/deploy.yaml
name: Deploy to Staging (DISABLED)

on:
  workflow_dispatch:
    inputs:
      confirm:
        description: 'This workflow is disabled. CI/CD runs via Gitea Actions.'
        required: true
        default: 'I understand'

# Original trigger (disabled):
# on:
#   push:
#     branches:
#       - master
    paths:
      - 'services/iam-service-net/**'
      - 'services/merchant-service-net/**'
      - 'services/order-service-net/**'
      - 'services/fnb-engine-net/**'
      - 'services/inventory-service-net/**'
      - 'services/wallet-service-net/**'
      - 'services/catalog-service-net/**'
      - 'services/storage-service-net/**'
      - 'services/booking-service-net/**'
      - 'services/chat-service-net/**'
      - 'services/social-service-net/**'
      - 'services/promotion-service-net/**'
      - 'services/membership-service-net/**'
      - 'services/mining-service-net/**'
      - 'services/mission-service-net/**'
      - 'services/ads-manager-service-net/**'
      - 'services/ads-serving-service-net/**'
      - 'services/ads-billing-service-net/**'
      - 'services/ads-tracking-service-net/**'
      - 'services/ads-analytics-service-net/**'
      - 'services/mkt-facebook-service-net/**'
      - 'services/mkt-whatsapp-service-net/**'
      - 'services/mkt-x-service-net/**'
      - 'services/mkt-zalo-service-net/**'
      - 'apps/web-client-tpos-net/**'
      - 'deployments/staging/**'
  workflow_dispatch:
    inputs:
      service:
        description: 'Service to deploy (leave empty for all)'
        required: false
        default: ''
        type: choice
        options:
          - ''
          - iam-service
          - merchant-service
          - order-service
          - fnb-engine
          - inventory-service
          - wallet-service
          - catalog-service
          - storage-service
          - booking-service
          - chat-service
          - social-service
          - promotion-service
          - membership-service
          - mining-service
          - mission-service
          - ads-manager-service
          - ads-serving-service
          - ads-billing-service
          - ads-tracking-service
          - ads-analytics-service
          - mkt-facebook-service
          - mkt-whatsapp-service
          - mkt-x-service
          - mkt-zalo-service
          - pos-web

env:
  REGISTRY: harbor.techbi.org
  NAMESPACE: staging

jobs:
  # =========================================================================
  # Build & Push Docker Images
  # =========================================================================
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      services: ${{ steps.changes.outputs.services }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - name: Detect changed services
        id: changes
        run: |
          if [ -n "${{ github.event.inputs.service }}" ]; then
            echo 'services=["${{ github.event.inputs.service }}"]' >> $GITHUB_OUTPUT
            exit 0
          fi

          SERVICES=()
          CHANGED=$(git diff --name-only HEAD~1 HEAD)

          declare -A SERVICE_MAP=(
            ["services/iam-service-net"]="iam-service"
            ["services/merchant-service-net"]="merchant-service"
            ["services/order-service-net"]="order-service"
            ["services/fnb-engine-net"]="fnb-engine"
            ["services/inventory-service-net"]="inventory-service"
            ["services/wallet-service-net"]="wallet-service"
            ["services/catalog-service-net"]="catalog-service"
            ["services/storage-service-net"]="storage-service"
            ["services/booking-service-net"]="booking-service"
            ["services/chat-service-net"]="chat-service"
            ["services/social-service-net"]="social-service"
            ["services/promotion-service-net"]="promotion-service"
            ["services/membership-service-net"]="membership-service"
            ["services/mining-service-net"]="mining-service"
            ["services/mission-service-net"]="mission-service"
            ["services/ads-manager-service-net"]="ads-manager-service"
            ["services/ads-serving-service-net"]="ads-serving-service"
            ["services/ads-billing-service-net"]="ads-billing-service"
            ["services/ads-tracking-service-net"]="ads-tracking-service"
            ["services/ads-analytics-service-net"]="ads-analytics-service"
            ["services/mkt-facebook-service-net"]="mkt-facebook-service"
            ["services/mkt-whatsapp-service-net"]="mkt-whatsapp-service"
            ["services/mkt-x-service-net"]="mkt-x-service"
            ["services/mkt-zalo-service-net"]="mkt-zalo-service"
            ["apps/web-client-tpos-net"]="pos-web"
          )

          for path in "${!SERVICE_MAP[@]}"; do
            if echo "$CHANGED" | grep -q "^${path}/"; then
              SERVICES+=("\"${SERVICE_MAP[$path]}\"")
            fi
          done

          # EN: If deployment configs changed, deploy all
          # VI: Neu cau hinh deployment thay doi, deploy tat ca
          if echo "$CHANGED" | grep -q "^deployments/staging/"; then
            SERVICES=("\"iam-service\"" "\"merchant-service\"" "\"order-service\"" "\"fnb-engine\"" "\"inventory-service\"" "\"wallet-service\"" "\"catalog-service\"" "\"storage-service\"" "\"booking-service\"" "\"chat-service\"" "\"social-service\"" "\"promotion-service\"" "\"membership-service\"" "\"mining-service\"" "\"mission-service\"" "\"ads-manager-service\"" "\"ads-serving-service\"" "\"ads-billing-service\"" "\"ads-tracking-service\"" "\"ads-analytics-service\"" "\"mkt-facebook-service\"" "\"mkt-whatsapp-service\"" "\"mkt-x-service\"" "\"mkt-zalo-service\"" "\"pos-web\"")
          fi

          if [ ${#SERVICES[@]} -eq 0 ]; then
            echo 'services=[]' >> $GITHUB_OUTPUT
          else
            JOINED=$(IFS=,; echo "${SERVICES[*]}")
            echo "services=[${JOINED}]" >> $GITHUB_OUTPUT
          fi

  build-and-push:
    needs: detect-changes
    if: needs.detect-changes.outputs.services != '[]'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        service: ${{ fromJSON(needs.detect-changes.outputs.services) }}
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Harbor Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ secrets.DOCKER_REGISTRY }}
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Determine build context
        id: context
        run: |
          declare -A CONTEXT_MAP=(
            ["iam-service"]="./services/iam-service-net"
            ["merchant-service"]="./services/merchant-service-net"
            ["order-service"]="./services/order-service-net"
            ["fnb-engine"]="./services/fnb-engine-net"
            ["inventory-service"]="./services/inventory-service-net"
            ["wallet-service"]="./services/wallet-service-net"
            ["catalog-service"]="./services/catalog-service-net"
            ["storage-service"]="./services/storage-service-net"
            ["booking-service"]="./services/booking-service-net"
            ["chat-service"]="./services/chat-service-net"
            ["social-service"]="./services/social-service-net"
            ["promotion-service"]="./services/promotion-service-net"
            ["membership-service"]="./services/membership-service-net"
            ["mining-service"]="./services/mining-service-net"
            ["mission-service"]="./services/mission-service-net"
            ["ads-manager-service"]="./services/ads-manager-service-net"
            ["ads-serving-service"]="./services/ads-serving-service-net"
            ["ads-billing-service"]="./services/ads-billing-service-net"
            ["ads-tracking-service"]="./services/ads-tracking-service-net"
            ["ads-analytics-service"]="./services/ads-analytics-service-net"
            ["mkt-facebook-service"]="./services/mkt-facebook-service-net"
            ["mkt-whatsapp-service"]="./services/mkt-whatsapp-service-net"
            ["mkt-x-service"]="./services/mkt-x-service-net"
            ["mkt-zalo-service"]="./services/mkt-zalo-service-net"
            ["pos-web"]="./apps/web-client-tpos-net"
          )

          declare -A IMAGE_MAP=(
            ["iam-service"]="harbor.techbi.org/goodgo/iam-service-net"
            ["merchant-service"]="harbor.techbi.org/goodgo/merchant-service-net"
            ["order-service"]="harbor.techbi.org/goodgo/order-service-net"
            ["fnb-engine"]="harbor.techbi.org/goodgo/fnb-engine-net"
            ["inventory-service"]="harbor.techbi.org/goodgo/inventory-service-net"
            ["wallet-service"]="harbor.techbi.org/goodgo/wallet-service-net"
            ["catalog-service"]="harbor.techbi.org/goodgo/catalog-service-net"
            ["storage-service"]="harbor.techbi.org/goodgo/storage-service-net"
            ["booking-service"]="harbor.techbi.org/goodgo/booking-service-net"
            ["chat-service"]="harbor.techbi.org/goodgo/chat-service-net"
            ["social-service"]="harbor.techbi.org/goodgo/social-service-net"
            ["promotion-service"]="harbor.techbi.org/goodgo/promotion-service-net"
            ["membership-service"]="harbor.techbi.org/goodgo/membership-service-net"
            ["mining-service"]="harbor.techbi.org/goodgo/mining-service-net"
            ["mission-service"]="harbor.techbi.org/goodgo/mission-service-net"
            ["ads-manager-service"]="harbor.techbi.org/goodgo/ads-manager-service-net"
            ["ads-serving-service"]="harbor.techbi.org/goodgo/ads-serving-service-net"
            ["ads-billing-service"]="harbor.techbi.org/goodgo/ads-billing-service-net"
            ["ads-tracking-service"]="harbor.techbi.org/goodgo/ads-tracking-service-net"
            ["ads-analytics-service"]="harbor.techbi.org/goodgo/ads-analytics-service-net"
            ["mkt-facebook-service"]="harbor.techbi.org/goodgo/mkt-facebook-service-net"
            ["mkt-whatsapp-service"]="harbor.techbi.org/goodgo/mkt-whatsapp-service-net"
            ["mkt-x-service"]="harbor.techbi.org/goodgo/mkt-x-service-net"
            ["mkt-zalo-service"]="harbor.techbi.org/goodgo/mkt-zalo-service-net"
            ["pos-web"]="harbor.techbi.org/goodgo/web-client-tpos-net"
          )

          echo "context=${CONTEXT_MAP[${{ matrix.service }}]}" >> $GITHUB_OUTPUT
          echo "image=${IMAGE_MAP[${{ matrix.service }}]}" >> $GITHUB_OUTPUT

      - name: Build and push ${{ matrix.service }}
        uses: docker/build-push-action@v5
        with:
          context: ${{ steps.context.outputs.context }}
          push: true
          tags: |
            ${{ steps.context.outputs.image }}:staging
            ${{ steps.context.outputs.image }}:${{ github.sha }}
          cache-from: type=registry,ref=${{ steps.context.outputs.image }}:buildcache
          cache-to: type=registry,ref=${{ steps.context.outputs.image }}:buildcache,mode=max

  # =========================================================================
  # Run Database Migrations
  # =========================================================================
  migrations:
    needs: [detect-changes, build-and-push]
    if: needs.detect-changes.outputs.services != '[]'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup .NET SDK
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '10.0.x'

      - name: Install EF Core tools
        run: dotnet tool install --global dotnet-ef || true

      - name: Run IAM migrations
        if: contains(needs.detect-changes.outputs.services, 'iam-service')
        run: |
          dotnet ef database update \
            --project services/iam-service-net/src/IamService.Infrastructure/IamService.Infrastructure.csproj \
            --startup-project services/iam-service-net/src/IamService.API/IamService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_IAM_DATABASE_URL_STAGING }}

      - name: Run Merchant migrations
        if: contains(needs.detect-changes.outputs.services, 'merchant-service')
        run: |
          dotnet ef database update \
            --project services/merchant-service-net/src/MerchantService.Infrastructure/MerchantService.Infrastructure.csproj \
            --startup-project services/merchant-service-net/src/MerchantService.API/MerchantService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_MERCHANT_DATABASE_URL_STAGING }}

      - name: Run Order migrations
        if: contains(needs.detect-changes.outputs.services, 'order-service')
        run: |
          dotnet ef database update \
            --project services/order-service-net/src/OrderService.Infrastructure/OrderService.Infrastructure.csproj \
            --startup-project services/order-service-net/src/OrderService.API/OrderService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_ORDER_DATABASE_URL_STAGING }}

      - name: Run FnB Engine migrations
        if: contains(needs.detect-changes.outputs.services, 'fnb-engine')
        run: |
          dotnet ef database update \
            --project services/fnb-engine-net/src/FnbEngine.Infrastructure/FnbEngine.Infrastructure.csproj \
            --startup-project services/fnb-engine-net/src/FnbEngine.API/FnbEngine.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_FNB_DATABASE_URL_STAGING }}

      - name: Run Inventory migrations
        if: contains(needs.detect-changes.outputs.services, 'inventory-service')
        run: |
          dotnet ef database update \
            --project services/inventory-service-net/src/InventoryService.Infrastructure/InventoryService.Infrastructure.csproj \
            --startup-project services/inventory-service-net/src/InventoryService.API/InventoryService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_INVENTORY_DATABASE_URL_STAGING }}

      - name: Run Wallet migrations
        if: contains(needs.detect-changes.outputs.services, 'wallet-service')
        run: |
          dotnet ef database update \
            --project services/wallet-service-net/src/WalletService.Infrastructure/WalletService.Infrastructure.csproj \
            --startup-project services/wallet-service-net/src/WalletService.API/WalletService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_WALLET_DATABASE_URL_STAGING }}

      - name: Run Catalog migrations
        if: contains(needs.detect-changes.outputs.services, 'catalog-service')
        run: |
          dotnet ef database update \
            --project services/catalog-service-net/src/CatalogService.Infrastructure/CatalogService.Infrastructure.csproj \
            --startup-project services/catalog-service-net/src/CatalogService.API/CatalogService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_CATALOG_DATABASE_URL_STAGING }}

      - name: Run Storage migrations
        if: contains(needs.detect-changes.outputs.services, 'storage-service')
        run: |
          dotnet ef database update \
            --project services/storage-service-net/src/StorageService.Infrastructure/StorageService.Infrastructure.csproj \
            --startup-project services/storage-service-net/src/StorageService.API/StorageService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_STORAGE_DATABASE_URL_STAGING }}

      - name: Run Booking migrations
        if: contains(needs.detect-changes.outputs.services, 'booking-service')
        run: |
          dotnet ef database update \
            --project services/booking-service-net/src/BookingService.Infrastructure/BookingService.Infrastructure.csproj \
            --startup-project services/booking-service-net/src/BookingService.API/BookingService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_BOOKING_DATABASE_URL_STAGING }}

      - name: Run Chat migrations
        if: contains(needs.detect-changes.outputs.services, 'chat-service')
        run: |
          dotnet ef database update \
            --project services/chat-service-net/src/ChatService.Infrastructure/ChatService.Infrastructure.csproj \
            --startup-project services/chat-service-net/src/ChatService.API/ChatService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_CHAT_DATABASE_URL_STAGING }}

      - name: Run Social migrations
        if: contains(needs.detect-changes.outputs.services, 'social-service')
        run: |
          dotnet ef database update \
            --project services/social-service-net/src/SocialService.Infrastructure/SocialService.Infrastructure.csproj \
            --startup-project services/social-service-net/src/SocialService.API/SocialService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_SOCIAL_DATABASE_URL_STAGING }}

      - name: Run Promotion migrations
        if: contains(needs.detect-changes.outputs.services, 'promotion-service')
        run: |
          dotnet ef database update \
            --project services/promotion-service-net/src/PromotionService.Infrastructure/PromotionService.Infrastructure.csproj \
            --startup-project services/promotion-service-net/src/PromotionService.API/PromotionService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_PROMOTION_DATABASE_URL_STAGING }}

      - name: Run Membership migrations
        if: contains(needs.detect-changes.outputs.services, 'membership-service')
        run: |
          dotnet ef database update \
            --project services/membership-service-net/src/MembershipService.Infrastructure/MembershipService.Infrastructure.csproj \
            --startup-project services/membership-service-net/src/MembershipService.API/MembershipService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_MEMBERSHIP_DATABASE_URL_STAGING }}

      - name: Run Mining migrations
        if: contains(needs.detect-changes.outputs.services, 'mining-service')
        run: |
          dotnet ef database update \
            --project services/mining-service-net/src/MiningService.Infrastructure/MiningService.Infrastructure.csproj \
            --startup-project services/mining-service-net/src/MiningService.API/MiningService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_MINING_DATABASE_URL_STAGING }}

      - name: Run Mission migrations
        if: contains(needs.detect-changes.outputs.services, 'mission-service')
        run: |
          dotnet ef database update \
            --project services/mission-service-net/src/MissionService.Infrastructure/MissionService.Infrastructure.csproj \
            --startup-project services/mission-service-net/src/MissionService.API/MissionService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_MISSION_DATABASE_URL_STAGING }}

      - name: Run Ads Manager migrations
        if: contains(needs.detect-changes.outputs.services, 'ads-manager-service')
        run: |
          dotnet ef database update \
            --project services/ads-manager-service-net/src/AdsManagerService.Infrastructure/AdsManagerService.Infrastructure.csproj \
            --startup-project services/ads-manager-service-net/src/AdsManagerService.API/AdsManagerService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_ADS_MANAGER_DATABASE_URL_STAGING }}

      - name: Run Ads Serving migrations
        if: contains(needs.detect-changes.outputs.services, 'ads-serving-service')
        run: |
          dotnet ef database update \
            --project services/ads-serving-service-net/src/AdsServingService.Infrastructure/AdsServingService.Infrastructure.csproj \
            --startup-project services/ads-serving-service-net/src/AdsServingService.API/AdsServingService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_ADS_SERVING_DATABASE_URL_STAGING }}

      - name: Run Ads Billing migrations
        if: contains(needs.detect-changes.outputs.services, 'ads-billing-service')
        run: |
          dotnet ef database update \
            --project services/ads-billing-service-net/src/AdsBillingService.Infrastructure/AdsBillingService.Infrastructure.csproj \
            --startup-project services/ads-billing-service-net/src/AdsBillingService.API/AdsBillingService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_ADS_BILLING_DATABASE_URL_STAGING }}

      - name: Run Ads Tracking migrations
        if: contains(needs.detect-changes.outputs.services, 'ads-tracking-service')
        run: |
          dotnet ef database update \
            --project services/ads-tracking-service-net/src/AdsTrackingService.Infrastructure/AdsTrackingService.Infrastructure.csproj \
            --startup-project services/ads-tracking-service-net/src/AdsTrackingService.API/AdsTrackingService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_ADS_TRACKING_DATABASE_URL_STAGING }}

      - name: Run Ads Analytics migrations
        if: contains(needs.detect-changes.outputs.services, 'ads-analytics-service')
        run: |
          dotnet ef database update \
            --project services/ads-analytics-service-net/src/AdsAnalyticsService.Infrastructure/AdsAnalyticsService.Infrastructure.csproj \
            --startup-project services/ads-analytics-service-net/src/AdsAnalyticsService.API/AdsAnalyticsService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_ADS_ANALYTICS_DATABASE_URL_STAGING }}

      - name: Run Mkt Zalo migrations
        if: contains(needs.detect-changes.outputs.services, 'mkt-zalo-service')
        run: |
          dotnet ef database update \
            --project services/mkt-zalo-service-net/src/MktZaloService.Infrastructure/MktZaloService.Infrastructure.csproj \
            --startup-project services/mkt-zalo-service-net/src/MktZaloService.API/MktZaloService.API.csproj
        env:
          ConnectionStrings__DefaultConnection: ${{ secrets.REMOTE_MKT_ZALO_DATABASE_URL_STAGING }}

  # =========================================================================
  # Deploy to Kubernetes
  # =========================================================================
  deploy:
    needs: [detect-changes, build-and-push, migrations]
    if: needs.detect-changes.outputs.services != '[]'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup kubectl
        uses: azure/setup-kubectl@v3

      - name: Configure kubectl
        run: |
          echo "${{ secrets.KUBECONFIG_STAGING }}" | base64 -d > kubeconfig
          echo "KUBECONFIG=$(pwd)/kubeconfig" >> $GITHUB_ENV

      - name: Apply namespace and config
        run: |
          kubectl apply -f deployments/staging/kubernetes/namespace.yaml
          kubectl apply -f deployments/staging/kubernetes/configmap.yaml

      - name: Deploy Infrastructure
        run: |
          kubectl apply -f deployments/staging/kubernetes/redis.yaml
          kubectl apply -f deployments/staging/kubernetes/rabbitmq.yaml
          kubectl apply -f deployments/staging/kubernetes/minio.yaml

      - name: Deploy services
        run: |
          SERVICES='${{ needs.detect-changes.outputs.services }}'

          declare -A DEPLOY_MAP=(
            ["iam-service"]="iam-service.yaml"
            ["merchant-service"]="merchant-service.yaml"
            ["order-service"]="order-service.yaml"
            ["fnb-engine"]="fnb-engine.yaml"
            ["inventory-service"]="inventory-service.yaml"
            ["wallet-service"]="wallet-service.yaml"
            ["catalog-service"]="catalog-service.yaml"
            ["storage-service"]="storage-service.yaml"
            ["booking-service"]="booking-service.yaml"
            ["chat-service"]="chat-service.yaml"
            ["social-service"]="social-service.yaml"
            ["promotion-service"]="promotion-service.yaml"
            ["membership-service"]="membership-service.yaml"
            ["mining-service"]="mining-service.yaml"
            ["mission-service"]="mission-service.yaml"
            ["ads-manager-service"]="ads-manager-service.yaml"
            ["ads-serving-service"]="ads-serving-service.yaml"
            ["ads-billing-service"]="ads-billing-service.yaml"
            ["ads-tracking-service"]="ads-tracking-service.yaml"
            ["ads-analytics-service"]="ads-analytics-service.yaml"
            ["mkt-facebook-service"]="mkt-facebook-service.yaml"
            ["mkt-whatsapp-service"]="mkt-whatsapp-service.yaml"
            ["mkt-x-service"]="mkt-x-service.yaml"
            ["mkt-zalo-service"]="mkt-zalo-service.yaml"
            ["pos-web"]="pos-web.yaml"
          )

          for svc in "${!DEPLOY_MAP[@]}"; do
            if echo "$SERVICES" | grep -q "\"${svc}\""; then
              echo "Deploying ${svc}..."
              kubectl apply -f "deployments/staging/kubernetes/${DEPLOY_MAP[$svc]}"

              # EN: Force rollout to pick up new image
              # VI: Buoc rollout de cap nhat image moi
              kubectl set image "deployment/${svc}" \
                "${svc}=$(echo ${DEPLOY_MAP[$svc]} | sed 's/.yaml//')" \
                -n staging 2>/dev/null || true

              kubectl rollout restart "deployment/${svc}" -n staging
            fi
          done

      - name: Apply ingress
        run: |
          kubectl apply -f deployments/staging/kubernetes/ingress.yaml

      - name: Apply network policies
        run: |
          kubectl apply -f deployments/staging/kubernetes/network-policy.yaml

      - name: Wait for rollouts
        run: |
          SERVICES='${{ needs.detect-changes.outputs.services }}'

          declare -A DEPLOY_NAMES=(
            ["iam-service"]="iam-service"
            ["merchant-service"]="merchant-service"
            ["order-service"]="order-service"
            ["fnb-engine"]="fnb-engine"
            ["inventory-service"]="inventory-service"
            ["wallet-service"]="wallet-service"
            ["catalog-service"]="catalog-service"
            ["storage-service"]="storage-service"
            ["booking-service"]="booking-service"
            ["chat-service"]="chat-service"
            ["social-service"]="social-service"
            ["promotion-service"]="promotion-service"
            ["membership-service"]="membership-service"
            ["mining-service"]="mining-service"
            ["mission-service"]="mission-service"
            ["ads-manager-service"]="ads-manager-service"
            ["ads-serving-service"]="ads-serving-service"
            ["ads-billing-service"]="ads-billing-service"
            ["ads-tracking-service"]="ads-tracking-service"
            ["ads-analytics-service"]="ads-analytics-service"
            ["mkt-facebook-service"]="mkt-facebook-service"
            ["mkt-whatsapp-service"]="mkt-whatsapp-service"
            ["mkt-x-service"]="mkt-x-service"
            ["mkt-zalo-service"]="mkt-zalo-service"
            ["pos-web"]="pos-web"
          )

          FAILED=0
          for svc in "${!DEPLOY_NAMES[@]}"; do
            if echo "$SERVICES" | grep -q "\"${svc}\""; then
              echo "Waiting for ${svc}..."
              if ! kubectl rollout status "deployment/${DEPLOY_NAMES[$svc]}" -n staging --timeout=180s; then
                echo "WARNING: ${svc} rollout did not complete in time"
                FAILED=$((FAILED + 1))
              fi
            fi
          done

          if [ $FAILED -gt 0 ]; then
            echo "WARNING: ${FAILED} service(s) did not complete rollout"
            kubectl get pods -n staging
            exit 1
          fi

      - name: Verify deployment
        run: |
          echo "=== Pods ==="
          kubectl get pods -n staging -o wide
          echo ""
          echo "=== Services ==="
          kubectl get svc -n staging
          echo ""
          echo "=== Ingress ==="
          kubectl get ingress -n staging
