#!/usr/bin/env bash
# ============================================================================
# BlackRoad OS — Fleet GitHub Agent
# Nodes that can triage, comment, review, fix, and ship on GitHub.
# "We don't just watch the repo — we contribute."
# ============================================================================
set -euo pipefail

NODE="${BLACKROAD_NODE_NAME:-$(hostname)}"
LOG="$HOME/.blackroad-autonomy/github.log"
REPO_DIR="$HOME/blackroad-sync/BlackRoad-Operating-System"
ORG="blackboxprogramming"
MAIN_REPO="BlackRoad-Operating-System"
mkdir -p "$(dirname "$LOG")"

SSH_OPTS="-o ConnectTimeout=3 -o BatchMode=yes -o StrictHostKeyChecking=no -o LogLevel=ERROR"

declare -A SIBLINGS=(
  [alice]="pi@192.168.4.49"
  [cecilia]="blackroad@192.168.4.96"
  [octavia]="pi@192.168.4.101"
  [aria]="blackroad@192.168.4.98"
  [lucidia]="octavia@192.168.4.38"
)

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$NODE] $*" >> "$LOG"; }

# ─── RATE LIMIT CHECK ────────────────────────────────────────────────
check_rate() {
  local remaining
  remaining=$(gh api rate_limit --jq '.resources.core.remaining' 2>/dev/null || echo 0)
  if [ "$remaining" -lt 50 ]; then
    log "RATELIMIT only $remaining REST calls left — pausing GitHub work"
    return 1
  fi
  return 0
}

# ═══════════════════════════════════════════════════════════════════════
# TRIAGE — Read and label new issues
# ═══════════════════════════════════════════════════════════════════════
cmd_triage() {
  log "TRIAGE scanning for unlabeled issues"
  check_rate || return

  # Get issues without priority labels
  local issues
  issues=$(gh api "repos/${ORG}/${MAIN_REPO}/issues?state=open&per_page=30" \
    --jq '.[] | select(.pull_request == null) | select((.labels | map(.name) | any(test("urgent|high|medium|low"))) | not) | "\(.number)|\(.title)"' 2>/dev/null)

  if [ -z "$issues" ]; then
    log "TRIAGE all issues are labeled"
    return
  fi

  echo "$issues" | while IFS='|' read -r num title; do
    [ -z "$num" ] && continue
    log "TRIAGE #$num needs labels: $title"

    # Auto-classify based on keywords
    local labels=""
    local title_lower=$(echo "$title" | tr '[:upper:]' '[:lower:]')

    # Priority detection
    if echo "$title_lower" | grep -qE "crash|down|broken|urgent|critical|security"; then
      labels="urgent"
    elif echo "$title_lower" | grep -qE "bug|fix|error|fail|wrong"; then
      labels="high,bug"
    elif echo "$title_lower" | grep -qE "feature|add|new|implement|create"; then
      labels="medium,feature"
    elif echo "$title_lower" | grep -qE "docs|readme|comment|typo"; then
      labels="low,documentation"
    elif echo "$title_lower" | grep -qE "refactor|clean|improve|optimize"; then
      labels="medium,enhancement"
    elif echo "$title_lower" | grep -qE "fleet|node|pi|raspberry|ssh"; then
      labels="medium,fleet"
    elif echo "$title_lower" | grep -qE "cloudflare|worker|pages|kv|d1|r2"; then
      labels="medium,cloudflare"
    else
      labels="medium"
    fi

    # Apply labels
    for label in $(echo "$labels" | tr ',' ' '); do
      gh api --method POST "repos/${ORG}/${MAIN_REPO}/issues/${num}/labels" \
        -f "labels[]=$label" 2>/dev/null && \
        log "TRIAGE labeled #$num with $label" || true
    done
  done
}

# ═══════════════════════════════════════════════════════════════════════
# RESPOND — Comment on issues that need attention
# ═══════════════════════════════════════════════════════════════════════
cmd_respond() {
  log "RESPOND checking for issues I can help with"
  check_rate || return

  # Get open issues with fleet/node labels that have no comments from agents
  local issues
  issues=$(gh api "repos/${ORG}/${MAIN_REPO}/issues?state=open&labels=fleet&per_page=10" \
    --jq '.[] | select(.pull_request == null) | "\(.number)|\(.title)|\(.comments)"' 2>/dev/null)

  if [ -z "$issues" ]; then
    # Also check unlabeled issues
    issues=$(gh api "repos/${ORG}/${MAIN_REPO}/issues?state=open&per_page=10" \
      --jq '.[] | select(.pull_request == null) | select(.comments == 0) | "\(.number)|\(.title)|\(.comments)"' 2>/dev/null)
  fi

  [ -z "$issues" ] && { log "RESPOND no issues need my attention"; return; }

  echo "$issues" | head -5 | while IFS='|' read -r num title comments; do
    [ -z "$num" ] && continue
    [ "$comments" -gt 2 ] && continue  # Already has discussion

    # Check if I already commented
    local my_comments
    my_comments=$(gh api "repos/${ORG}/${MAIN_REPO}/issues/${num}/comments" \
      --jq "[.[] | select(.body | test(\"\\\\[$NODE\\\\]\"))] | length" 2>/dev/null || echo "0")
    [ "$my_comments" -gt 0 ] && continue

    # Gather relevant fleet data for the response
    local fleet_context=""
    local title_lower=$(echo "$title" | tr '[:upper:]' '[:lower:]')

    if echo "$title_lower" | grep -qiE "fleet|node|pi|ssh|offline|down|reboot"; then
      # This is a fleet issue — gather live status
      fleet_context="**Fleet Status (live from $NODE):**\n"
      for sname in alice cecilia octavia aria lucidia; do
        local target_user target_ip
        target_user=$(echo "${SIBLINGS[$sname]}" | cut -d@ -f1)
        target_ip=$(echo "${SIBLINGS[$sname]}" | cut -d@ -f2)
        if ssh $SSH_OPTS "${target_user}@${target_ip}" 'true' 2>/dev/null; then
          local temp load mem
          temp=$(ssh $SSH_OPTS "${target_user}@${target_ip}" 'echo $(($(cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null || echo 0) / 1000))' 2>/dev/null || echo "?")
          load=$(ssh $SSH_OPTS "${target_user}@${target_ip}" 'cat /proc/loadavg | cut -d" " -f1' 2>/dev/null || echo "?")
          mem=$(ssh $SSH_OPTS "${target_user}@${target_ip}" 'free | awk "/Mem:/{printf \"%.0f\", \$3*100/\$2}"' 2>/dev/null || echo "?")
          fleet_context+="- **$sname**: online, ${temp}°C, load ${load}, mem ${mem}%\n"
        else
          fleet_context+="- **$sname**: unreachable\n"
        fi
      done
    fi

    if echo "$title_lower" | grep -qiE "disk|storage|space|full"; then
      fleet_context+="**Disk Status:**\n"
      for sname in alice cecilia octavia aria lucidia; do
        local target_user target_ip
        target_user=$(echo "${SIBLINGS[$sname]}" | cut -d@ -f1)
        target_ip=$(echo "${SIBLINGS[$sname]}" | cut -d@ -f2)
        local disk
        disk=$(ssh $SSH_OPTS "${target_user}@${target_ip}" 'df -h / | awk "NR==2{printf \"%s used of %s (%s)\", \$3, \$2, \$5}"' 2>/dev/null || echo "unreachable")
        fleet_context+="- **$sname**: $disk\n"
      done
    fi

    # Build comment
    local comment="**[$NODE] Fleet Agent Report**\n\n"
    comment+="I noticed this issue and checked the fleet.\n\n"

    if [ -n "$fleet_context" ]; then
      comment+="$fleet_context\n"
    fi

    # Add suggestions based on issue type
    if echo "$title_lower" | grep -qiE "offline|down|unreachable"; then
      comment+="**Suggested actions:**\n"
      comment+="1. Check physical power connections\n"
      comment+="2. Try SSH from another node: \`ssh $SSH_OPTS <user>@<ip>\`\n"
      comment+="3. Check WireGuard: \`sudo wg show\`\n"
      comment+="4. If DHCP changed IP, scan: \`arp -a | grep 'raspberry\\|88:a2:9e'\`\n"
    elif echo "$title_lower" | grep -qiE "disk|full|storage"; then
      comment+="**Suggested actions:**\n"
      comment+="1. Clean journal: \`sudo journalctl --vacuum-size=50M\`\n"
      comment+="2. Clean apt: \`sudo apt-get clean\`\n"
      comment+="3. Find large files: \`du -h --max-depth=2 / 2>/dev/null | sort -rh | head -20\`\n"
      comment+="4. Clean old logs: \`find /var/log -name '*.gz' -delete\`\n"
    elif echo "$title_lower" | grep -qiE "undervoltage|power|throttl"; then
      comment+="**Suggested actions:**\n"
      comment+="1. Use 5V/5A USB-C PSU (Pi 5 with Hailo-8 needs this)\n"
      comment+="2. Check: \`vcgencmd get_throttled\`\n"
      comment+="3. Reduce CPU: \`echo conservative | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor\`\n"
    fi

    comment+="\n---\n*Automated by $NODE via br-github — BlackRoad Fleet Agent*"

    # Post comment
    gh api --method POST "repos/${ORG}/${MAIN_REPO}/issues/${num}/comments" \
      -f body="$(echo -e "$comment")" 2>/dev/null && \
      log "RESPOND commented on #$num" || \
      log "RESPOND failed to comment on #$num"
  done
}

# ═══════════════════════════════════════════════════════════════════════
# WATCH — Monitor repo activity and react
# ═══════════════════════════════════════════════════════════════════════
cmd_watch() {
  log "WATCH checking repo activity"
  check_rate || return

  # Check for new PRs
  local prs
  prs=$(gh api "repos/${ORG}/${MAIN_REPO}/pulls?state=open&per_page=5" \
    --jq '.[] | "\(.number)|\(.title)|\(.user.login)|\(.changed_files)"' 2>/dev/null)

  if [ -n "$prs" ]; then
    echo "$prs" | while IFS='|' read -r num title author files; do
      [ -z "$num" ] && continue
      log "WATCH PR #$num by $author: $title ($files files)"

      # Check if already reviewed by an agent
      local reviewed
      reviewed=$(gh api "repos/${ORG}/${MAIN_REPO}/pulls/${num}/comments" \
        --jq "[.[] | select(.body | test(\"Fleet Agent\"))] | length" 2>/dev/null || echo "0")
      [ "$reviewed" -gt 0 ] && continue

      # Quick review: check if PR touches fleet config
      local pr_files
      pr_files=$(gh api "repos/${ORG}/${MAIN_REPO}/pulls/${num}/files" \
        --jq '.[].filename' 2>/dev/null)

      local review_comment=""
      if echo "$pr_files" | grep -qiE "fleet|node|config|ssh"; then
        review_comment="**[$NODE] Fleet Agent Review**\n\nThis PR touches fleet-related files. I've noted the changes:\n\n"
        echo "$pr_files" | while read -r fname; do
          review_comment+="- \`$fname\`\n"
        done
        review_comment+="\nPlease ensure fleet config changes are tested on at least one node before merging."
      fi

      if [ -n "$review_comment" ]; then
        gh api --method POST "repos/${ORG}/${MAIN_REPO}/issues/${num}/comments" \
          -f body="$(echo -e "$review_comment")" 2>/dev/null && \
          log "WATCH reviewed PR #$num" || true
      fi
    done
  fi

  # Check for stale issues (no activity in 30 days)
  local stale
  stale=$(gh api "repos/${ORG}/${MAIN_REPO}/issues?state=open&per_page=50&sort=updated&direction=asc" \
    --jq '.[] | select(.pull_request == null) | select(.updated_at < (now - 2592000 | todate)) | "\(.number)|\(.title)"' 2>/dev/null)

  if [ -n "$stale" ]; then
    echo "$stale" | head -5 | while IFS='|' read -r num title; do
      [ -z "$num" ] && continue
      log "WATCH stale issue #$num: $title"
      # Add stale label
      gh api --method POST "repos/${ORG}/${MAIN_REPO}/issues/${num}/labels" \
        -f "labels[]=stale" 2>/dev/null || true
    done
  fi
}

# ═══════════════════════════════════════════════════════════════════════
# REPORT — Create fleet status issue
# ═══════════════════════════════════════════════════════════════════════
cmd_report() {
  log "REPORT creating fleet status report"
  check_rate || return

  local body="## Fleet Status Report\n"
  body+="**Generated by:** $NODE\n"
  body+="**Timestamp:** $(date -u '+%Y-%m-%d %H:%M UTC')\n\n"
  body+="### Node Status\n\n"
  body+="| Node | Status | Temp | Load | Mem | Disk | Uptime |\n"
  body+="|------|--------|------|------|-----|------|--------|\n"

  local online=0 total=0 issues_found=""

  for sname in alice cecilia octavia aria lucidia; do
    total=$((total + 1))
    local target_user target_ip
    target_user=$(echo "${SIBLINGS[$sname]}" | cut -d@ -f1)
    target_ip=$(echo "${SIBLINGS[$sname]}" | cut -d@ -f2)

    if ssh $SSH_OPTS "${target_user}@${target_ip}" 'true' 2>/dev/null; then
      online=$((online + 1))
      local temp load mem disk uptime_str throttle
      temp=$(ssh $SSH_OPTS "${target_user}@${target_ip}" 'echo $(($(cat /sys/class/thermal/thermal_zone0/temp 2>/dev/null || echo 0) / 1000))' 2>/dev/null)
      load=$(ssh $SSH_OPTS "${target_user}@${target_ip}" 'cat /proc/loadavg | cut -d" " -f1' 2>/dev/null)
      mem=$(ssh $SSH_OPTS "${target_user}@${target_ip}" 'free | awk "/Mem:/{printf \"%.0f\", \$3*100/\$2}"' 2>/dev/null)
      disk=$(ssh $SSH_OPTS "${target_user}@${target_ip}" "df / | awk 'NR==2{print \$5}'" 2>/dev/null)
      uptime_str=$(ssh $SSH_OPTS "${target_user}@${target_ip}" 'uptime -p 2>/dev/null | sed "s/up //"' 2>/dev/null)
      throttle=$(ssh $SSH_OPTS "${target_user}@${target_ip}" 'vcgencmd get_throttled 2>/dev/null' 2>/dev/null || echo "")

      body+="| $sname | ✅ online | ${temp}°C | ${load} | ${mem}% | ${disk} | ${uptime_str} |\n"

      # Flag issues
      [ "${temp:-0}" -gt 65 ] && issues_found+="- ⚠️ **$sname** running hot: ${temp}°C\n"
      [ "${disk:-0%}" = "$(echo "$disk" | grep -oP '\d+' | head -1)" ] && {
        local dpct=$(echo "$disk" | grep -oP '\d+' | head -1)
        [ "${dpct:-0}" -gt 85 ] && issues_found+="- ⚠️ **$sname** disk ${disk} full\n"
      }
      echo "$throttle" | grep -qv "0x0" 2>/dev/null && [ -n "$throttle" ] && echo "$throttle" | grep -qv "Can't open" && \
        issues_found+="- ⚠️ **$sname** undervoltage: $throttle\n"
    else
      body+="| $sname | ❌ offline | — | — | — | — | — |\n"
      issues_found+="- 🔴 **$sname** is offline/unreachable\n"
    fi
  done

  body+="\n### Summary\n\n"
  body+="- **$online/$total** nodes online\n"

  if [ -n "$issues_found" ]; then
    body+="\n### Issues Detected\n\n$issues_found"
  fi

  body+="\n---\n*Automated fleet report by $NODE — BlackRoad Fleet Agent*\n"

  # Create the issue
  gh api --method POST "repos/${ORG}/${MAIN_REPO}/issues" \
    -f title="Fleet Status Report — $(date '+%Y-%m-%d') [$NODE]" \
    -f body="$(echo -e "$body")" \
    -f "labels[]=fleet" \
    -f "labels[]=report" 2>/dev/null && \
    log "REPORT fleet status issue created" || \
    log "REPORT failed to create issue"
}

# ═══════════════════════════════════════════════════════════════════════
# CLOSE — Auto-close resolved issues
# ═══════════════════════════════════════════════════════════════════════
cmd_close_resolved() {
  log "CLOSE checking for resolved issues"
  check_rate || return

  # Get open fleet issues
  local issues
  issues=$(gh api "repos/${ORG}/${MAIN_REPO}/issues?state=open&labels=fleet&per_page=20" \
    --jq '.[] | select(.pull_request == null) | "\(.number)|\(.title)"' 2>/dev/null)

  [ -z "$issues" ] && return

  echo "$issues" | while IFS='|' read -r num title; do
    [ -z "$num" ] && continue
    local title_lower=$(echo "$title" | tr '[:upper:]' '[:lower:]')
    local resolved=false
    local resolution=""

    # Check if "offline" issues are resolved
    if echo "$title_lower" | grep -qiE "offline|down|unreachable"; then
      # Extract node name from title
      for sname in alice cecilia octavia aria lucidia; do
        if echo "$title_lower" | grep -qi "$sname"; then
          local target_user target_ip
          target_user=$(echo "${SIBLINGS[$sname]}" | cut -d@ -f1)
          target_ip=$(echo "${SIBLINGS[$sname]}" | cut -d@ -f2)
          if ssh $SSH_OPTS "${target_user}@${target_ip}" 'true' 2>/dev/null; then
            resolved=true
            resolution="$sname is back online and responding to SSH."
          fi
        fi
      done
    fi

    if [ "$resolved" = true ]; then
      # Comment and close
      gh api --method POST "repos/${ORG}/${MAIN_REPO}/issues/${num}/comments" \
        -f body="**[$NODE] Auto-Resolved**

$resolution

Verified by fleet agent at $(date -u '+%Y-%m-%d %H:%M UTC').

---
*Automated by $NODE — BlackRoad Fleet Agent*" 2>/dev/null

      gh api --method PATCH "repos/${ORG}/${MAIN_REPO}/issues/${num}" \
        -f state="closed" \
        -f state_reason="completed" 2>/dev/null && \
        log "CLOSE resolved #$num: $resolution" || true
    fi
  done
}

# ═══════════════════════════════════════════════════════════════════════
# SCAN-REPOS — Check health across all org repos
# ═══════════════════════════════════════════════════════════════════════
cmd_scan_repos() {
  log "SCAN checking health of all repos"
  check_rate || return

  local repos
  repos=$(gh api "users/${ORG}/repos?per_page=100&sort=updated" \
    --jq '.[] | select(.archived == false) | "\(.name)|\(.default_branch)|\(.open_issues_count)|\(.pushed_at)"' 2>/dev/null)

  local stale_repos="" issues_repos=""

  echo "$repos" | while IFS='|' read -r name branch issues pushed; do
    [ -z "$name" ] && continue

    # Check for repos not pushed in 90 days
    local pushed_epoch now_epoch
    pushed_epoch=$(date -d "$pushed" +%s 2>/dev/null || date -j -f "%Y-%m-%dT%H:%M:%SZ" "$pushed" +%s 2>/dev/null || echo 0)
    now_epoch=$(date +%s)
    local days_since=$(( (now_epoch - pushed_epoch) / 86400 ))

    if [ "$days_since" -gt 90 ]; then
      log "SCAN stale repo: $name (${days_since}d since last push)"
    fi

    if [ "$issues" -gt 5 ]; then
      log "SCAN repo with many issues: $name ($issues open)"
    fi
  done
}

# ═══════════════════════════════════════════════════════════════════════
# FULL CYCLE
# ═══════════════════════════════════════════════════════════════════════
cmd_cycle() {
  log "=== GitHub agent cycle started ==="
  cmd_triage
  cmd_respond
  cmd_watch
  cmd_close_resolved
  log "=== GitHub agent cycle complete ==="
}

# ═══════════════════════════════════════════════════════════════════════
# HELP
# ═══════════════════════════════════════════════════════════════════════
cmd_help() {
  echo ""
  echo "  br-github — $NODE's GitHub Agent"
  echo "  ─────────────────────────────────"
  echo ""
  echo "  cycle        Full GitHub cycle (triage + respond + watch + close)"
  echo "  triage       Auto-label unlabeled issues"
  echo "  respond      Comment on issues with fleet data"
  echo "  watch        Monitor PRs and stale issues"
  echo "  report       Create fleet status report issue"
  echo "  close        Auto-close resolved fleet issues"
  echo "  scan-repos   Health check across all org repos"
  echo "  help         This help"
  echo ""
}

# ═══════════════════════════════════════════════════════════════════════
# MAIN
# ═══════════════════════════════════════════════════════════════════════
ACTION="${1:-help}"

case "$ACTION" in
  cycle)        cmd_cycle ;;
  triage)       cmd_triage ;;
  respond)      cmd_respond ;;
  watch)        cmd_watch ;;
  report)       cmd_report ;;
  close)        cmd_close_resolved ;;
  scan-repos)   cmd_scan_repos ;;
  help|--help)  cmd_help ;;
  *)
    echo "Unknown: $ACTION"
    cmd_help
    exit 1
    ;;
esac
