name: CI

on:
  pull_request:
    branches:
      - develop
      - master

jobs:
  format:
    name: Format Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: cachix/install-nix-action@v27
        with:
          github_access_token: ${{ secrets.GITHUB_TOKEN }}
          extra_nix_config: |
            experimental-features = nix-command flakes

      - name: Check formatting
        run: nix develop --command cargo fmt --all -- --check

  clippy:
    name: Lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: cachix/install-nix-action@v27
        with:
          github_access_token: ${{ secrets.GITHUB_TOKEN }}
          extra_nix_config: |
            experimental-features = nix-command flakes

      - name: Run clippy
        run: nix develop --command cargo clippy --all-targets --all-features -- -D warnings

  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: cachix/install-nix-action@v27
        with:
          github_access_token: ${{ secrets.GITHUB_TOKEN }}
          extra_nix_config: |
            experimental-features = nix-command flakes

      - name: Run tests
        run: nix develop --command cargo test --all-features --workspace

  test-windows:
    name: Test (Windows)
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable

      - uses: Swatinem/rust-cache@v2

      - name: Run tests
        run: cargo test --all-features --workspace

  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: cachix/install-nix-action@v27
        with:
          github_access_token: ${{ secrets.GITHUB_TOKEN }}
          extra_nix_config: |
            experimental-features = nix-command flakes

      - name: Build workspace
        run: nix develop --command cargo build --all-features --workspace

  build-no-tui:
    name: Build (no-tui)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: cachix/install-nix-action@v27
        with:
          github_access_token: ${{ secrets.GITHUB_TOKEN }}
          extra_nix_config: |
            experimental-features = nix-command flakes

      - name: Check no-tui build
        run: nix develop --command cargo check --package kanban-cli --no-default-features --features json,sqlite

  changeset:
    name: Validate Changeset
    if: github.event_name == 'pull_request' && github.base_ref == 'develop'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check for changeset
        run: |
          CHANGESETS=$(ls .changeset/*.md 2>/dev/null | grep -v "README.md" || true)

          if [ -z "$CHANGESETS" ]; then
            echo "❌ No changeset found!"
            echo ""
            echo "Please add a changeset file: .changeset/<ticket-id>-<description>.md"
            echo ""
            echo "Example: .changeset/kan-123-add-feature.md"
            echo "---"
            echo "bump: patch"
            echo "---"
            echo ""
            echo "Description of your changes"
            exit 1
          fi

          BRANCH_NAME="${{ github.head_ref }}"
          TICKET_ID=$(echo "$BRANCH_NAME" | grep -oE '^[A-Z]+-[0-9]+' | tr '[:upper:]' '[:lower:]')

          if [ -n "$TICKET_ID" ]; then
            MATCHING_CHANGESET=$(ls .changeset/${TICKET_ID}-*.md 2>/dev/null || true)

            if [ -z "$MATCHING_CHANGESET" ]; then
              echo "❌ No changeset matching ticket ID: $TICKET_ID"
              echo "Expected: .changeset/${TICKET_ID}-*.md"
              echo ""
              echo "Found changesets:"
              ls .changeset/*.md 2>/dev/null | grep -v "README.md" || echo "  (none)"
              exit 1
            fi

            echo "✅ Found changeset: $MATCHING_CHANGESET"
            echo ""
            echo "📝 Contents:"
            cat "$MATCHING_CHANGESET"
          fi

          for changeset in $CHANGESETS; do
            bump=$(grep -A1 "^---$" "$changeset" | grep "^bump:" | cut -d' ' -f2 | tr -d '\r\n')
            if [[ ! "$bump" =~ ^(patch|minor|major)$ ]]; then
              echo "❌ Invalid bump type in $changeset: '$bump'"
              echo "Must be one of: patch, minor, major"
              exit 1
            fi
          done

          echo "✅ Changeset validated successfully"

  changeset-check:
    name: Changeset Check
    if: github.event_name == 'pull_request' && github.base_ref == 'master'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check for changesets
        env:
          PR_TITLE: ${{ github.event.pull_request.title }}
        run: |
          if [[ "$PR_TITLE" == *"[hotfix]"* ]]; then
            echo "Hotfix PR, skipping changeset check"
            exit 0
          fi

          if [ ! -d ".changeset" ]; then
            echo "No .changeset directory found"
            echo "PRs to master require changesets to trigger a release."
            echo "Add [hotfix] to the PR title to bypass this check."
            exit 1
          fi

          CHANGESETS=$(find .changeset -maxdepth 1 -name "*.md" ! -name "README.md" 2>/dev/null || true)

          if [ -z "$CHANGESETS" ]; then
            echo "No changesets found"
            echo "PRs to master require changesets to trigger a release."
            echo "Add [hotfix] to the PR title to bypass this check."
            exit 1
          fi

          echo "Found changesets (release will be triggered on merge):"
          for changeset in $CHANGESETS; do
            bump=$(sed -n '/^---$/,/^---$/{ /^bump:/{ s/^bump: *//; p; } }' "$changeset" | tr -d '\r\n')
            echo "  $changeset (bump: ${bump:-unknown})"
          done

  release-validation:
    name: Release Validation
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: cachix/install-nix-action@v27
        with:
          github_access_token: ${{ secrets.GITHUB_TOKEN }}
          extra_nix_config: |
            experimental-features = nix-command flakes

      - name: Validate release build
        run: |
          nix develop --command validate-release

      - name: Check crate list sync invariant
        run: |
          nix develop --command check-crate-list-sync
