#!/usr/bin/env bash
# ccjump — pick an active Claude/amux session (this machine + configured remote machines) and JUMP to it.
#   local session  -> tmux switch-client (when inside tmux) else `amux attach`
#   remote session -> `amux-remote <box> attach` (rides SSH; opens an iTerm -CC tab)
# TUI: fzf with a live preview pane (recent output of the highlighted session). Local rows show
# instantly; remotes stream in (fetched in parallel, each time-limited so a down box can't hang).
# Fallbacks if no fzf: macOS `choose from list` (clickable) > numbered menu. bash-3.2 safe (like amux).
#
#   ccjump            pick + jump (fzf TUI)
#   ccjump --list     print discovered sessions (no picker/jump)
# Internal: --feed (stream rows for fzf/reload), --preview <row> (preview pane body).
# Binding (tmux 3.2+):  bind-key j display-popup -w 90% -h 70% -E ccjump
case "${1:-}" in -h|--help)
  awk 'NR==1&&/^#!/{next} /^[[:space:]]*#/{sub(/^[[:space:]]*#[[:space:]]?/,"");print;next} {exit}' "$0"; exit 0 ;;
esac
set -uo pipefail
# PATH covers the common install dirs across macOS (Homebrew intel+ARM), Linux,
# and MSYS2/Git Bash, so these work when launched from a GUI or a cron/launchd
# context that does not source your shell rc.
export PATH="$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin:/home/linuxbrew/.linuxbrew/bin:/mingw64/bin:/usr/bin:/bin:$PATH"
AMUX="${AMUX:-amux}"; AMUXBOX="${AMUXBOX:-amux-remote}"   # amux-remote <box> <cmd> (box-required)
SELF="$0"; case "$SELF" in */*) : ;; *) SELF="$(command -v "$SELF" || echo "$HOME/scripts/ccjump")";; esac
strip(){ sed -E 's/\x1b\[[0-9;]*[a-zA-Z]//g'; }

tmo(){ # tmo SECONDS cmd...   (portable timeout; macOS has no `timeout`)
  local s="$1"; shift; "$@" & local p=$!
  ( sleep "$s"; kill -TERM "$p" 2>/dev/null ) 2>/dev/null & local k=$!
  wait "$p" 2>/dev/null; local rc=$?; kill -TERM "$k" 2>/dev/null; return $rc
}
row(){ # loc name run hint  -> colored, aligned; loc(field1)+name(field3) stay PLAIN for parse-back
  local loc="$1" name="$2" run="$3" hint="$4" mark
  if [ -n "$run" ]; then mark=$'\033[32m●\033[0m'; else mark=$'\033[2m○\033[0m'; fi
  printf '%-7s %b  %-20s \033[2m%s\033[0m\n' "$loc" "$mark" "$name" "${hint:0:52}"
}
feed(){
  "$AMUX" ls 2>/dev/null | strip | while IFS= read -r line; do
    if [[ "$line" =~ ^[[:space:]]*[0-9]+(\*?)[[:space:]]+([^[:space:]]+)[[:space:]]+(.*)$ ]]; then
      row local "${BASH_REMATCH[2]}" "${BASH_REMATCH[1]:+r}" "${BASH_REMATCH[3]}"
    fi
  done
  local f box
  for f in "$HOME"/.amux/remotes/*.env; do
    [ -e "$f" ] || continue; box="$(basename "$f" .env)"
    (
      tmo 4 "$AMUXBOX" "$box" ls --bare 2>/dev/null | strip | while IFS= read -r line; do
        line="${line#"${line%%[![:space:]]*}"}"; [ -n "$line" ] || continue
        case "$line" in *" sessions"|*sessions|"No "*|error*|ERROR*) continue ;; esac
        run=""; if [ "${line:0:1}" = "*" ]; then run="r"; line="${line#\*}"; line="${line#"${line%%[![:space:]]*}"}"; fi
        row "$box" "${line%%[[:space:]]*}" "$run" ""
      done
    ) &
  done
  wait
}

case "${1:-}" in
  --feed) feed; exit 0 ;;
  --list) feed | strip; exit 0 ;;
  --preview)
    shift; line="$(printf '%s' "$*" | strip)"; read -r loc _m name _rest <<<"$line"
    [ -n "${name:-}" ] || exit 0
    if [ "$loc" = local ]; then "$AMUX" peek "$name" 2>/dev/null || echo "(no preview)"
    else tmo 4 "$AMUXBOX" "$loc" peek "$name" 2>/dev/null || echo "(no preview)"; fi
    exit 0 ;;
esac

# ---- pick ----
choice=""
if command -v fzf >/dev/null 2>&1; then
  choice="$(feed | fzf --ansi --reverse --cycle --border --info=inline \
      --prompt='claude ▸ ' --header='↵ jump   ⌃r reload   esc cancel   (● running ○ idle · click or type to filter)' \
      --preview "$SELF --preview {}" --preview-window='right,55%,border-left,wrap' \
      --bind "ctrl-r:reload($SELF --feed)")"
elif command -v osascript >/dev/null 2>&1; then
  _rows=(); while IFS= read -r _l; do [ -n "$_l" ] && _rows+=("$_l"); done < <(feed | strip)
  [ "${#_rows[@]}" -gt 0 ] || { echo "no sessions" >&2; exit 1; }
  choice="$(osascript -e 'on run a' -e 'set c to choose from list a with prompt "Jump to a Claude session:" with title "ccjump"' -e 'if c is false then return ""' -e 'return item 1 of c' -e 'end run' "${_rows[@]}")"
else
  echo "Select a session:"; select choice in $(feed | strip); do break; done
fi
[ -n "${choice:-}" ] || exit 0

# ---- parse (LOC=field1, NAME=field3) + jump ----
read -r loc _mark name _rest <<<"$(printf '%s' "$choice" | strip)"
[ -n "${name:-}" ] || exit 0
if [ "$loc" = local ]; then
  if [ -n "${TMUX:-}" ]; then exec tmux switch-client -t "=amux-$name"; else exec "$AMUX" attach "$name"; fi
else
  exec "$AMUXBOX" "$loc" attach "$name"
fi
