name: Generate Release Notes

on:
  workflow_call:
    inputs:
      version:
        description: 'Version number (e.g., 4.25.3)'
        required: true
        type: string
      target_commitish:
        description: 'Commit SHA or branch (leave empty for current HEAD)'
        required: false
        type: string
      release_notes:
        description: 'Custom release notes (leave empty to auto-generate)'
        required: false
        type: string
    outputs:
      release_notes:
        description: 'Generated or provided release notes'
        value: ${{ jobs.generate.outputs.release_notes }}
    secrets:
      UNRAID_BOT_GITHUB_ADMIN_TOKEN:
        required: true

jobs:
  generate:
    name: Generate Release Notes
    runs-on: ubuntu-latest
    outputs:
      release_notes: ${{ steps.generate_notes.outputs.release_notes }}
    steps:
      - name: Checkout repo
        uses: actions/checkout@v5
        with:
          ref: ${{ inputs.target_commitish || github.ref }}
          fetch-depth: 0
          token: ${{ secrets.UNRAID_BOT_GITHUB_ADMIN_TOKEN }}

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Generate Release Notes
        id: generate_notes
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          TAG_NAME="v${{ inputs.version }}"
          VERSION="${{ inputs.version }}"
          
          if [ -n "${{ inputs.release_notes }}" ]; then
            NOTES="${{ inputs.release_notes }}"
          else
            CHANGELOG_PATH="api/CHANGELOG.md"
            
            if [ -f "$CHANGELOG_PATH" ]; then
              echo "Extracting release notes from CHANGELOG.md for version ${VERSION}"
              
              NOTES=$(awk -v ver="$VERSION" '
                BEGIN { 
                  found=0; capture=0; output="";
                  gsub(/\./, "\\.", ver);
                }
                /^## \[/ {
                  if (capture) exit;
                  if ($0 ~ "\\[" ver "\\]") {
                    found=1;
                    capture=1;
                  }
                }
                capture { 
                  if (output != "") output = output "\n";
                  output = output $0;
                }
                END {
                  if (found) print output;
                  else exit 1;
                }
              ' "$CHANGELOG_PATH") || EXTRACTION_STATUS=$?
              
              if [ ${EXTRACTION_STATUS:-0} -eq 0 ] && [ -n "$NOTES" ]; then
                echo "✓ Found release notes in CHANGELOG.md"
              else
                echo "⚠ Version ${VERSION} not found in CHANGELOG.md, generating with conventional-changelog"
                
                PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
                CHANGELOG_GENERATED=false
                
                if [ -n "$PREV_TAG" ]; then
                  echo "Generating changelog from ${PREV_TAG}..HEAD using conventional-changelog"
                  
                  npm install -g conventional-changelog-cli
                  
                  TEMP_NOTES=$(mktemp)
                  conventional-changelog -p conventionalcommits \
                    --release-count 1 \
                    --output-unreleased \
                    > "$TEMP_NOTES" 2>/dev/null || true
                  
                  if [ -s "$TEMP_NOTES" ]; then
                    NOTES=$(cat "$TEMP_NOTES")
                    
                    if [ -n "$NOTES" ]; then
                      echo "✓ Generated changelog with conventional-changelog"
                      CHANGELOG_GENERATED=true
                      
                      TEMP_CHANGELOG=$(mktemp)
                      {
                        if [ -f "$CHANGELOG_PATH" ]; then
                          head -n 1 "$CHANGELOG_PATH"
                          echo ""
                          echo "$NOTES"
                          echo ""
                          tail -n +2 "$CHANGELOG_PATH"
                        else
                          echo "# Changelog"
                          echo ""
                          echo "$NOTES"
                        fi
                      } > "$TEMP_CHANGELOG"
                      
                      mv "$TEMP_CHANGELOG" "$CHANGELOG_PATH"
                      echo "✓ Updated CHANGELOG.md with generated notes"
                    else
                      echo "⚠ conventional-changelog produced empty output, using GitHub auto-generation"
                      NOTES=$(gh api repos/${{ github.repository }}/releases/generate-notes \
                        -f tag_name="${TAG_NAME}" \
                        -f target_commitish="${{ inputs.target_commitish || github.sha }}" \
                        -f previous_tag_name="${PREV_TAG}" \
                        --jq '.body')
                    fi
                  else
                    echo "⚠ conventional-changelog failed, using GitHub auto-generation"
                    NOTES=$(gh api repos/${{ github.repository }}/releases/generate-notes \
                      -f tag_name="${TAG_NAME}" \
                      -f target_commitish="${{ inputs.target_commitish || github.sha }}" \
                      -f previous_tag_name="${PREV_TAG}" \
                      --jq '.body')
                  fi
                  
                  rm -f "$TEMP_NOTES"
                else
                  echo "⚠ No previous tag found, using GitHub auto-generation"
                  NOTES=$(gh api repos/${{ github.repository }}/releases/generate-notes \
                    -f tag_name="${TAG_NAME}" \
                    -f target_commitish="${{ inputs.target_commitish || github.sha }}" \
                    --jq '.body' || echo "Release ${VERSION}")
                fi
                
                if [ "$CHANGELOG_GENERATED" = true ]; then
                  BRANCH_OR_SHA="${{ inputs.target_commitish || github.ref }}"
                  
                  if git show-ref --verify --quiet "refs/heads/${BRANCH_OR_SHA}"; then
                    echo ""
                    echo "=========================================="
                    echo "CHANGELOG GENERATED AND COMMITTED"
                    echo "=========================================="
                    echo ""
                    
                    git config user.name "github-actions[bot]"
                    git config user.email "github-actions[bot]@users.noreply.github.com"
                    
                    BEFORE_SHA=$(git rev-parse HEAD)
                    
                    git add "$CHANGELOG_PATH"
                    git commit -m "chore: add changelog for version ${VERSION}"
                    git push origin "HEAD:${BRANCH_OR_SHA}"
                    
                    AFTER_SHA=$(git rev-parse HEAD)
                    
                    echo "✓ Changelog committed and pushed successfully"
                    echo ""
                    echo "Previous SHA: ${BEFORE_SHA}"
                    echo "New SHA:      ${AFTER_SHA}"
                    echo ""
                    echo "⚠️  CRITICAL: A new commit was created, but github.sha is immutable."
                    echo "⚠️  github.sha = ${BEFORE_SHA} (original workflow trigger)"
                    echo "⚠️  The release tag must point to ${AFTER_SHA} (with changelog)"
                    echo ""
                    echo "Re-run this workflow to create the release with the correct commit."
                    echo ""
                    exit 1
                  else
                    echo "⚠ Target is a commit SHA, not a branch. Cannot push changelog updates."
                    echo "Changelog was generated but not committed."
                  fi
                fi
              fi
            else
              echo "⚠ CHANGELOG.md not found, using GitHub auto-generation"
              PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
              
              if [ -n "$PREV_TAG" ]; then
                NOTES=$(gh api repos/${{ github.repository }}/releases/generate-notes \
                  -f tag_name="${TAG_NAME}" \
                  -f target_commitish="${{ inputs.target_commitish || github.sha }}" \
                  -f previous_tag_name="${PREV_TAG}" \
                  --jq '.body')
              else
                NOTES="Release ${VERSION}"
              fi
            fi
          fi
          
          echo "release_notes<<EOF" >> $GITHUB_OUTPUT
          echo "$NOTES" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

