name: Publish Android APK and TestFlight Betas
on:
  workflow_dispatch:
    inputs:
        build-platform:
          description: 'Select the platform to build'
          required: true
          default: 'Both'
          type: choice
          options:
            - Android
            - iOS
            - Both

        version-bump:
          description: 'Version bump type'
          required: true
          default: 'No Bump'
          type: choice
          options:
            - No Bump
            - minor
            - patch
            - major
    
jobs:
  generate-release-notes:
    runs-on: ubuntu-latest
    outputs:
      release_notes: ${{ steps.set-output.outputs.release_notes }}
    steps:
      - name: 📦 Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.SIGNING_REPO_PAT }}  
  
      - name: 🧠 Collect commit messages
        id: commits
        run: |
          git fetch --tags --quiet

          # Find the latest tag reachable from current HEAD
          LAST_TAG=$(git describe --tags --abbrev=0)

          # Get all non-merge commit messages since that tag
          COMMIT_MESSAGES=$(git log --no-merges --pretty=format:"- %s" "${LAST_TAG}..HEAD")

          # Output for GitHub Actions
          {
            echo "messages<<EOF"
            echo "$COMMIT_MESSAGES"
            echo "EOF"
          } >> "$GITHUB_OUTPUT"


      - name: 📜 Generate release notes using Node.js
        run: |
          yarn install --network-concurrency 1
          node scripts/generate-release-notes.js "${{ steps.commits.outputs.messages }}"
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

      - name: 🧾 Read release notes from file and export
        id: set-output
        run: |
          NOTES=$(cat release_notes.txt)
          echo "release_notes<<EOF" >> $GITHUB_OUTPUT
          echo "$NOTES" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

  publish-android:
    if: ${{ github.event.inputs['build-platform'] == 'Android' || github.event.inputs['build-platform'] == 'Both' }}
    runs-on: macos-15
    outputs:
      version: ${{ steps.setver.outputs.version }}
    steps:
      - name: 🛒 Checkout
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.SIGNING_REPO_PAT }}
      
      - name: 🖥 Setup Node 20
        uses: actions/setup-node@v4
        with:
          node-version: 20
      
      - name: 💎 Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
            ruby-version: '3.0'  
            bundler-cache: true

      - name: 🍎 Run yarn init-android
        run: yarn install --network-concurrency 1

      - name: ➕ Version Up
        if: ${{ github.event.inputs['version-bump'] != 'No Bump' }}
        run: yarn react-native bump-version --type ${{ github.event.inputs['version-bump'] }} 
      
      - id: setver
        run: echo "version=$(node -p -e "require('./package.json').version")" >> $GITHUB_OUTPUT

      
      - name: 💬 Echo package.json version to Github ENV
        run: echo VERSION_NUMBER=$(node -p -e "require('./package.json').version") >> $GITHUB_ENV
      
      - name: 🤫 Output TelemetryDeck Secrets to TelemetryDeck.json          
        run: |
          echo "{" > telemetrydeck.json
          echo "\"appID\": \"${{ secrets.TELEMETRYDECK_APPID }}\"," >> telemetrydeck.json
          echo "\"clientUser\": \"anonymous\"," >> telemetrydeck.json
          echo "\"app\": \"Jellify\"" >> telemetrydeck.json
          echo "}" >> telemetrydeck.json

          
      - name: 🤫 Output Glitchtip Secrets to Glitchtip.json
        run: |
          echo "{" > glitchtip.json
          echo "\"dsn\": \"${{ secrets.GLITCHTIP_DSN }}\"" >> glitchtip.json
          echo "}" >> glitchtip.json
      
      - name: ✅ Validate Config Files
        run: |
          node -e "JSON.parse(require('fs').readFileSync('telemetrydeck.json'))"
          node -e "JSON.parse(require('fs').readFileSync('glitchtip.json'))"
    
      - name: 🚀 Run Android fastlane build
        run: yarn fastlane:android:build
      
      - name: 📤 Upload Android Artifacts
        uses: actions/upload-artifact@v4
        with:
          name: android-artifacts
          path: ./android/app/build/outputs/apk/release/*.apk


  publish-iOS:
    if: ${{ github.event.inputs['build-platform'] == 'iOS' || github.event.inputs['build-platform'] == 'Both' }}
    runs-on: macos-15
    outputs:
      version: ${{ steps.setver.outputs.version }}
    needs: [generate-release-notes]
    steps:
  
      - name: 🛒 Checkout
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.SIGNING_REPO_PAT }}

      - name: 🖥 Setup Node 20
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: 🍎 Run yarn init-ios:new-arch
        run: yarn init-ios:new-arch
      
      - name: ➕ Version Up
        if: ${{ github.event.inputs['version-bump'] != 'No Bump' }}
        run: yarn react-native bump-version --type ${{ github.event.inputs['version-bump'] }}  

      - id: setver
        run: echo "version=$(node -p -e "require('./package.json').version")" >> $GITHUB_OUTPUT
          
      - name: 💬 Echo package.json version to Github ENV
        run: echo VERSION_NUMBER=$(node -p -e "require('./package.json').version") >> $GITHUB_ENV
          
      - name: 🤫 Output App Store Connect API Key JSON to Fastlane
        run: echo -e '${{ secrets.APPSTORE_CONNECT_API_KEY_JSON }}' > appstore_connect_api_key.json
        working-directory: ./ios/fastlane

      - name: 🤫 Output TelemetryDeck Secrets to TelemetryDeck.json          
        run: |
          echo "{" > telemetrydeck.json
          echo "\"appID\": \"${{ secrets.TELEMETRYDECK_APPID }}\"," >> telemetrydeck.json
          echo "\"clientUser\": \"anonymous\"," >> telemetrydeck.json
          echo "\"app\": \"Jellify\"" >> telemetrydeck.json
          echo "}" >> telemetrydeck.json

          
      - name: 🤫 Output Glitchtip Secrets to Glitchtip.json
        run: |
          echo "{" > glitchtip.json
          echo "\"dsn\": \"${{ secrets.GLITCHTIP_DSN }}\"" >> glitchtip.json
          echo "}" >> glitchtip.json
                
      - name: ✅ Validate Config Files
        run: |
          node -e "JSON.parse(require('fs').readFileSync('telemetrydeck.json'))"
          node -e "JSON.parse(require('fs').readFileSync('glitchtip.json'))"
                    
      - name: 🚀 Run iOS fastlane build and publish to TestFlight
        run: yarn fastlane:ios:beta
        env:
          APPSTORE_CONNECT_API_KEY_JSON: ${{ secrets.APPSTORE_CONNECT_API_KEY_JSON }}
          FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD: ${{ secrets.FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD }}
          MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
          MATCH_REPO_PAT: "anultravioletaurora:${{ secrets.SIGNING_REPO_PAT }}"

      - name: 📤 Upload iOS Artifact
        uses: actions/upload-artifact@v4
        with:
          name: ios-artifacts
          path: ./ios/Jellify.ipa

  finalize-release:
    needs: [publish-android, publish-iOS, generate-release-notes]
    if: always()
    runs-on: macos-15
    steps:
      - name: 🛒 Checkout Repo
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.SIGNING_REPO_PAT }}  

      - name: ❌ Fail if selected job failed
        run: |
          SELECTED="${{ github.event.inputs['build-platform'] }}"
          IOS_RESULT="${{ needs.publish-ios.result }}"
          ANDROID_RESULT="${{ needs.publish-android.result }}"

          echo "Selected: $SELECTED"
          echo "iOS Result: $IOS_RESULT"
          echo "Android Result: $ANDROID_RESULT"

          if [[ "$SELECTED" == "iOS" && "$IOS_RESULT" != "success" ]]; then
            echo "❌ iOS build failed!"
            exit 1
          fi

          if [[ "$SELECTED" == "Android" && "$ANDROID_RESULT" != "success" ]]; then
            echo "❌ Android build failed!"
            exit 1
          fi

          if [[ "$SELECTED" == "Both" && ( "$IOS_RESULT" != "success" || "$ANDROID_RESULT" != "success" ) ]]; then
            echo "❌ One or more platform builds failed!"
            exit 1
          fi

      - name: 💎 Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.0' 
          bundler-cache: true

      - name: 📦 Install dependencies
        run: yarn install --network-concurrency 1

      - name: ⬇️ Download Android Artifacts
        if: ${{ github.event.inputs['build-platform'] == 'Android' || github.event.inputs['build-platform'] == 'Both' }}
        uses: actions/download-artifact@v4
        with:
          name: android-artifacts
          path: artifacts/

      - name: ⬇️ Download iOS Artifacts
        if: ${{ github.event.inputs['build-platform'] == 'iOS' || github.event.inputs['build-platform'] == 'Both' }}
        uses: actions/download-artifact@v4
        with:
          name: ios-artifacts
          path: artifacts/

      - name: ➕ Version Up
        if: ${{ github.event.inputs['version-bump'] != 'No Bump' }}
        run: yarn react-native bump-version --type ${{ github.event.inputs['version-bump'] }}
      
      - name: 🔢 Set artifact version numbers
        run: |
          VERSION=${{ needs.publish-ios.outputs.version || needs.publish-android.outputs.version }}
          mkdir final-artifacts

          # Rename IPA
          if [ -f artifacts/Jellify.ipa ]; then
            cp artifacts/Jellify.ipa "final-artifacts/Jellify-${VERSION}.ipa"
          fi

          # Rename APKs
          if [ -d artifacts/ ]; then
            for apk in artifacts/*.apk; do
              filename=$(basename "$apk")
              cp "$apk" "final-artifacts/Jellify-${VERSION}-${filename}"
            done
          fi

      - name: 🔢 Commit version bump if any
        if: ${{ github.event.inputs['version-bump'] != 'No Bump' }}
        run: |
          git config --global user.name "anultravioletaurora"
          git config --global user.email "violet@jellify.app"
          git add package.json ios/Jellify.xcodeproj/project.pbxproj android/app/build.gradle || true
          git commit -m "[skip actions] version bump" || echo "No changes to commit"
          git pull origin main
          git push origin main

      - name: 🎉 Create Unified GitHub Release
        uses: ncipollo/release-action@v1
        id: githubRelease
        with:
          artifacts: ./final-artifacts/*
          name: ${{ needs.publish-ios.outputs.version || needs.publish-android.outputs.version }}
          tag: ${{ needs.publish-ios.outputs.version || needs.publish-android.outputs.version }}
          body: ${{ needs.generate-release-notes.outputs.release_notes }}
          prerelease: true
          token: ${{ secrets.SIGNING_REPO_PAT }}

      - name: 🗣️ Notify on Discord
        run: |
          cd ios
          bundle install && bundle exec fastlane notifyOnDiscord
          cd ..
        env:
          DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
          APP_VERSION: ${{ needs.publish-ios.outputs.version || needs.publish-android.outputs.version }}
          release_url: ${{ steps.githubRelease.outputs.html_url }}