name: Docker Build and Push

on:
  release:
    types: [published]
  schedule:
    # Run nightly at 2 AM UTC
    - cron: '0 2 * * *'
  workflow_dispatch:
    inputs:
      tag:
        description: 'Docker tag'
        required: true
        default: 'latest'

jobs:
  php_syntax_errors:
    name: 1️⃣ PHP Code Style errors
    if: github.event_name == 'release'
    runs-on: ubuntu-latest
    steps:
      - name: Set up PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.4

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

      - name: Install dependencies
        uses: ramsey/composer-install@v2

      - name: Check source code for syntax errors
        run: ./vendor/bin/pint --test

  tests:
    name: 2️⃣ PHP Tests
    if: github.event_name == 'release'
    needs:
      - php_syntax_errors
    runs-on: ubuntu-latest
    strategy:
      matrix:
        php-version:
          - 8.4
    env:
      extensions: bcmath, curl, dom, gd, imagick, json, libxml, mbstring, pcntl, pdo, pdo_mysql, zip

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

      - name: Setup PHP Action
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-version }}
          extensions: ${{ env.extensions }}
          coverage: xdebug
          tools: pecl, composer

      - name: Install Composer dependencies
        uses: ramsey/composer-install@v2

      - name: Use Node.js 24
        uses: actions/setup-node@v4
        with:
          node-version: 24

      - name: Install
        run: npm install

      - name: Compile Front-end
        run: npm run build

      - name: Apply tests ${{ matrix.php-version }}
        run: php artisan test

  release_artifact_build:
    name: 🏗️ Build / Upload - Release File
    if: github.event_name == 'release'
    needs:
      - tests
    runs-on: ubuntu-latest
    env:
      extensions: bcmath, curl, dom, gd, imagick, json, libxml, mbstring, pcntl, pdo, pdo_mysql, zip

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

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: 8.4
          extensions: ${{ env.extensions }}
          coverage: none

      - name: Install Composer dependencies
        uses: ramsey/composer-install@v2
        with:
          composer-options: --no-dev

      - name: Use Node.js 24
        uses: actions/setup-node@v4
        with:
          node-version: 24

      - name: Install
        run: npm install

      - name: Compile Front-end
        run: npm run build

      - name: Build Dist
        run: |
          make clean dist

      - name: Upload package
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ github.token }}
          file: InvoiceShelf.zip
          asset_name: InvoiceShelf.zip
          tag: ${{ github.ref }}
          overwrite: true

  release_docker_build:
    name: 🐳 Release Docker Build
    if: github.event_name == 'release'
    needs:
      - tests
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

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

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_USERNAME }}
          password: ${{ secrets.DOCKER_HUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: invoiceshelf/invoiceshelf
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=semver,pattern={{major}}
            type=raw,value=latest,enable={{is_default_branch}}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: docker/production/Dockerfile
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  manual_docker_build:
    name: 🛠️ Manual Docker Build
    if: github.event_name == 'workflow_dispatch'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

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

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_USERNAME }}
          password: ${{ secrets.DOCKER_HUB_TOKEN }}

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: docker/production/Dockerfile
          platforms: linux/amd64,linux/arm64
          push: true
          tags: invoiceshelf/invoiceshelf:${{ github.event.inputs.tag }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  nightly_build:
    name: 🌙 Nightly Docker Build
    if: github.event_name == 'schedule'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        branch: [master, develop]
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          ref: ${{ matrix.branch }}
          fetch-depth: 2

      - name: Check for recent changes
        id: changes
        run: |
          # Check if there are commits in the last 24 hours
          RECENT_COMMITS=$(git log --since="24 hours ago" --oneline | wc -l)
          echo "recent_commits=$RECENT_COMMITS" >> $GITHUB_OUTPUT
          if [ "$RECENT_COMMITS" -gt 0 ]; then
            echo "has_changes=true" >> $GITHUB_OUTPUT
          else
            echo "has_changes=false" >> $GITHUB_OUTPUT
          fi

      - name: Set up Docker Buildx
        if: steps.changes.outputs.has_changes == 'true'
        uses: docker/setup-buildx-action@v3

      - name: Log in to Docker Hub
        if: steps.changes.outputs.has_changes == 'true'
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_USERNAME }}
          password: ${{ secrets.DOCKER_HUB_TOKEN }}

      - name: Set Docker tag
        if: steps.changes.outputs.has_changes == 'true'
        id: tag
        run: |
          if [ "${{ matrix.branch }}" = "master" ]; then
            echo "tag=nightly" >> $GITHUB_OUTPUT
          elif [ "${{ matrix.branch }}" = "develop" ]; then
            echo "tag=alpha" >> $GITHUB_OUTPUT
          fi

      - name: Build and push Docker image
        if: steps.changes.outputs.has_changes == 'true'
        uses: docker/build-push-action@v5
        with:
          context: .
          file: docker/production/Dockerfile
          platforms: linux/amd64,linux/arm64
          push: true
          tags: invoiceshelf/invoiceshelf:${{ steps.tag.outputs.tag }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: No changes detected
        if: steps.changes.outputs.has_changes == 'false'
        run: |
          echo "No commits found in the last 24 hours for ${{ matrix.branch }} branch. Skipping build."
