name: Generate Release Notes

on:
  push:
    tags:
      - 'v*.*.*'  # Triggers on version tags like v1.0.0, v2.1.3, etc.
  workflow_dispatch:
    inputs:
      tag:
        description: 'Tag version to release (e.g., v0.3.0)'
        required: true
        type: string

permissions:
  contents: write  # Needed to create/update releases and push commits

jobs:
  # Note: We trust that validate.yml and lint.yml have already run on the
  # main branch commit before the tag was created (either by prepare-release
  # script or auto-tag workflow). This avoids duplicate workflow runs.

  sync-manifest:
    name: Sync manifest.json with tag version
    runs-on: ubuntu-latest
    outputs:
      updated: ${{ steps.update.outputs.updated }}
      version: ${{ steps.tag.outputs.version }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract version from tag
        id: tag
        run: |
          TAG_VERSION="${GITHUB_REF#refs/tags/v}"
          echo "version=$TAG_VERSION" >> $GITHUB_OUTPUT
          echo "Tag version: v$TAG_VERSION"

      - name: Check manifest.json version
        id: manifest
        run: |
          MANIFEST_VERSION=$(grep -o '"version": "[^"]*"' custom_components/tibber_prices/manifest.json | cut -d'"' -f4)
          echo "version=$MANIFEST_VERSION" >> $GITHUB_OUTPUT
          echo "Manifest version: $MANIFEST_VERSION"

      - name: Update manifest.json if needed
        id: update
        run: |
          TAG_VERSION="${{ steps.tag.outputs.version }}"
          MANIFEST_VERSION="${{ steps.manifest.outputs.version }}"

          if [ "$TAG_VERSION" != "$MANIFEST_VERSION" ]; then
            echo "::notice::Version mismatch detected - auto-syncing"
            echo "  Tag: v$TAG_VERSION"
            echo "  Manifest: $MANIFEST_VERSION"

            # Update manifest.json
            sed -i "s/\"version\": \".*\"/\"version\": \"$TAG_VERSION\"/" custom_components/tibber_prices/manifest.json

            # Verify update
            NEW_VERSION=$(grep -o '"version": "[^"]*"' custom_components/tibber_prices/manifest.json | cut -d'"' -f4)
            if [ "$NEW_VERSION" = "$TAG_VERSION" ]; then
              echo "✓ Successfully updated manifest.json to $TAG_VERSION"
              echo "updated=true" >> $GITHUB_OUTPUT
            else
              echo "::error::Failed to update manifest.json"
              exit 1
            fi
          else
            echo "✓ Versions match - no update needed"
            echo "updated=false" >> $GITHUB_OUTPUT
          fi

      - name: Commit and push manifest.json update
        if: steps.update.outputs.updated == 'true'
        run: |
          TAG_VERSION="v${{ steps.tag.outputs.version }}"

          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

          git add custom_components/tibber_prices/manifest.json
          git commit -m "chore(release): sync manifest.json with tag ${TAG_VERSION}"

          # Push to main branch
          git push origin HEAD:main

          # Delete and recreate tag on new commit
          echo "::notice::Recreating tag ${TAG_VERSION} on updated commit"
          git tag -d "${TAG_VERSION}"
          git push origin :refs/tags/"${TAG_VERSION}"
          git tag -a "${TAG_VERSION}" -m "Release ${TAG_VERSION}"
          git push origin "${TAG_VERSION}"

          # Delete existing release if present (will be recreated by release-notes job)
          gh release delete "${TAG_VERSION}" --yes --cleanup-tag=false || echo "No existing release to delete"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  release-notes:
    name: Generate and publish release notes
    runs-on: ubuntu-latest
    needs: sync-manifest  # Wait for manifest sync to complete
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0  # Fetch all history for git-cliff
          ref: main  # Use updated main branch if manifest was synced

      - name: Get previous tag
        id: previoustag
        run: |
          PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
          echo "previous_tag=${PREVIOUS_TAG}" >> $GITHUB_OUTPUT
          echo "Previous tag: ${PREVIOUS_TAG}"

      - name: Check version appropriateness
        id: version_check
        run: |
          TAG_VERSION="${GITHUB_REF#refs/tags/v}"
          PREV_TAG="${{ steps.previoustag.outputs.previous_tag }}"

          if [ -z "$PREV_TAG" ]; then
            echo "warning=" >> $GITHUB_OUTPUT
            exit 0
          fi

          # Analyze commits between tags
          COMMITS=$(git log ${PREV_TAG}..HEAD --format="%s" --no-merges)
          BREAKING=$(echo "$COMMITS" | grep -cE "^[^:]+!:|^[^:]+: .+BREAKING CHANGE" || true)
          FEAT=$(echo "$COMMITS" | grep -cE "^feat(\(.+\))?:" || true)
          FIX=$(echo "$COMMITS" | grep -cE "^fix(\(.+\))?:" || true)

          # Parse versions
          PREV_VERSION="${PREV_TAG#v}"
          IFS='.' read -r PREV_MAJOR PREV_MINOR PREV_PATCH <<< "$PREV_VERSION"
          IFS='.' read -r MAJOR MINOR PATCH <<< "$TAG_VERSION"

          WARNING=""
          SUGGESTION=""

          # Pre-1.0 version rules (0.x.y)
          if [ "$MAJOR" -eq 0 ]; then
            if [ $BREAKING -gt 0 ] && [ "$MINOR" = "$PREV_MINOR" ]; then
              WARNING="⚠️ **Version Warning**: $BREAKING breaking change(s) detected, but only PATCH version bumped."
              SUGGESTION="In pre-1.0 (0.x.y), breaking changes should bump MINOR version. Consider **v0.$((MINOR + 1)).0** instead of v$TAG_VERSION"
            elif [ $FEAT -gt 0 ] && [ "$MINOR" = "$PREV_MINOR" ] && [ "$PATCH" != "$PREV_PATCH" ]; then
              WARNING="⚠️ **Version Warning**: $FEAT new feature(s) detected, but only PATCH version bumped."
              SUGGESTION="New features should bump MINOR version. Consider **v0.$((MINOR + 1)).0** instead of v$TAG_VERSION"
            fi
          else
            # Post-1.0 version rules (x.y.z)
            if [ $BREAKING -gt 0 ] && [ "$MAJOR" = "$PREV_MAJOR" ]; then
              WARNING="⚠️ **Version Warning**: $BREAKING breaking change(s) detected, but MAJOR version not bumped."
              SUGGESTION="Breaking changes require MAJOR version bump. Consider **v$((MAJOR + 1)).0.0** instead of v$TAG_VERSION"
            elif [ $FEAT -gt 0 ] && [ "$MINOR" = "$PREV_MINOR" ] && [ "$PATCH" != "$PREV_PATCH" ]; then
              WARNING="⚠️ **Version Warning**: $FEAT new feature(s) detected, but only PATCH version bumped."
              SUGGESTION="New features should bump MINOR version. Consider **v$MAJOR.$((MINOR + 1)).0** instead of v$TAG_VERSION"
            fi
          fi

          # Output warning message
          if [ -n "$WARNING" ]; then
            echo "$WARNING"
            echo "$SUGGESTION"
            echo ""
            echo "Commits analyzed: Breaking=$BREAKING, Features=$FEAT, Fixes=$FIX"

            # Set output for later steps (using heredoc for multi-line)
            {
              echo "warning<<EOF"
              echo "$WARNING"
              echo ""
              echo "$SUGGESTION"
              echo ""
              echo "**Commits analyzed:** Breaking=$BREAKING, Features=$FEAT, Fixes=$FIX"
              echo ""
              echo "**To fix:**"
              echo "1. Run locally: \`./scripts/release/suggest-version\`"
              echo "2. Create correct tag: \`./scripts/release/prepare <suggested-version>\`"
              echo "3. Push the corrected tag: \`git push origin v<suggested-version>\`"
              echo ""
              echo "**This tag will be automatically deleted in the next step.**"
              echo "EOF"
            } >> $GITHUB_OUTPUT
          else
            echo "✓ Version bump looks appropriate for the changes"
            echo "warning=" >> $GITHUB_OUTPUT
          fi

      - name: Delete inappropriate version tag
        if: steps.version_check.outputs.warning != ''
        run: |
          TAG_NAME="${GITHUB_REF#refs/tags/}"
          echo "❌ Deleting tag $TAG_NAME (version not appropriate for changes)"
          echo ""
          echo "${{ steps.version_check.outputs.warning }}"
          echo ""
          git push origin --delete "$TAG_NAME"
          exit 1

      - name: Install git-cliff
        if: steps.version_check.outputs.warning == ''
        run: |
          wget https://github.com/orhun/git-cliff/releases/download/v2.4.0/git-cliff-2.4.0-x86_64-unknown-linux-gnu.tar.gz
          tar -xzf git-cliff-2.4.0-x86_64-unknown-linux-gnu.tar.gz
          sudo mv git-cliff-2.4.0/git-cliff /usr/local/bin/
          git-cliff --version

      - name: Generate release notes
        if: steps.version_check.outputs.warning == ''
        id: release_notes
        run: |
          FROM_TAG="${{ steps.previoustag.outputs.previous_tag }}"
          TO_TAG="${GITHUB_REF#refs/tags/}"

          echo "Generating release notes from ${FROM_TAG} to ${TO_TAG}"

          # Use our script with git-cliff backend (AI disabled in CI)
          # git-cliff will handle filtering via cliff.toml
          USE_AI=false ./scripts/release/generate-notes "${FROM_TAG}" "${TO_TAG}" > release-notes.md

          # Extract title from release notes (first line starting with "# ")
          TITLE=$(head -n 1 release-notes.md | sed 's/^# //')
          if [ -z "$TITLE" ]; then
            TITLE="Release Updates"
          fi
          echo "title=$TITLE" >> $GITHUB_OUTPUT

          # Output for GitHub Actions
          {
            echo 'notes<<EOF'
            cat release-notes.md
            echo EOF
          } >> $GITHUB_OUTPUT

      - name: Create GitHub Release
        if: steps.version_check.outputs.warning == ''
        uses: softprops/action-gh-release@v2
        with:
          name: ${{ steps.release_notes.outputs.title }}
          body: ${{ steps.release_notes.outputs.notes }}
          draft: false
          prerelease: false
          generate_release_notes: false  # We provide our own
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Summary
        if: steps.version_check.outputs.warning == ''
        run: |
          echo "✅ Release notes generated and published!" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "**Tag:** ${GITHUB_REF#refs/tags/}" >> $GITHUB_STEP_SUMMARY
          echo "**Previous tag:** ${{ steps.previoustag.outputs.previous_tag }}" >> $GITHUB_STEP_SUMMARY
          if [[ "${{ needs.sync-manifest.outputs.updated }}" == "true" ]]; then
            echo "**Manifest sync:** Updated manifest.json to version ${{ needs.sync-manifest.outputs.version }}" >> $GITHUB_STEP_SUMMARY
          else
            echo "**Manifest sync:** No update needed (version already matches)" >> $GITHUB_STEP_SUMMARY
          fi
          if [ -n "${{ steps.version_check.outputs.warning }}" ]; then
            echo "**Version check:** ⚠️ Warning detected (see release notes)" >> $GITHUB_STEP_SUMMARY
          else
            echo "**Version check:** ✓ Version appropriate for changes" >> $GITHUB_STEP_SUMMARY
          fi
