name: Build, Tag, Push, and Release to GitHub Container Registry

on:
  push:
    branches:
      - '**'

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    permissions:
      contents: write
      packages: write
      issues: read
      checks: write
      pull-requests: write

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ github.token }}

      - name: Set up QEMU for multi-arch builds
        uses: docker/setup-qemu-action@v3

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

      - name: Set up JDK 21
        uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'temurin'

      - name: Run Backend Tests
        id: backend_tests
        working-directory: ./booklore-api
        run: |
          echo "Running backend tests with testcontainers..."
          ./gradlew test
        continue-on-error: true

      - name: Publish Test Results
        uses: EnricoMi/publish-unit-test-result-action@v2
        if: always()
        with:
          files: booklore-api/build/test-results/**/*.xml
          check_name: Backend Test Results
          comment_title: Backend Test Results
          report_individual_runs: true
          report_suite_logs: 'any'

      - name: Upload Test Reports
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: test-reports
          path: |
            booklore-api/build/reports/tests/
            booklore-api/build/test-results/
          retention-days: 30

      - name: Check Test Results
        if: steps.backend_tests.outcome == 'failure'
        run: |
          echo "❌ Backend tests failed! Check the test results above."
          exit 1

      - name: Get Latest Master Version
        id: get_version
        run: |
          latest_tag=$(git tag --list "v*" --sort=-v:refname | head -n 1)
          latest_tag=${latest_tag:-"v0.0.0"}
          echo "latest_tag=$latest_tag" >> $GITHUB_ENV
          echo "Latest master tag: $latest_tag"

      - name: Determine Version Bump (Only for Master)
        if: github.ref == 'refs/heads/master'
        id: determine_bump
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          echo "Determining version bump from PR labels..."

          # Extract PR number from merge commit
          pr_number=$(git log -1 --pretty=%B | grep -oE 'Merge pull request #[0-9]+' | grep -oE '[0-9]+') || true
          if [ -z "$pr_number" ]; then
            pr_number=$(gh pr list --state merged --base master --limit 1 --json number --jq '.[0].number')
          fi
          echo "PR number: $pr_number"

          labels=$(gh pr view "$pr_number" --json labels --jq '.labels[].name' || echo "")
          echo "PR labels: $labels"

          if echo "$labels" | grep -q 'major'; then
            bump="major"
          elif echo "$labels" | grep -q 'minor'; then
            bump="minor"
          elif echo "$labels" | grep -q 'patch'; then
            bump="patch"
          else
            last_commit_msg=$(git log -1 --pretty=%B)
            if echo "$last_commit_msg" | grep -iq '#major'; then
              bump="major"
            elif echo "$last_commit_msg" | grep -iq '#minor'; then
              bump="minor"
            elif echo "$last_commit_msg" | grep -iq '#patch'; then
              bump="patch"
            else
              bump="patch"
            fi
          fi

          # Calculate next version
          semver=$(echo ${{ env.latest_tag }} | sed 's/^v//')
          major=$(echo $semver | cut -d. -f1)
          minor=$(echo $semver | cut -d. -f2)
          patch=$(echo $semver | cut -d. -f3)

          case "$bump" in
            major) major=$((major+1)); minor=0; patch=0 ;;
            minor) minor=$((minor+1)); patch=0 ;;
            patch) patch=$((patch+1)) ;;
          esac

          next_version="v${major}.${minor}.${patch}"
          echo "Version bump type: $bump"
          echo "Next version: $next_version"

          echo "bump=$bump" >> $GITHUB_ENV
          echo "new_tag=$next_version" >> $GITHUB_ENV

      - name: Generate Image Tag
        id: set_image_tag
        run: |
          branch="${GITHUB_REF#refs/heads/}"
          if [[ "$branch" == "master" ]]; then
            image_tag="${{ env.new_tag }}"
          elif [[ "$branch" == "develop" ]]; then
            short_sha=$(git rev-parse --short HEAD)
            image_tag="${{ env.latest_tag }}-develop-${short_sha}"
          else
            short_sha=$(git rev-parse --short HEAD)
            image_tag="${short_sha}"
          fi
          echo "image_tag=$image_tag" >> $GITHUB_ENV
          echo "Image tag: $image_tag"

      - name: Build and Push Docker Image
        run: |
          docker buildx create --use
          docker buildx build \
            --platform linux/amd64,linux/arm64 \
            --build-arg APP_VERSION=${{ env.image_tag }} \
            --tag booklore/booklore:${{ env.image_tag }} \
            --tag ghcr.io/booklore-app/booklore:${{ env.image_tag }} \
            --push .

      - name: Push Latest Tag (Only for Master)
        if: github.ref == 'refs/heads/master'
        run: |
          docker buildx build \
            --platform linux/amd64,linux/arm64 \
            --build-arg APP_VERSION=${{ env.new_tag }} \
            --tag booklore/booklore:latest \
            --tag ghcr.io/booklore-app/booklore:latest \
            --push .

      - name: Update Release Draft (Only for Master)
        if: github.ref == 'refs/heads/master'
        uses: release-drafter/release-drafter@v6
        with:
          tag: ${{ env.new_tag }}
          name: "Release ${{ env.new_tag }}"
        env:
          GITHUB_TOKEN: ${{ github.token }}

      - name: Publish Draft Release (Only for Master)
        if: github.ref == 'refs/heads/master'
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: |
          gh release edit ${{ env.new_tag }} --draft=false

      - name: Notify Discord of New Release
        if: false
        continue-on-error: true
        shell: bash
        env:
          GH_TOKEN: ${{ github.token }}
          DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
          NEW_TAG: ${{ env.new_tag }}
        run: |
          set -euo pipefail
          if [ -z "${DISCORD_WEBHOOK_URL:-}" ]; then
            echo "DISCORD_WEBHOOK_URL not set, skipping Discord notification."
            exit 0
          fi
          release_json=$(gh release view "$NEW_TAG" --json name,body,url)
          release_name=$(jq -r '.name' <<< "$release_json")
          release_body=$(jq -r '.body' <<< "$release_json")
          release_url=$(jq -r '.url' <<< "$release_json")
          clean_body=$(echo "$release_body" | tr -d '\r')
          max_length=1800
          if [ ${#clean_body} -gt $max_length ]; then
            clean_body="${clean_body:0:$((max_length-12))}… [truncated]"
          fi
          payload=$(jq -n \
            --arg title "New Release: $release_name" \
            --arg url   "$release_url" \
            --arg desc  "$clean_body" \
            '{
              content: null,
              embeds: [{
                title: $title,
                url: $url,
                description: $desc,
                color: 3066993
              }]
            }')
          curl -H "Content-Type: application/json" -d "$payload" "$DISCORD_WEBHOOK_URL"
