# =============================================================================
# AWOOOI - Production Deployment Pipeline (Phase 8)
# =============================================================================
# 沿用 WOOO AIOps 穩定架構
# Registry: harbor.wooo.work (192.168.0.110)
# K8s: 192.168.0.120 (K3s Master)
# Runner: 192.168.0.110 (Self-Hosted)
#
# 鐵律:
# - 生產環境嚴禁 Docker Compose，K8s 唯一合法部署
# - 110 金庫 Build + Push
# - 120 K3s Deploy
# =============================================================================

name: Deploy to Production

on:
  push:
    branches:
      - main
    paths:
      - 'apps/api/**'
      - 'apps/web/**'
      - 'k8s/awoooi-prod/**'
      - '.github/workflows/deploy-prod.yml'
  workflow_dispatch:
    inputs:
      deploy_api:
        description: 'Deploy API'
        required: false
        default: true
        type: boolean
      deploy_web:
        description: 'Deploy Web'
        required: false
        default: true
        type: boolean
      deploy_worker:
        description: 'Deploy Worker'
        required: false
        default: true
        type: boolean
      skip_tests:
        description: 'Skip smoke tests (emergency only)'
        required: false
        default: false
        type: boolean

# 沿用 AIOPS 設計: 新 commit 自動取消舊 workflow
concurrency:
  group: deploy-prod-${{ github.ref }}
  cancel-in-progress: true

env:
  # Harbor 金庫 (110 主機) - 使用 IP 避免 TLS 證書問題
  REGISTRY: 192.168.0.110:5000
  HARBOR_PROJECT: library
  # K3s 叢集 (120 主機)
  K8S_NAMESPACE: awoooi-prod
  KUBECONFIG: /home/wooo/.kube/config-120
  # 加速配置 (沿用 AIOPS)
  BASE_REGISTRY: "192.168.0.110:5000/dockerhub-cache"
  PYPI_INDEX_URL: "http://192.168.0.110:3141/root/pypi/+simple/"
  PYPI_TRUSTED_HOST: "192.168.0.110"
  NPM_REGISTRY: "http://192.168.0.110:4873"

jobs:
  # ===========================================================================
  # Stage 1: Build & Push Images (110 金庫)
  # ===========================================================================
  build:
    name: "Build Images"
    runs-on: [self-hosted, harbor, k8s]
    outputs:
      image_tag: ${{ steps.meta.outputs.tag }}
      api_image: ${{ steps.meta.outputs.api_image }}
      web_image: ${{ steps.meta.outputs.web_image }}

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Generate Image Tags
        id: meta
        run: |
          SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
          TAG="${SHORT_SHA}-${{ github.run_id }}"
          echo "tag=${TAG}" >> $GITHUB_OUTPUT
          echo "api_image=${{ env.REGISTRY }}/${{ env.HARBOR_PROJECT }}/api:${TAG}" >> $GITHUB_OUTPUT
          echo "web_image=${{ env.REGISTRY }}/${{ env.HARBOR_PROJECT }}/web:${TAG}" >> $GITHUB_OUTPUT
          echo "📦 Image Tag: ${TAG}"

      - name: Login to Harbor Registry
        run: |
          echo "${{ secrets.HARBOR_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u ${{ secrets.HARBOR_USER }} --password-stdin
          echo "✅ Harbor 登入成功"

      # ----- Build API Image -----
      # Phase 6.4i: 必須從 monorepo 根目錄建構 (context: .)
      # 因為 Dockerfile 需要複製 packages/lewooogo-* 本地套件
      - name: "Build API Image"
        if: ${{ github.event_name == 'push' || inputs.deploy_api }}
        env:
          DOCKER_BUILDKIT: 1
        run: |
          echo "🐳 Building API image..."
          docker build \
            --push \
            -t ${{ steps.meta.outputs.api_image }} \
            -t ${{ env.REGISTRY }}/${{ env.HARBOR_PROJECT }}/api:latest \
            --build-arg BASE_REGISTRY=${{ env.BASE_REGISTRY }} \
            --build-arg PYPI_INDEX_URL=${{ env.PYPI_INDEX_URL }} \
            --build-arg PYPI_TRUSTED_HOST=${{ env.PYPI_TRUSTED_HOST }} \
            -f apps/api/Dockerfile \
            .
          echo "✅ API Image: ${{ steps.meta.outputs.api_image }}"

      # ----- Build Web Image -----
      - name: "Build Web Image"
        if: ${{ github.event_name == 'push' || inputs.deploy_web }}
        env:
          DOCKER_BUILDKIT: 1
        run: |
          echo "🎨 Building Web image..."
          docker build \
            --push \
            -t ${{ steps.meta.outputs.web_image }} \
            -t ${{ env.REGISTRY }}/${{ env.HARBOR_PROJECT }}/web:latest \
            --build-arg BASE_REGISTRY=${{ env.BASE_REGISTRY }} \
            --build-arg NEXT_PUBLIC_API_URL=https://awoooi.wooo.work \
            -f apps/web/Dockerfile \
            .
          echo "✅ Web Image: ${{ steps.meta.outputs.web_image }}"

  # ===========================================================================
  # Stage 2: Deploy to K3s (120 主機)
  # ===========================================================================
  deploy:
    name: "Deploy to K3s"
    needs: build
    runs-on: [self-hosted, harbor, k8s]

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configure kubectl
        run: |
          export KUBECONFIG=${{ env.KUBECONFIG }}
          export PATH=$HOME/bin:$PATH
          echo "🔌 Connecting to K3s cluster..."
          kubectl cluster-info
          kubectl get nodes -o wide

      - name: Update Image Tags in Manifests
        run: |
          IMAGE_TAG="${{ needs.build.outputs.image_tag }}"
          echo "🔄 Updating manifests with tag: ${IMAGE_TAG}"
          sed -i "s|IMAGE_TAG_PLACEHOLDER|${IMAGE_TAG}|g" k8s/awoooi-prod/*.yaml
          grep -r "image:" k8s/awoooi-prod/ | head -10

      - name: Apply Kubernetes Manifests
        run: |
          export KUBECONFIG=${{ env.KUBECONFIG }}
          export PATH=$HOME/bin:$PATH
          echo "📦 Applying K8s manifests..."
          # 排除 kustomization.yaml 與 secrets (Secrets 由手動管理，避免覆蓋)
          for f in k8s/awoooi-prod/*.yaml; do
            BASENAME="$(basename "$f")"
            if [[ "$BASENAME" != "kustomization.yaml" && "$BASENAME" != "03-secrets.yaml" && "$BASENAME" != "03-secrets.example.yaml" ]]; then
              kubectl apply -f "$f" --namespace=${{ env.K8S_NAMESPACE }}
            else
              echo "⏭️ Skipped: $BASENAME (managed separately)"
            fi
          done

      - name: Rollout Restart Deployments
        run: |
          export KUBECONFIG=${{ env.KUBECONFIG }}
          export PATH=$HOME/bin:$PATH
          echo "🔄 Triggering rolling restart..."
          kubectl rollout restart deployment/awoooi-api -n ${{ env.K8S_NAMESPACE }} || true
          kubectl rollout restart deployment/awoooi-web -n ${{ env.K8S_NAMESPACE }} || true
          # Worker 暫停，不重啟
          echo "ℹ️ Worker restart skipped"

      - name: Wait for Rollout
        run: |
          export KUBECONFIG=${{ env.KUBECONFIG }}
          export PATH=$HOME/bin:$PATH
          echo "⏳ Waiting for rollout..."
          kubectl rollout status deployment/awoooi-api -n ${{ env.K8S_NAMESPACE }} --timeout=300s
          kubectl rollout status deployment/awoooi-web -n ${{ env.K8S_NAMESPACE }} --timeout=300s
          # Worker 暫停 (replicas=0)，Phase 6.5 完善後啟用
          echo "ℹ️ Worker deployment skipped (replicas=0)"

      - name: Verify Deployment
        run: |
          export KUBECONFIG=${{ env.KUBECONFIG }}
          export PATH=$HOME/bin:$PATH
          echo "=== Deployment Status ==="
          kubectl get pods -n ${{ env.K8S_NAMESPACE }} -l system=awoooi -o wide
          echo ""
          echo "=== Services ==="
          kubectl get svc -n ${{ env.K8S_NAMESPACE }} -l system=awoooi

  # ===========================================================================
  # Stage 3: Smoke Tests
  # ===========================================================================
  smoke-test:
    name: "Smoke Tests"
    needs: deploy
    if: ${{ !inputs.skip_tests }}
    runs-on: [self-hosted, harbor, k8s]

    steps:
      - name: API Health Check
        run: |
          echo "🏥 Running API health check..."
          for i in {1..10}; do
            if curl -sf http://192.168.0.120:32334/api/v1/health; then
              echo ""
              echo "✅ API is healthy"
              exit 0
            fi
            echo "Attempt $i/10 failed, retrying in 10s..."
            sleep 10
          done
          echo "❌ API health check failed after 10 attempts"
          exit 1

      - name: Web Health Check
        run: |
          echo "🏥 Running Web health check..."
          for i in {1..5}; do
            if curl -sf http://192.168.0.120:32335/ -o /dev/null; then
              echo "✅ Web is healthy"
              exit 0
            fi
            echo "Attempt $i/5 failed, retrying in 5s..."
            sleep 5
          done
          echo "⚠️ Web health check failed"

  # ===========================================================================
  # Stage 4: Notify (閉環通報)
  # ===========================================================================
  notify:
    name: "Send Notification"
    needs: [build, deploy, smoke-test]
    if: always()
    runs-on: [self-hosted, harbor, k8s]

    steps:
      - name: Determine Status
        id: status
        run: |
          BUILD="${{ needs.build.result }}"
          DEPLOY="${{ needs.deploy.result }}"
          SMOKE="${{ needs.smoke-test.result }}"

          if [ "$BUILD" = "success" ] && [ "$DEPLOY" = "success" ]; then
            if [ "$SMOKE" = "success" ] || [ "$SMOKE" = "skipped" ]; then
              echo "status=success" >> $GITHUB_OUTPUT
              echo "emoji=✅" >> $GITHUB_OUTPUT
              echo "message=部署成功" >> $GITHUB_OUTPUT
            else
              echo "status=warning" >> $GITHUB_OUTPUT
              echo "emoji=⚠️" >> $GITHUB_OUTPUT
              echo "message=部署完成但健康檢查失敗" >> $GITHUB_OUTPUT
            fi
          else
            echo "status=failure" >> $GITHUB_OUTPUT
            echo "emoji=❌" >> $GITHUB_OUTPUT
            echo "message=部署失敗" >> $GITHUB_OUTPUT
          fi

      - name: Send Telegram Notification
        # Phase 8: 升級為結構化 HTML + Inline Keyboard UX
        run: |
          STATUS="${{ steps.status.outputs.status }}"
          BUILD_TAG="${{ needs.build.outputs.image_tag }}"
          SHORT_SHA="${{ github.sha }}"
          SHORT_SHA="${SHORT_SHA:0:7}"
          RUN_URL="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
          ACTOR="${{ github.actor }}"

          # 根據狀態設定 Emoji 與標題
          if [ "$STATUS" = "success" ]; then
            EMOJI="✅"
            TITLE="部署成功"
          elif [ "$STATUS" = "warning" ]; then
            EMOJI="⚠️"
            TITLE="部署警告"
          else
            EMOJI="❌"
            TITLE="部署失敗"
          fi

          # HTML 結構化訊息 (使用 \n 換行)
          MESSAGE="${EMOJI} <b>AWOOOI 部署通知</b>\n\n━━━━━━━━━━━━━━━━━\n📦 <b>狀態:</b> ${TITLE}\n🌍 <b>環境:</b> Production\n🏷️ <b>版本:</b> <code>${BUILD_TAG}</code>\n🔗 <b>Commit:</b> <code>${SHORT_SHA}</code>\n👤 <b>觸發者:</b> ${ACTOR}\n━━━━━━━━━━━━━━━━━"

          # Inline Keyboard 按鈕 (成功時多一個按鈕)
          if [ "$STATUS" = "success" ]; then
            KEYBOARD='{"inline_keyboard":[[{"text":"📋 查看部署紀錄","url":"'"${RUN_URL}"'"},{"text":"🚀 開啟正式站","url":"https://awoooi.wooo.work"}]]}'
          else
            KEYBOARD='{"inline_keyboard":[[{"text":"📋 查看部署紀錄","url":"'"${RUN_URL}"'"}]]}'
          fi

          # 發送 Telegram 訊息 (JSON payload with HTML + Inline Keyboard)
          # 鐵律: Token 必須用 Secrets，禁止硬編碼
          curl -s -X POST "https://api.telegram.org/bot${{ secrets.OPENCLAW_TG_BOT_TOKEN }}/sendMessage" \
            -H "Content-Type: application/json" \
            -d "{\"chat_id\":\"${{ secrets.OPENCLAW_TG_CHAT_ID }}\",\"text\":\"${MESSAGE}\",\"parse_mode\":\"HTML\",\"reply_markup\":${KEYBOARD}}"

      - name: Send OpenClaw Webhook
        if: always()
        run: |
          curl -sf -X POST "http://192.168.0.188:8088/api/v1/webhook/deploy" \
            -H "Content-Type: application/json" \
            -d "{
              \"event\": \"deploy_${{ steps.status.outputs.status }}\",
              \"system\": \"awoooi\",
              \"env\": \"prod\",
              \"tag\": \"${{ needs.build.outputs.image_tag }}\",
              \"actor\": \"${{ github.actor }}\",
              \"commit\": \"${{ github.sha }}\",
              \"run_url\": \"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\"
            }" || echo "⚠️ OpenClaw webhook 發送失敗 (非阻塞)"
