# =============================================================================
# CI Pipeline - ERP Construccion
# Runs on every push and pull request
# =============================================================================

name: CI Pipeline

on:
  push:
    branches: [main, develop, 'feature/**']
  pull_request:
    branches: [main, develop]

env:
  NODE_VERSION: '20'
  POSTGRES_USER: test_user
  POSTGRES_PASSWORD: test_password
  POSTGRES_DB: test_db

jobs:
  # ===========================================================================
  # Lint & Type Check
  # ===========================================================================
  lint:
    name: Lint & Type Check
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: |
            backend/package-lock.json
            frontend/web/package-lock.json

      - name: Install Backend Dependencies
        working-directory: backend
        run: npm ci

      - name: Install Frontend Dependencies
        working-directory: frontend/web
        run: npm ci

      - name: Lint Backend
        working-directory: backend
        run: npm run lint

      - name: Lint Frontend
        working-directory: frontend/web
        run: npm run lint || true

      - name: Type Check Backend
        working-directory: backend
        run: npm run build -- --noEmit || npm run build

  # ===========================================================================
  # Validate Constants (SSOT)
  # ===========================================================================
  validate-constants:
    name: Validate SSOT Constants
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: backend/package-lock.json

      - name: Install Dependencies
        working-directory: backend
        run: npm ci

      - name: Run Constants Validation
        working-directory: backend
        run: npm run validate:constants || echo "Validation script not yet implemented"

  # ===========================================================================
  # Unit Tests - Backend
  # ===========================================================================
  test-backend:
    name: Backend Tests
    runs-on: ubuntu-latest
    needs: [lint]
    services:
      postgres:
        image: postgis/postgis:15-3.3-alpine
        env:
          POSTGRES_USER: ${{ env.POSTGRES_USER }}
          POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }}
          POSTGRES_DB: ${{ env.POSTGRES_DB }}
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

      redis:
        image: redis:7-alpine
        ports:
          - 6379:6379
        options: >-
          --health-cmd "redis-cli ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

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

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: backend/package-lock.json

      - name: Install Dependencies
        working-directory: backend
        run: npm ci

      - name: Run Unit Tests
        working-directory: backend
        run: npm run test -- --coverage --passWithNoTests
        env:
          DB_HOST: localhost
          DB_PORT: 5432
          DB_USER: ${{ env.POSTGRES_USER }}
          DB_PASSWORD: ${{ env.POSTGRES_PASSWORD }}
          DB_NAME: ${{ env.POSTGRES_DB }}
          REDIS_HOST: localhost
          REDIS_PORT: 6379

      - name: Upload Coverage Report
        uses: codecov/codecov-action@v3
        if: always()
        with:
          files: backend/coverage/lcov.info
          flags: backend
          fail_ci_if_error: false

  # ===========================================================================
  # Unit Tests - Frontend
  # ===========================================================================
  test-frontend:
    name: Frontend Tests
    runs-on: ubuntu-latest
    needs: [lint]
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: frontend/web/package-lock.json

      - name: Install Dependencies
        working-directory: frontend/web
        run: npm ci

      - name: Run Unit Tests
        working-directory: frontend/web
        run: npm run test -- --coverage --passWithNoTests || echo "No tests yet"

      - name: Upload Coverage Report
        uses: codecov/codecov-action@v3
        if: always()
        with:
          files: frontend/web/coverage/lcov.info
          flags: frontend
          fail_ci_if_error: false

  # ===========================================================================
  # Build Check
  # ===========================================================================
  build:
    name: Build
    runs-on: ubuntu-latest
    needs: [test-backend, test-frontend]
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Build Backend
        working-directory: backend
        run: |
          npm ci
          npm run build

      - name: Build Frontend
        working-directory: frontend/web
        run: |
          npm ci
          npm run build

      - name: Upload Backend Artifacts
        uses: actions/upload-artifact@v3
        with:
          name: backend-dist
          path: backend/dist
          retention-days: 7

      - name: Upload Frontend Artifacts
        uses: actions/upload-artifact@v3
        with:
          name: frontend-dist
          path: frontend/web/dist
          retention-days: 7

  # ===========================================================================
  # Docker Build (only on main/develop)
  # ===========================================================================
  docker:
    name: Docker Build
    runs-on: ubuntu-latest
    needs: [build]
    if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

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

      - name: Build Backend Docker Image
        uses: docker/build-push-action@v5
        with:
          context: ./backend
          file: ./backend/Dockerfile
          target: production
          push: false
          tags: construccion-backend:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Build Frontend Docker Image
        uses: docker/build-push-action@v5
        with:
          context: ./frontend/web
          file: ./frontend/web/Dockerfile
          target: production
          push: false
          tags: construccion-frontend:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
