name: Deploy to PyPI

on:
  push:
    branches: [ main ]
    paths-ignore:
      - 'README.md'
      - 'docs/**'
      - '.github/ISSUE_TEMPLATE/**'
      - '.github/PULL_REQUEST_TEMPLATE.md'
      - '.github/CODE_OF_CONDUCT.md'
      - '.github/CONTRIBUTING.md'
      - '.github/SECURITY.md'

env:
  PYTHON_VERSION: "3.13"

permissions:
  contents: write
  actions: read
  packages: read

jobs:
  check-release:
    runs-on: ubuntu-latest
    outputs:
      should_release: ${{ steps.check.outputs.should_release }}
      commit_hash: ${{ steps.commit_info.outputs.hash }}

    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        fetch-depth: 0
        token: ${{ secrets.GITHUB_TOKEN }}

    - name: Check if should skip release
      id: check
      run: |
        COMMIT_MSG=$(git log -1 --pretty=%B)
        echo "Commit message: $COMMIT_MSG"

        # Check for skip release indicators
        if [[ $COMMIT_MSG =~ \[skip-release\] ]] || [[ $COMMIT_MSG =~ \[skip-deploy\] ]]; then
          echo "should_release=false" >> $GITHUB_OUTPUT
          echo "🚫 Release skipped due to [skip-release] flag in commit message"
        else
          echo "should_release=true" >> $GITHUB_OUTPUT
          echo "✅ Will proceed with release process"
        fi

    - name: Get commit info
      id: commit_info
      run: |
        COMMIT_HASH=$(git rev-parse HEAD)
        echo "hash=$COMMIT_HASH" >> $GITHUB_OUTPUT
        echo "Current commit: $COMMIT_HASH"

  release:
    runs-on: ubuntu-latest
    needs: check-release
    if: needs.check-release.outputs.should_release == 'true'
    outputs:
      version: ${{ steps.version.outputs.version }}
      version_changed: ${{ steps.version.outputs.changed }}
      commit_hash: ${{ steps.commit_info.outputs.hash }}

    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        fetch-depth: 0
        token: ${{ secrets.GITHUB_TOKEN }}

    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - name: Configure Git
      run: |
        git config --local user.email "action@github.com"
        git config --local user.name "GitHub Action"

    - name: Get current branch
      id: branch
      run: |
        CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
        echo "branch=$CURRENT_BRANCH" >> $GITHUB_OUTPUT
        echo "Current branch: $CURRENT_BRANCH"

    - name: Determine version bump type
      id: bump_type
      run: |
        COMMIT_MSG=$(git log -1 --pretty=%B)
        echo "Commit message: $COMMIT_MSG"
        if [[ $COMMIT_MSG =~ ^.*\!:.*$ ]] || [[ $COMMIT_MSG =~ BREAKING[[:space:]]CHANGE ]] || [[ $COMMIT_MSG =~ "BREAKING CHANGE" ]]; then
          echo "type=major" >> $GITHUB_OUTPUT
          echo "Detected BREAKING CHANGE - will bump MAJOR version"
        elif [[ $COMMIT_MSG =~ feat(\(.+\))?[!]?:[[:space:]] ]] || [[ $COMMIT_MSG =~ "feat:" ]] || [[ $COMMIT_MSG =~ ^feat(\(.+\))?:.*$ ]]; then
          echo "type=minor" >> $GITHUB_OUTPUT
          echo "Detected feature - will bump MINOR version"
        else
          echo "type=patch" >> $GITHUB_OUTPUT
          echo "Default - will bump PATCH version"
        fi

    - name: Show current state before bump
      run: |
        echo "=== Before version bump ==="
        echo "Current version in __init__.py:"
        python -c "import sys; sys.path.insert(0, 'src'); from ccg import __version__; print(__version__)"
        echo "Latest git tag:"
        git describe --tags --abbrev=0 || echo "No tags found"
        echo "Recent commits since last tag:"
        LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD")
        if [ "$LATEST_TAG" != "HEAD" ]; then
          git log --oneline $LATEST_TAG..HEAD
        else
          git log --oneline -5
        fi

    - name: Bump version and update files
      id: version
      run: |
        echo "Running version bump with type: ${{ steps.bump_type.outputs.type }}"
        python scripts/bump_version.py --type ${{ steps.bump_type.outputs.type }}
        NEW_VERSION=$(python -c "import sys; sys.path.insert(0, 'src'); from ccg import __version__; print(__version__)")
        echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT

        echo "=== After version bump ==="
        echo "New version: $NEW_VERSION"
        echo "Git status:"
        git status --porcelain

        if git diff --quiet; then
          echo "changed=false" >> $GITHUB_OUTPUT
          echo "No version changes detected"
        else
          echo "changed=true" >> $GITHUB_OUTPUT
          echo "Version bumped to: $NEW_VERSION"
          echo "Files changed:"
          git diff --name-only
        fi

    - name: Show generated changelog content
      if: steps.version.outputs.changed == 'true'
      run: |
        echo "=== Generated CHANGELOG.md content ==="
        if [ -f "CHANGELOG.md" ]; then
          echo "First 50 lines of CHANGELOG.md:"
          head -50 CHANGELOG.md
          echo "..."
        else
          echo "CHANGELOG.md not found"
        fi

    - name: Commit version changes
      if: steps.version.outputs.changed == 'true'
      id: commit_info
      run: |
        git add -A
        git commit -m ":wrench: chore: bump version to ${{ steps.version.outputs.version }}"

        COMMIT_HASH=$(git rev-parse HEAD)
        echo "hash=$COMMIT_HASH" >> $GITHUB_OUTPUT
        echo "Created commit: $COMMIT_HASH"

        CURRENT_BRANCH="${{ steps.branch.outputs.branch }}"
        echo "Pushing to branch: $CURRENT_BRANCH"
        git push origin "$CURRENT_BRANCH"

    - name: Create Git tag
      if: steps.version.outputs.changed == 'true'
      run: |
        git tag -a "v${{ steps.version.outputs.version }}" -m "Release v${{ steps.version.outputs.version }}"
        git push origin "v${{ steps.version.outputs.version }}"

    - name: Generate release changelog from current version
      if: steps.version.outputs.changed == 'true'
      id: changelog
      run: |
        echo "=== Extracting current version changelog ==="
        python scripts/extract_current_changelog.py > CURRENT_CHANGELOG.md
        echo "Generated CURRENT_CHANGELOG.md:"
        cat CURRENT_CHANGELOG.md

    - name: Create GitHub Release
      if: steps.version.outputs.changed == 'true'
      uses: softprops/action-gh-release@v2
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      with:
        tag_name: v${{ steps.version.outputs.version }}
        name: Release v${{ steps.version.outputs.version }}
        body_path: CURRENT_CHANGELOG.md
        draft: false
        prerelease: false

  deploy:
    runs-on: ubuntu-latest
    needs: release
    if: needs.release.outputs.version_changed == 'true'

    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      with:
        ref: ${{ needs.release.outputs.commit_hash }}
        fetch-depth: 0

    - name: Verify correct version
      run: |
        CURRENT_VERSION=$(python -c "import sys; sys.path.insert(0, 'src'); from ccg import __version__; print(__version__)")
        EXPECTED_VERSION="${{ needs.release.outputs.version }}"

        echo "Current version in code: $CURRENT_VERSION"
        echo "Expected version: $EXPECTED_VERSION"

        if [ "$CURRENT_VERSION" != "$EXPECTED_VERSION" ]; then
          echo "❌ ERROR: Version mismatch!"
          echo "Expected: $EXPECTED_VERSION"
          echo "Got: $CURRENT_VERSION"
          exit 1
        else
          echo "✅ Version verified: $CURRENT_VERSION"
        fi

    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: ${{ env.PYTHON_VERSION }}

    - name: Install build dependencies
      run: |
        python -m pip install --upgrade pip
        python -m pip install build twine

    - name: Build package
      run: |
        echo "Building package with version ${{ needs.release.outputs.version }}"
        python -m build

    - name: Verify build
      run: |
        python -m twine check dist/*
        ls -la dist/

        WHEEL_FILE=$(ls dist/*.whl | head -1)
        echo "Built wheel: $WHEEL_FILE"

        if [[ $WHEEL_FILE == *"${{ needs.release.outputs.version }}"* ]]; then
          echo "✅ Wheel file has correct version"
        else
          echo "❌ ERROR: Wheel file doesn't contain expected version"
          echo "Expected version in filename: ${{ needs.release.outputs.version }}"
          exit 1
        fi

    - name: Publish to PyPI
      env:
        TWINE_USERNAME: __token__
        TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
      run: |
        echo "Publishing version ${{ needs.release.outputs.version }} to PyPI"
        python -m twine upload dist/*

    - name: Verify PyPI deployment
      run: |
        sleep 60
        pip install --upgrade conventional-commits-generator==${{ needs.release.outputs.version }}
        ccg --version
