name: "Notify Discord when a PR is opened or merged"

on:
  workflow_call:
    inputs:
      PR_TITLE:
        description: "The title of the PR"
        type: string
      PR_URL:
        description: "The URL of the PR"
        type: string
      PR_AUTHOR:
        description: "The author of the PR"
        type: string
      PR_STATUS:
        description: "The status of the PR"
        type: string
      DISCORD_CHANNEL_ID:
        description: "The Discord channel ID"
        type: string
      PR_NUMBER:
        description: "The number of the PR"
        type: string
      DISCORD_GUILD_ID:
        description: "The Discord guild ID"
        type: string
      COMMENT_BODY:
        description: "The comment body"
        type: string
        default: ""
      COMMENT_AUTHOR:
        description: "The comment author"
        type: string
        default: ""
      COMMENT_URL:
        description: "The comment URL"
        type: string
        default: ""
      COMMENT_IS_EDIT:
        description: "Whether this is an edit of an existing comment"
        type: string
        default: "false"
    secrets:
      DISCORD_WEBHOOK_URL:
        description: "Discord Webhook URL"
        required: false
      DISCORD_BOT_TOKEN:
        description: "Discord Bot Token"

jobs:
  open_thread:
    runs-on: ubicloud-standard-2
    if: ${{ inputs.PR_STATUS == 'opened' }}
    steps:
      - name: Send Discord notification and start a thread
        env:
          WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
          BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
          CHANNEL_ID: ${{ inputs.DISCORD_CHANNEL_ID }}
          GUILD_ID: ${{ inputs.DISCORD_GUILD_ID }}
          PR_TITLE: ${{ inputs.PR_TITLE }}
          PR_NUMBER: ${{ inputs.PR_NUMBER }}
          PR_URL: ${{ inputs.PR_URL }}
          PR_AUTHOR: ${{ inputs.PR_AUTHOR }}
        run: |
          # Check if thread already exists
          thread_exists=false
          if threads=$(curl -s -H "Authorization: Bot $BOT_TOKEN" "https://discord.com/api/v10/guilds/${GUILD_ID}/threads/active"); then
            if thread_id=$(echo "$threads" | jq -r --arg cid "$CHANNEL_ID" --arg pref "#${PR_NUMBER}:" '.threads[] | select(.parent_id == $cid and (.name | startswith($pref))) | .id' 2>/dev/null); then
              if [ -n "$thread_id" ]; then
                thread_exists=true
                echo "Thread already exists, skipping creation"
              fi
            fi
          else
            echo "Failed to check for existing threads, will create new thread"
          fi

          # Create thread if it doesn't exist or if check failed
          if [ "$thread_exists" = false ]; then
            echo "Creating new thread"
            THREAD_TITLE="#${PR_NUMBER}: ${PR_TITLE} by \`${PR_AUTHOR}\`"
            payload=$(jq -n \
              --arg content "${PR_URL}" \
              --arg thread "${THREAD_TITLE:0:99}" \
              '{
                content: $content,
                thread_name: $thread,
                auto_archive_duration: 10080
              }'
            )
            curl -H "Content-Type: application/json" \
              -X POST \
              -d "$payload" \
              "$WEBHOOK_URL"
          fi

  merge_success_emoji:
    runs-on: ubuntu-latest
    if: ${{ inputs.PR_STATUS == 'merged' }}
    steps:
      - name: React
        env:
          BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
          CHANNEL_ID: ${{ inputs.DISCORD_CHANNEL_ID }}
          GUILD_ID: ${{ inputs.DISCORD_GUILD_ID }}
          PR_NUMBER: ${{ inputs.PR_NUMBER }}
        run: |
          # 1) get PR thread
          threads=$(curl -H "Authorization: Bot $BOT_TOKEN" "https://discord.com/api/v10/guilds/${GUILD_ID}/threads/active")
          thread_id=$(
            echo "$threads" \
              | jq -r --arg cid "$CHANNEL_ID" \
                    --arg pref "#${PR_NUMBER}:" \
                '.threads[]
                | select(.parent_id == $cid and (.name | startswith($pref)))
                | .id'
          )
          if [ -z "$thread_id" ]; then
            echo "Thread not found"
            exit 1
          fi
          # 2) get the first message in that thread
          messages=$(curl -H "Authorization: Bot $BOT_TOKEN" \
            "https://discord.com/api/v10/channels/$thread_id/messages")
          message_id=$(echo "$messages" | jq -r '.[-1].id')

          if [ -z "$message_id" ]; then
            echo "Message not found"
            exit 1
          fi

          # 3) add the ✅ reaction
          curl -X PUT \
            -H "Authorization: Bot $BOT_TOKEN" \
            "https://discord.com/api/v10/channels/$thread_id/messages/$message_id/reactions/%E2%9C%85/@me"

  post_comment:
    runs-on: ubuntu-latest
    if: ${{ inputs.PR_STATUS == 'comment' }}
    steps:
      - name: Post or update comment in Discord thread
        env:
          BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }}
          CHANNEL_ID: ${{ inputs.DISCORD_CHANNEL_ID }}
          GUILD_ID: ${{ inputs.DISCORD_GUILD_ID }}
          PR_NUMBER: ${{ inputs.PR_NUMBER }}
          COMMENT_BODY: ${{ inputs.COMMENT_BODY }}
          COMMENT_AUTHOR: ${{ inputs.COMMENT_AUTHOR }}
          COMMENT_URL: ${{ inputs.COMMENT_URL }}
          COMMENT_IS_EDIT: ${{ inputs.COMMENT_IS_EDIT }}
        run: |
          # 1) Find the thread by PR number
          threads=$(curl -s -H "Authorization: Bot $BOT_TOKEN" \
            "https://discord.com/api/v10/guilds/${GUILD_ID}/threads/active")
          thread_id=$(echo "$threads" | jq -r \
            --arg cid "$CHANNEL_ID" \
            --arg pref "#${PR_NUMBER}:" \
            '.threads[] | select(.parent_id == $cid and (.name | startswith($pref))) | .id')

          if [ -z "$thread_id" ]; then
            echo "Thread not found for PR #${PR_NUMBER}, skipping"
            exit 0
          fi

          # 2) Truncate comment body to fit Discord's 2000 char limit
          # Reserve space for the author line + link (~100 chars)
          max_body=1800
          if [ ${#COMMENT_BODY} -gt $max_body ]; then
            # For bot comments, show the tail (conclusions/code tend to be at the end)
            if [[ "$COMMENT_AUTHOR" == *"[bot]"* ]] || [[ "$COMMENT_AUTHOR" == *"-bot"* ]]; then
              truncated_body="...${COMMENT_BODY: -$max_body}"
            else
              truncated_body="${COMMENT_BODY:0:$max_body}..."
            fi
          else
            truncated_body="$COMMENT_BODY"
          fi

          # 3) Build the message content
          if [ "$COMMENT_IS_EDIT" = "true" ]; then
            message=$(printf '**%s** [edited comment](%s):\n%s' "$COMMENT_AUTHOR" "$COMMENT_URL" "$truncated_body")
          else
            message=$(printf '**%s** [commented](%s):\n%s' "$COMMENT_AUTHOR" "$COMMENT_URL" "$truncated_body")
          fi
          payload=$(jq -n --arg content "$message" '{content: $content, flags: 4, allowed_mentions: {parse: []}}')

          # 4) If this is an edit, try to find and update the existing Discord message
          if [ "$COMMENT_IS_EDIT" = "true" ]; then
            # Search recent messages in the thread for one containing the comment URL
            messages=$(curl -s -H "Authorization: Bot $BOT_TOKEN" \
              "https://discord.com/api/v10/channels/${thread_id}/messages?limit=100")
            existing_msg_id=$(echo "$messages" | jq -r \
              --arg url "$COMMENT_URL" \
              '[.[] | select(.content | contains($url))] | first | .id // empty')

            if [ -n "$existing_msg_id" ]; then
              echo "Updating existing Discord message $existing_msg_id"
              curl -s -X PATCH \
                -H "Authorization: Bot $BOT_TOKEN" \
                -H "Content-Type: application/json" \
                -d "$payload" \
                "https://discord.com/api/v10/channels/${thread_id}/messages/${existing_msg_id}"
              exit 0
            fi
            echo "Original Discord message not found, posting as new message"
          fi

          # 5) Post a new message to the thread
          curl -s -X POST \
            -H "Authorization: Bot $BOT_TOKEN" \
            -H "Content-Type: application/json" \
            -d "$payload" \
            "https://discord.com/api/v10/channels/${thread_id}/messages"
