name: Publish to npm

on:
  release:
    types: [released]
  workflow_dispatch:
    inputs:
      tag_name:
        description: "Release tag (e.g., v1.2.3)"
        required: true
      release_id:
        description: "GitHub release ID"
        required: true

concurrency:
  group: publish
  cancel-in-progress: true

permissions:
  contents: write
  packages: write

env:
  NODE_VERSION: 22
  PNPM_VERSION: 10.8.1

jobs:
  publish:
    runs-on: ubuntu-latest
    # Only run if this was converted from a pre-release
    if: github.event.release.prerelease == false
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.release.tag_name || inputs.tag_name }}

      - name: Setup Node
        uses: ./.github/actions/setup-node

      - name: Configure npm authentication
        run: |
          echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc

      - name: Download release assets
        uses: actions/github-script@v7
        env:
          RELEASE_ID: ${{ inputs.release_id }}
        with:
          script: |
            const fs = require('fs');
            const path = require('path');

            const releaseId = context.payload.release?.id || process.env.RELEASE_ID;
            console.log("releaseId:", releaseId);

            if (!releaseId) {
              core.setFailed('No release ID found.');
              return;
            }

            const release = await github.rest.repos.getRelease({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: releaseId
            });
            
            // Find the .tgz file
            const tgzAsset = release.data.assets.find(asset => asset.name.endsWith('.tgz'));
            
            if (!tgzAsset) {
              core.setFailed('No .tgz file found in release assets');
              return;
            }
            
            // Download the asset
            const response = await github.rest.repos.getReleaseAsset({
              owner: context.repo.owner,
              repo: context.repo.repo,
              asset_id: tgzAsset.id,
              headers: {
                Accept: 'application/octet-stream'
              }
            });
            
            // Save to npx-cli directory
            const filePath = path.join('npx-cli', tgzAsset.name);
            fs.writeFileSync(filePath, Buffer.from(response.data));
            
            console.log(`Downloaded ${tgzAsset.name} to ${filePath}`);
            
            // Set output for next step
            core.setOutput('package-file', filePath);
            core.setOutput('package-name', tgzAsset.name);

      - name: Verify package integrity
        id: verify
        run: |
          cd npx-cli
          
          # List files to confirm download
          ls -la *.tgz
          
          # Verify the package can be read
          npm pack --dry-run || echo "Note: This is expected to show differences since we're using the pre-built package"
          
          # Extract package name from the downloaded file
          PACKAGE_FILE=$(ls *.tgz | head -n1)
          echo "package-file=$PACKAGE_FILE" >> $GITHUB_OUTPUT

      - name: Publish to npm
        run: |
          cd npx-cli
          
          # Publish the exact same package that was tested
          PACKAGE_FILE="${{ steps.verify.outputs.package-file }}"
          
          echo "Publishing $PACKAGE_FILE to npm..."
          npm publish "$PACKAGE_FILE"
          
          echo "✅ Successfully published to npm!"
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Update release description
        uses: actions/github-script@v7
        env:
          RELEASE_ID: ${{ inputs.release_id }}
        with:
          script: |
            const releaseId = context.payload.release?.id || process.env.RELEASE_ID;;

            // Fetch the release to get the current body
            const release = await github.rest.repos.getRelease({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: releaseId
            });

            const currentBody = release.data.body || '';
            await github.rest.repos.updateRelease({
              owner: context.repo.owner,
              repo: context.repo.repo,
              release_id: releaseId,
              body: currentBody + '\n\n✅ **Published to npm registry**'
            });