name: Build and Deploy

on:
  push:
    branches:
      - main
  workflow_dispatch:

env:
  REGISTRY: ghcr.io
  VITE_API_BASE_URL: ${{ vars.VITE_API_BASE_URL || '' }}
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    strategy:
      fail-fast: false
      matrix:
        service:
          - name: web
            dockerfile: apps/web/Dockerfile
          - name: api
            dockerfile: apps/api/Dockerfile
          - name: ml
            dockerfile: apps/ml-service/Dockerfile
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          lfs: true

      - name: Set image prefix
        run: echo "IMAGE_PREFIX=ghcr.io/${GITHUB_REPOSITORY,,}" >> "$GITHUB_ENV"

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

      - name: Set up Python for ONNX conversion
        if: matrix.service.name == 'ml'
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Generate ONNX model artifact
        if: matrix.service.name == 'ml'
        working-directory: Machine_Learning
        run: |
          python -m pip install --upgrade pip
          python -m pip install 'tensorflow>=2.13.0' 'tf2onnx>=1.16.1' 'onnx>=1.16.0'
          python convert_onnx.py

      - name: Log in to GHCR
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.IMAGE_PREFIX }}/${{ matrix.service.name }}
          tags: |
            type=ref,event=branch
            type=sha

      - name: Build and push image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ${{ matrix.service.dockerfile }}
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          build-args: |
            VITE_API_BASE_URL=${{ env.VITE_API_BASE_URL }}
          cache-from: type=gha,scope=${{ matrix.service.name }}
          cache-to: type=gha,mode=max,scope=${{ matrix.service.name }}

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    permissions:
      contents: read
      packages: read
    steps:
      - name: Validate deploy secrets
        env:
          VPS_HOST: ${{ secrets.VPS_HOST }}
          VPS_USER: ${{ secrets.VPS_USER }}
          VPS_SSH_KEY: ${{ secrets.VPS_SSH_KEY }}
        run: |
          if [ -z "$VPS_HOST" ] || [ -z "$VPS_USER" ] || [ -z "$VPS_SSH_KEY" ]; then
            echo "Missing deploy secrets: VPS_HOST, VPS_USER, VPS_SSH_KEY." >&2
            exit 1
          fi

      - name: Deploy to VPS
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          passphrase: ${{ secrets.VPS_SSH_PASSPHRASE }}
          port: ${{ secrets.VPS_PORT || 22 }}
          script: |
            set -e
            DEPLOY_PATH="${DEPLOY_PATH:-/opt/ZeaVis-Edu}"
            REPO_SLUG="$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')"

            if [ ! -d "$DEPLOY_PATH/.git" ]; then
              mkdir -p "$DEPLOY_PATH"
              git clone https://github.com/${{ github.repository }}.git "$DEPLOY_PATH"
            fi

            cd "$DEPLOY_PATH"
            git fetch origin main
            git reset --hard origin/main

            {
              printf 'GITHUB_REPOSITORY=%s\n' "$REPO_SLUG"
              cat << 'ENVEOF'
            DATABASE_URL=${{ secrets.DATABASE_URL }}
            SESSION_SECRET=${{ secrets.SESSION_SECRET }}
            WEB_APP_URL=https://zeavisedu.asepharyana.tech
            ML_SERVICE_URL=http://zeavis-ml:8000
            ENVEOF
            } > .env

            docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }}
            docker network create app-shared-net 2>/dev/null || true
            docker network create telemetry-net 2>/dev/null || true
            docker compose down --remove-orphans || true
            docker rm -f zeavis-web zeavis-api zeavis-ml zeavis-node-exporter 2>/dev/null || true
            docker compose pull
            docker compose up -d
            docker compose ps
            docker compose ps | grep -q "zeavis-web.*Up" || exit 1
            docker compose ps | grep -q "zeavis-api.*Up" || exit 1
            docker compose ps | grep -q "zeavis-ml.*Up" || exit 1
            docker compose ps | grep -q "zeavis-node-exporter.*Up" || echo "⚠️  node_exporter not running (non-fatal)"
