#!/usr/bin/env bash
set -euo pipefail

# Default limit
LIMIT=30
STATE="open"

# nerd font icons https://www.nerdfonts.com/cheat-sheet
CI_SUCCESS=$'\uf05d' # 
CI_PENDING=$'\uf252' # 
CI_FAIL=$'\uea87'    # 

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        -L|--limit)
            LIMIT="$2"
            shift 2
            ;;
        -s|--state)
            STATE="$2"
            shift 2
            ;;
        -h|--help)
            echo "Usage: pulls [options]"
            echo ""
            echo "List all your pull requests across all repositories"
            echo ""
            echo "Options:"
            echo "  -L, --limit NUM    Maximum number of PRs to fetch (default: 30)"
            echo "  -s, --state STATE  Filter by state: open|closed|merged|all (default: open)"
            echo "  -h, --help         Show this help message"
            echo ""
            echo "Color coding:"
            echo "  Gray   - Draft PR"
            echo "  Yellow - Waiting for review/approval"
            echo "  Green  - Approved and ready to merge"
            echo "  Purple - Merged PR"
            echo "  Red    - Closed PR (not merged)"
            echo ""
            echo "CI Status symbols:"
            echo "  ✓ - All checks passing"
            echo "  ✗ - Some checks failing"
            echo "   - Checks pending/in progress"
            echo "  · - No checks configured"
            exit 0
            ;;
        *)
            echo "Unknown option: $1"
            echo "Use --help for usage information"
            exit 1
            ;;
    esac
done

# Build the GraphQL query based on state
QUERY="is:pr author:@me"
case $STATE in
    open)
        QUERY="$QUERY is:open"
        ;;
    closed)
        QUERY="$QUERY is:closed"
        ;;
    merged)
        QUERY="$QUERY is:merged"
        ;;
    all)
        # No state filter
        ;;
    *)
        echo "Invalid state: $STATE. Must be one of: open, closed, merged, all"
        exit 1
        ;;
esac

# Create temp file for data
tmpfile=$(mktemp)

# Fetch PRs with review status using GraphQL and save to temp file
gh api graphql --paginate -f query="
query(\$endCursor: String) {
  search(query: \"$QUERY\", type: ISSUE, first: $LIMIT, after: \$endCursor) {
    edges {
      node {
        ... on PullRequest {
          number
          title
          repository {
            nameWithOwner
          }
          isDraft
          reviewDecision
          state
          updatedAt
          url
          commits(last: 1) {
            nodes {
              commit {
                statusCheckRollup {
                  state
                }
              }
            }
          }
        }
      }
    }
  }
}" | jq -r --arg ci_success "$CI_SUCCESS" --arg ci_pending "$CI_PENDING" --arg ci_fail "$CI_FAIL" '
    .data.search.edges[].node |
    # Determine color based on status
    if .state == "MERGED" then
        "PURPLE"
    elif .state == "CLOSED" then
        "RED"
    elif .isDraft then
        "GRAY"
    elif .reviewDecision == "APPROVED" then
        "GREEN"
    elif .reviewDecision == "REVIEW_REQUIRED" or .reviewDecision == "CHANGES_REQUESTED" or .reviewDecision == null then
        "YELLOW"
    else
        "NONE"
    end as $color |
    # Determine CI status symbol
    (if .commits.nodes[0].commit.statusCheckRollup then
        .commits.nodes[0].commit.statusCheckRollup.state
    else
        null
    end) as $ciState |
    (if $ciState == "SUCCESS" then
        $ci_success
    elif $ciState == "FAILURE" or $ciState == "ERROR" then
        $ci_fail
    elif $ciState == "PENDING" or $ciState == "EXPECTED" then
        $ci_pending
    else
        "·"
    end) as $ciSymbol |
    [
        $color,
        .repository.nameWithOwner,
        "#\(.number)",
        $ciSymbol,
        .state,
        (.updatedAt | fromdateiso8601 | strftime("%Y-%m-%d")),
        .title,
        .url
    ] | @tsv
' > "$tmpfile"

# Format table without escape codes first, then apply colors and links
formatted_table=$(
    {
        echo -e "REPO\tNUMBER\tCI\tSTATE\tUPDATED\tTITLE"
        echo -e "----\t------\t--\t-----\t-------\t-----"
        while IFS=$'\t' read -r color repo number ci state updated title url; do
            echo -e "${repo}\t${number}\t${ci}\t${state}\t${updated}\t${title}"
        done < "$tmpfile"
    } | column -t -s $'\t'
)

# Now add colors and hyperlinks to the formatted table
line_num=0
while IFS= read -r line; do
    line_num=$((line_num + 1))
    # Pass through header lines unchanged
    if [ $line_num -le 2 ]; then
        echo "$line"
        continue
    fi

    # Read corresponding data line
    data_line_num=$((line_num - 2))
    IFS=$'\t' read -r color repo number ci state updated title url < <(sed -n "${data_line_num}p" "$tmpfile")

    # Build hyperlink using actual escape character
    # OSC8 format: ESC]8;;URLBELTEXTESC]8;;BEL
    # Using BEL (\007) as terminator instead of ST (ESC\) for better compatibility
    esc=$'\033'
    bel=$'\007'

    # Extract the parts of the line - we need to hyperlink both number and title
    # Line format: REPO  NUMBER  CI  STATE  UPDATED  TITLE
    # We'll split on the PR number first, then on the CI symbol, then on the title
    before_number="${line%%$number*}"
    after_number="${line#*$number}"

    # Extract the CI symbol part
    before_ci="${after_number%%$ci*}"
    after_ci="${after_number#*$ci}"

    # Now split after_ci to get the middle part and the title
    # The title is at the end, so we need to find it
    before_title="${after_ci%$title*}"

    # Build the hyperlinked line with OSC8 sequences around both number and title
    hyperlink_start="${esc}]8;;${url}${bel}"
    hyperlink_end="${esc}]8;;${bel}"

    # Determine row color code
    case $color in
        GRAY)
            row_color="${esc}[90m"
            ;;
        YELLOW)
            row_color="${esc}[33m"
            ;;
        GREEN)
            row_color="${esc}[32m"
            ;;
        PURPLE)
            row_color="${esc}[35m"
            ;;
        RED)
            row_color="${esc}[31m"
            ;;
        *)
            row_color=""
            ;;
    esac

    # Color the CI icon and restore row color after
    if [ "$ci" = "$CI_FAIL" ]; then
        colored_ci="${esc}[31m${ci}${esc}[0m${row_color}"
    elif [ "$ci" = "$CI_SUCCESS" ]; then
        colored_ci="${esc}[32m${ci}${esc}[0m${row_color}"
    elif [ "$ci" = "$CI_PENDING" ]; then
        colored_ci="${esc}[33m${ci}${esc}[0m${row_color}"
    else
        colored_ci="${ci}"
    fi

    line_with_link="${before_number}${hyperlink_start}${number}${hyperlink_end}${before_ci}${colored_ci}${before_title}${hyperlink_start}${title}${hyperlink_end}"

    # Apply color to entire line
    if [ -n "$row_color" ]; then
        printf "${row_color}${line_with_link}${esc}[0m\n"
    else
        printf "${line_with_link}\n"
    fi
done <<< "$formatted_table"

# Clean up temp file
rm -f "$tmpfile"
