version: 2.1

# Import the Node orb
orbs:
  node: circleci/node@7.2.1

# Jobs
jobs:
  # ============================================
  # TEST PHASE
  # ============================================
  
  test-lint:
    executor:
      name: node/default
      resource_class: small
      tag: 'lts'
    steps:
      - checkout
      - node/install-packages:
          pkg-manager: pnpm
      - run:
          name: Run linting
          command: pnpm run lint
  
  test-typecheck:
    executor:
      name: node/default
      resource_class: small
      tag: 'lts'
    steps:
      - checkout
      - node/install-packages:
          pkg-manager: pnpm
          cache-path: ~/.pnpm-store
      - run:
          name: Type check all packages
          command: pnpm run typecheck
  
  test-unit:
    executor:
      name: node/default
      resource_class: medium
      tag: 'lts'
    steps:
      - checkout
      - node/install-packages:
          pkg-manager: pnpm
          cache-path: ~/.pnpm-store
      - run:
          name: Run unit tests
          command: pnpm --filter @xtablo/main run test
  
  test-api:
    executor:
      name: node/default
      tag: 'lts'
      resource_class: small
    steps:
      - checkout
      - node/install-packages:
          pkg-manager: pnpm
          cache-path: ~/.pnpm-store
      - run:
          name: Run API checks
          command: |
            if [ "${RUN_API_INTEGRATION_TESTS:-0}" = "1" ]; then
              pnpm --filter @xtablo/api run test
            else
              echo "Skipping API integration tests (set RUN_API_INTEGRATION_TESTS=1 to enable)."
              pnpm --filter @xtablo/api run build
            fi

  # ============================================
  # BUILD PHASE
  # ============================================
  
  build-apps:
    docker:
      - image: cimg/node:lts
    resource_class: small
    parameters:
      environment:
        type: string
        default: "staging"
    steps:
      - checkout
      - node/install-packages:
          pkg-manager: pnpm
          cache-path: ~/.pnpm-store
      - run:
          name: Build main app for << parameters.environment >>
          command: |
            cd apps/main
            pnpm run build:<< parameters.environment >>
      - run:
          name: Build external app
          command: |
            cd apps/external
            pnpm run build
      - persist_to_workspace:
          root: .
          paths:
            - apps/main/dist
            - apps/external/dist
      - store_artifacts:
          path: apps/main/dist
          destination: main-app-<< parameters.environment >>
      - store_artifacts:
          path: apps/external/dist
          destination: external-app
  
  build-api:
    docker:
      - image: cimg/node:lts
    resource_class: small
    steps:
      - checkout
      - node/install-packages:
          pkg-manager: pnpm
          cache-path: ~/.pnpm-store
      - run:
          name: Build API
          command: pnpm --filter @xtablo/api run build
      - persist_to_workspace:
          root: .
          paths:
            - apps/api/dist
      - store_artifacts:
          path: apps/api/dist
          destination: api

  # ============================================
  # DOCKER BUILD PHASE
  # ============================================
  
  build-docker-api:
    machine:
      image: ubuntu-2204:current
    resource_class: medium
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: Build API Docker image
          command: docker build -f apps/api/Dockerfile -t xtablo-api:${CIRCLE_SHA1} -t xtablo-api:latest .
      - run:
          name: Save Docker image
          command: |
            mkdir -p /tmp/docker-images
            docker save xtablo-api:${CIRCLE_SHA1} -o /tmp/docker-images/api.tar
      - persist_to_workspace:
          root: /tmp
          paths:
            - docker-images/api.tar

  # ============================================
  # DEPLOY PHASE
  # ============================================
  
  deploy-staging:
    docker:
      - image: cimg/node:lts
    resource_class: small
    steps:
      - checkout
      - attach_workspace:
          at: .
      - node/install-packages:
          pkg-manager: pnpm
          cache-path: ~/.pnpm-store
      - run:
          name: Deploy main app to staging
          command: |
            cd apps/main
            echo "Deploying main app to staging environment..."
            npx wrangler deploy --env staging
      - run:
          name: Deploy external app to staging
          command: |
            cd apps/external
            echo "Deploying external app to staging..."
            # Add external app staging deployment if needed
            # npx wrangler deploy --env staging
      - run:
          name: Deploy API to staging
          command: |
            echo "Deploying API to staging environment..."
            # Add your API deployment commands here
            # Example for Google Cloud Run:
            # gcloud run deploy xtablo-api-staging --image gcr.io/${GCP_PROJECT}/xtablo-api:${CIRCLE_SHA1} --region us-central1
  
  deploy-production:
    docker:
      - image: cimg/node:lts
    resource_class: small
    steps:
      - checkout
      - attach_workspace:
          at: .
      - node/install-packages:
          pkg-manager: pnpm
          cache-path: ~/.pnpm-store
      - run:
          name: Deploy main app to production
          command: |
            cd apps/main
            echo "Deploying main app to production environment..."
            npx wrangler deploy --env production
      - run:
          name: Deploy external app to production
          command: |
            cd apps/external
            echo "Deploying external app to production..."
            # Add external app production deployment if needed
            # npx wrangler deploy --env production
      - run:
          name: Deploy API to production
          command: |
            echo "Deploying API to production environment..."
            # Add your production API deployment commands here
            # Example for Google Cloud Run:
            # gcloud run deploy xtablo-api --image gcr.io/${GCP_PROJECT}/xtablo-api:${CIRCLE_SHA1} --region us-central1

# Workflows
workflows:
  version: 2
  
  # Run on all branches (except main and develop)
  test-and-build:
    when:
      and:
        - not:
            equal: [ main, << pipeline.git.branch >> ]
        - not:
            equal: [ develop, << pipeline.git.branch >> ]
    jobs:
      # Test phase - run in parallel
      - test-lint
      - test-typecheck
      - test-unit
      - test-api
      
      # Build phase - run after tests pass
      - build-apps:
          requires:
            - test-lint
            - test-typecheck
            - test-unit
      
      - build-api:
          requires:
            - test-api
      
      - build-docker-api:
          requires:
            - build-api
  
  # Staging deployment workflow (develop branch)
  deploy-to-staging:
    when:
      equal: [ develop, << pipeline.git.branch >> ]
    jobs:
      # Test phase
      - test-lint
      - test-typecheck
      - test-unit
      - test-api
      
      # Build phase for staging
      - build-apps:
          environment: "staging"
          requires:
            - test-lint
            - test-typecheck
            - test-unit
      
      - build-api:
          requires:
            - test-api
      
      - build-docker-api:
          requires:
            - build-api
      
      # Deploy to staging
      - deploy-staging:
          requires:
            - build-apps
            - build-docker-api
  
  # Production deployment workflow (main branch)
  deploy-to-production:
    when:
      equal: [ main, << pipeline.git.branch >> ]
    jobs:
      # Test phase
      - test-lint
      - test-typecheck
      - test-unit
      - test-api
      
      # Build phase for production
      - build-apps:
          environment: "prod"
          requires:
            - test-lint
            - test-typecheck
            - test-unit
      
      - build-api:
          requires:
            - test-api
      
      - build-docker-api:
          requires:
            - build-api
      
      # Manual approval gate before production
      - hold-for-approval:
          type: approval
          requires:
            - build-apps
            - build-docker-api
      
      # Deploy to production
      - deploy-production:
          requires:
            - hold-for-approval
