# shellcheck shell=bash
# lib-menu.sh — interactive menu (option C hybrid).
#
# Hierarchy: whiptail > dialog > plain-text bash-select. Stdout contract:
#   - one-line output = profile name OR comma-separated custom primitive list
#   - empty stdout + exit 1 = user cancelled
# Menu is ONLY triggered from the top-level flow: never from --add/--remove/--list.
#
# Requires: all_primitive_names, primitive_field from lib-profile.sh.
# Requires: err from lib-log.sh.
# Reads globals: PROFILE, ADD_LIST, REMOVE_NAME, LIST_MODE (set by install.sh).

# menu_should_skip — return 0 if menu should be skipped, 1 if it should run.
# Skip reasons: any selection flag was passed, or stdin/stdout is not a TTY.
menu_should_skip() {
  [ -n "$PROFILE" ]      && return 0
  [ -n "$ADD_LIST" ]     && return 0
  [ -n "$REMOVE_NAME" ]  && return 0
  [ "$LIST_MODE" = "1" ] && return 0
  [ ! -t 0 ]             && return 0
  [ ! -t 1 ]             && return 0
  return 1
}

# whiptail/dialog radiolist → profile name. Exits 1 on cancel.
menu_whiptail_profile() {
  local tool="$1"
  "$tool" --title "KeiSeiKit Installer" --radiolist \
    "Choose install profile (SPACE to select, ENTER to confirm):" 22 78 8 \
    "minimal"  "agents + hooks + skills + bridges (~5s)"           ON  \
    "core"     "+ tomd (~5s)"                                       OFF \
    "frontend" "+ 8 site tools (~60s, 80 MB)"                       OFF \
    "ops"      "+ 8 infra tools (~90s, 50 MB)"                      OFF \
    "dev"      "+ 9 dev tools (~60s, 40 MB)"                        OFF \
    "mcp"      "+ 10 LBM-port MCP tools (~90s, 50 MB)"              OFF \
    "full"     "all 36 primitives (~5 min, 200 MB)"                 OFF \
    "custom"   "pick individual primitives"                         OFF \
    3>&1 1>&2 2>&3
}

# whiptail/dialog checklist → comma-separated primitive names. Exits 1 on cancel.
menu_whiptail_custom() {
  local tool="$1"
  local args=() name desc
  while IFS= read -r name; do
    [ -z "$name" ] && continue
    desc="$(primitive_field "$name" desc 2>/dev/null || echo '')"
    # truncate long descs so whiptail doesn't wrap awkwardly
    desc="${desc:0:48}"
    args+=("$name" "$desc" "OFF")
  done < <(all_primitive_names)
  local picked
  picked="$("$tool" --title "Custom — pick primitives" --checklist \
    "SPACE to toggle, ENTER to confirm:" 24 78 16 \
    "${args[@]}" 3>&1 1>&2 2>&3)" || return 1
  # whiptail emits quoted names separated by spaces; normalize to csv
  echo "$picked" | tr -d '"' | tr ' ' ',' | sed 's/^,//;s/,$//'
}

# plain-text profile picker → profile name. Exits 1 on cancel.
menu_plain_profile() {
  echo "================================" >&2
  echo " KeiSeiKit Installer"             >&2
  echo "================================" >&2
  echo                                     >&2
  echo "Choose install profile:"           >&2
  echo                                     >&2
  echo "  1) minimal   — agents + hooks + skills + bridges only (~5s)" >&2
  echo "  2) core      — + tomd (~5s)"                                  >&2
  echo "  3) frontend  — + 8 site tools (~60s, 80 MB)"                  >&2
  echo "  4) ops       — + 8 infra tools (~90s, 50 MB)"                 >&2
  echo "  5) dev       — + 9 dev tools (~60s, 40 MB)"                   >&2
  echo "  6) mcp       — + 10 LBM-port MCP tools (~90s, 50 MB)"         >&2
  echo "  7) full      — all 36 primitives (~5 min, 200 MB)"            >&2
  echo "  8) custom    — pick individual primitives"                    >&2
  echo                                                                   >&2
  local reply
  printf 'Enter choice [1-8] (default 1): ' >&2
  read -r reply || return 1
  case "${reply:-1}" in
    1) echo minimal  ;;
    2) echo core     ;;
    3) echo frontend ;;
    4) echo ops      ;;
    5) echo dev      ;;
    6) echo mcp      ;;
    7) echo full     ;;
    8) echo custom   ;;
    *) err "invalid choice: $reply"; return 1 ;;
  esac
}

# Print the numbered primitive list to stderr (helper for plain custom picker).
_print_primitive_list() {
  local -a names=("$@")
  local i desc
  echo                                         >&2
  echo "Select primitives (space-separated numbers, 'a' for all, 'n' for none):" >&2
  echo                                         >&2
  for (( i=0; i<${#names[@]}; i++ )); do
    desc="$(primitive_field "${names[$i]}" desc 2>/dev/null || echo '')"
    printf "  %2d) [ ] %-20s — %s\n" "$((i+1))" "${names[$i]}" "$desc" >&2
  done
  echo                                         >&2
}

# plain-text custom picker → comma-separated primitive names.
menu_plain_custom() {
  local -a names=() picked=()
  local name reply tok
  while IFS= read -r name; do
    [ -z "$name" ] && continue
    names+=("$name")
  done < <(all_primitive_names)
  _print_primitive_list "${names[@]}"
  printf 'Selection: ' >&2
  read -r reply || return 1
  case "$reply" in
    a|A|all) picked=("${names[@]}") ;;
    n|N|none|'') picked=() ;;
    *)
      for tok in $reply; do
        [[ "$tok" =~ ^[0-9]+$ ]] && (( tok >= 1 && tok <= ${#names[@]} )) \
          && picked+=("${names[$((tok-1))]}")
      done
      ;;
  esac
  local IFS=,; echo "${picked[*]}"
}

# Run the menu and parse its output into PROFILE / CUSTOM_PRIMS globals.
# Returns 0 on success (incl. menu_should_skip), 1 on user cancel.
run_menu_if_needed() {
  CUSTOM_PRIMS=""
  CONFIRM_TOTAL=0
  CONFIRM_SECS=0
  CONFIRM_MB=0
  menu_should_skip && return 0
  [ -f "$MANIFEST" ] || { err "MANIFEST.toml missing: $MANIFEST"; exit 2; }
  local menu_out
  menu_out="$(show_interactive_menu)" || { say "menu cancelled — aborting"; return 1; }
  if [ -z "$menu_out" ]; then
    say "no selection — aborting"
    return 1
  fi
  if echo "$menu_out" | grep -q ','; then
    CUSTOM_PRIMS="$menu_out"
    PROFILE="custom"
  elif echo "$menu_out" | grep -qE '^(minimal|core|frontend|ops|dev|mcp|full)$'; then
    PROFILE="$menu_out"
  else
    # Single name from custom-with-one-item — treat as CUSTOM_PRIMS
    CUSTOM_PRIMS="$menu_out"
    PROFILE="custom"
  fi
  return 0
}

# show_interactive_menu — master dispatcher. Echoes profile name OR csv list.
show_interactive_menu() {
  local tool=""
  if command -v whiptail >/dev/null 2>&1; then
    tool="whiptail"
  elif command -v dialog >/dev/null 2>&1; then
    tool="dialog"
  fi
  local choice
  if [ -n "$tool" ]; then
    choice="$(menu_whiptail_profile "$tool")" || return 1
    if [ "$choice" = "custom" ]; then
      menu_whiptail_custom "$tool" || return 1
    else
      echo "$choice"
    fi
  else
    choice="$(menu_plain_profile)" || return 1
    if [ "$choice" = "custom" ]; then
      menu_plain_custom
    else
      echo "$choice"
    fi
  fi
}
