#!/usr/bin/env bash

################################################################################
# 闪电API - Hermes Agent 一键配置脚本
#
# 功能: 选择线路 / 选择模型类型 / 拉取模型列表 / 写入 Hermes 配置
# 官网: flashapi.top
# 模型调用: ai.flashapi.top (国内直连) / cdn.flashapi.top (海外CDN)
################################################################################

set -euo pipefail
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
GRAY='\033[0;90m'
BOLD='\033[1m'
BLUE='\033[38;5;33m'
BRIGHT_YELLOW='\033[38;5;226m'
NC='\033[0m'

HERMES_CONFIG_DIR="${HERMES_CONFIG_DIR:-$HOME/.hermes}"
HERMES_CONFIG_FILE="$HERMES_CONFIG_DIR/config.yaml"
CLAUDE_MODELS=("claude-opus-4-6" "claude-opus-4-7" "claude-sonnet-4-6" "claude-haiku-4-5")
CODEX_MODELS=("gpt-5.5" "gpt-5.4" "gpt-5.4-mini" "gpt-5.3-codex" "gpt-5.2")

ROUTE_LABEL=""
ROUTE_BASE_URL=""
MODEL_LABEL=""
PROVIDER=""
PROVIDER_BASE_URL=""
MODEL_KEY=""
MODEL_ID=""
API_KEY=""
MODEL_CHOICES=()

print_banner() {
  echo ""
  echo -e "  ${BOLD}${BRIGHT_YELLOW}    ⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡${NC}"
  echo -e "  ${BOLD}${BRIGHT_YELLOW}  ███████╗██╗      █████╗ ███████╗██╗  ██╗${NC}"
  echo -e "  ${BOLD}${BRIGHT_YELLOW}  ██╔════╝██║     ██╔══██╗██╔════╝██║  ██║${NC}"
  echo -e "  ${BOLD}${BRIGHT_YELLOW}  █████╗  ██║     ███████║███████╗███████║${NC}"
  echo -e "  ${BOLD}${BRIGHT_YELLOW}  ██╔══╝  ██║     ██╔══██║╚════██║██╔══██║${NC}"
  echo -e "  ${BOLD}${BRIGHT_YELLOW}  ██║     ███████╗██║  ██║███████║██║  ██║${NC}"
  echo -e "  ${BOLD}${BRIGHT_YELLOW}  ╚═╝     ╚══════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝${NC}"
  echo -e "  ${BOLD}${BLUE}           ⚡ A P I ⚡${NC}"
  echo -e "  ${BOLD}${BRIGHT_YELLOW}    ⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡${NC}"
  echo ""
  echo -e "  ${GRAY}───────────────────────────────────────────────────────${NC}"
  echo -e "  ${WHITE}⚡ 闪电API${NC} ${GRAY}|${NC} ${CYAN}官网${NC} ${BOLD}${BRIGHT_YELLOW}flashapi.top${NC}"
  echo -e "  ${WHITE}Hermes Agent 一键配置${NC} ${GRAY}|${NC} ${CYAN}让顶尖模型触手可及${NC}"
  echo -e "  ${GRAY}───────────────────────────────────────────────────────${NC}"
  echo -e "  ${GRAY}国内直连:${NC} ${GREEN}ai.flashapi.top${NC}  ${GRAY}海外CDN:${NC} ${GREEN}cdn.flashapi.top${NC}"
  echo -e "  ${GRAY}───────────────────────────────────────────────────────${NC}"
  echo ""
}

print_status() {
  local type="$1"
  local message="$2"
  case "$type" in
    ok)    echo -e "  ${GREEN}[⚡]${NC} $message" ;;
    info)  echo -e "  ${CYAN}[*]${NC} $message" ;;
    warn)  echo -e "  ${YELLOW}[!]${NC} $message" ;;
    error) echo -e "  ${RED}[x]${NC} $message" ;;
    *)     echo "  $message" ;;
  esac
}

require_commands() {
  if ! command -v curl >/dev/null 2>&1; then
    print_status "error" "未检测到 curl，无法拉取模型列表"
    exit 1
  fi
}

attach_terminal_stdin() {
  if [[ -r /dev/tty ]]; then
    exec </dev/tty
  fi
}

mask_key() {
  local value="$1"
  if [[ -z "$value" ]]; then
    echo ""
    return
  fi
  if [[ ${#value} -le 12 ]]; then
    echo "$value"
    return
  fi
  echo "${value:0:8}...${value: -4}"
}

choose_route() {
  echo -e "  ${WHITE}请选择 API 线路:${NC}"
  echo ""
  echo -e "    ${BRIGHT_YELLOW}⚡${NC} ${CYAN}1)${NC} ${GREEN}国内直连${NC} - https://ai.flashapi.top"
  echo -e "       ${GRAY}服务器位于香港，国内可直连${NC}"
  echo ""
  echo -e "    ${BRIGHT_YELLOW}⚡${NC} ${CYAN}2)${NC} ${GREEN}海外CDN${NC}  - https://cdn.flashapi.top"
  echo -e "       ${GRAY}全球 CDN 加速，适合海外用户${NC}"
  echo ""
  echo -en "  ${WHITE}请输入选项 (1/2): ${NC}" >&2

  local choice
  read -r choice < /dev/tty

  case "$choice" in
    1)
      ROUTE_LABEL="国内直连"
      ROUTE_BASE_URL="https://ai.flashapi.top"
      ;;
    2)
      ROUTE_LABEL="海外CDN"
      ROUTE_BASE_URL="https://cdn.flashapi.top"
      ;;
    *)
      print_status "error" "无效线路选项，已取消"
      exit 1
      ;;
  esac

  echo ""
  print_status "ok" "已选择线路: ${ROUTE_LABEL} (${ROUTE_BASE_URL})"
}

choose_model_type() {
  echo ""
  echo -e "  ${WHITE}请选择模型类型:${NC}"
  echo ""
  echo -e "    ${BRIGHT_YELLOW}⚡${NC} ${CYAN}1)${NC} ${GREEN}GPT${NC}"
  echo -e "       ${GRAY}自动筛选 OpenAI / GPT 系列模型${NC}"
  echo ""
  echo -e "    ${BRIGHT_YELLOW}⚡${NC} ${CYAN}2)${NC} ${GREEN}Claude${NC}"
  echo -e "       ${GRAY}自动筛选 Anthropic / Claude 系列模型${NC}"
  echo ""
  echo -en "  ${WHITE}请输入选项 (1/2): ${NC}" >&2

  local choice
  read -r choice < /dev/tty

  case "$choice" in
    1)
      MODEL_LABEL="GPT"
      PROVIDER="openai"
      PROVIDER_BASE_URL="${ROUTE_BASE_URL}/v1"
      ;;
    2)
      MODEL_LABEL="Claude"
      PROVIDER="anthropic"
      PROVIDER_BASE_URL="${ROUTE_BASE_URL}"
      ;;
    *)
      print_status "error" "无效模型类型，已取消"
      exit 1
      ;;
  esac

  echo ""
  print_status "ok" "已选择模型类型: ${MODEL_LABEL}"
  if [[ "$PROVIDER" == "anthropic" ]]; then
    print_status "info" "Anthropic（Claude）接口使用 ${PROVIDER_BASE_URL}，不要追加 /v1"
  else
    print_status "info" "OpenAI（Codex）接口使用 ${PROVIDER_BASE_URL}，必须带 /v1"
  fi
}

read_api_key() {
  echo ""
  echo -en "  ${WHITE}请输入 API Key: ${NC}" >&2

  local value=""
  while IFS= read -r -s -n1 char < /dev/tty; do
    if [[ "$char" == $'\0' || "$char" == $'\n' || "$char" == $'\r' ]]; then
      break
    elif [[ "$char" == $'\177' || "$char" == $'\b' ]]; then
      if [[ -n "$value" ]]; then
        value="${value%?}"
        echo -en "\b \b" >&2
      fi
    else
      value+="$char"
      echo -n "*" >&2
    fi
  done
  echo "" >&2

  if [[ -z "$value" ]]; then
    print_status "error" "API Key 不能为空，已取消"
    exit 1
  fi

  API_KEY="$value"
  print_status "info" "已读取 API Key: $(mask_key "$API_KEY")"
}

fetch_models() {
  echo ""
  print_status "info" "正在拉取模型列表并验证连通性 ..."

  local response models_url
  models_url="${PROVIDER_BASE_URL}/models"
  response="$(
    curl -sS --connect-timeout 8 --max-time 20 \
      -H "Authorization: Bearer ${API_KEY}" \
      -H "x-api-key: ${API_KEY}" \
      -H "anthropic-version: 2023-06-01" \
      "$models_url" 2>/dev/null || true
  )"

  if [[ -z "$response" ]]; then
    response="$(
      curl -sS --connect-timeout 8 --max-time 20 \
        -H "Authorization: Bearer ${API_KEY}" \
        -H "x-api-key: ${API_KEY}" \
        -H "anthropic-version: 2023-06-01" \
        "${ROUTE_BASE_URL}/v1/models" 2>/dev/null || true
    )"
  fi

  MODEL_CHOICES=()
  local parsed=""

  if [[ -n "$response" ]] && command -v python3 >/dev/null 2>&1; then
    parsed="$(
      printf '%s' "$response" | PROVIDER="$PROVIDER" python3 -c '
import json, os, sys

provider = os.environ.get("PROVIDER", "")
try:
    data = json.load(sys.stdin)
except Exception:
    sys.exit(0)

if isinstance(data, dict):
    models = data.get("data") or data.get("models") or []
elif isinstance(data, list):
    models = data
else:
    models = []

def item_id(item):
    if isinstance(item, dict):
        return str(item.get("id") or item.get("name") or item.get("model") or "").strip()
    return str(item).strip()

def matches(value):
    lower = value.lower()
    if not lower:
        return False
    if provider == "anthropic":
        return lower.startswith("anthropic/") or "claude" in lower
    return (
        lower.startswith("openai/")
        or lower.startswith("gpt-")
        or lower.startswith("chatgpt-")
        or lower.startswith("o1")
        or lower.startswith("o3")
        or lower.startswith("o4")
        or "codex" in lower
    )

seen = set()
for item in models:
    value = item_id(item)
    if not matches(value):
        continue
    if "/" in value:
        value = value.split("/", 1)[1]
    if value in seen:
        continue
    seen.add(value)
    print(value)
' 2>/dev/null || true
    )"
  fi

  local line
  while IFS= read -r line; do
    [[ -n "$line" ]] && MODEL_CHOICES+=("$line")
  done <<<"$parsed"

  if [[ ${#MODEL_CHOICES[@]} -eq 0 ]]; then
    print_status "warn" "模型列表拉取或解析失败，使用内置推荐列表"
    if [[ "$PROVIDER" == "anthropic" ]]; then
      MODEL_CHOICES=("${CLAUDE_MODELS[@]}")
    else
      MODEL_CHOICES=("${CODEX_MODELS[@]}")
    fi
    return
  fi

  print_status "ok" "模型列表请求成功"
}

choose_model_from_remote() {
  print_status "info" "正在筛选 ${MODEL_LABEL} 模型 ..."

  echo ""
  echo -e "  ${WHITE}请选择具体模型:${NC}"
  echo ""

  local i=1
  local id
  for id in "${MODEL_CHOICES[@]}"; do
    echo -e "    ${BRIGHT_YELLOW}⚡${NC} ${CYAN}${i})${NC} ${GREEN}${id}${NC}"
    echo ""
    i=$((i + 1))
  done

  echo -en "  ${WHITE}请输入模型编号: ${NC}" >&2
  local choice
  read -r choice < /dev/tty

  if ! [[ "$choice" =~ ^[0-9]+$ ]]; then
    print_status "error" "模型编号无效"
    exit 1
  fi

  if (( choice < 1 || choice > ${#MODEL_CHOICES[@]} )); then
    print_status "error" "模型编号超出范围"
    exit 1
  fi

  MODEL_ID="${MODEL_CHOICES[$((choice - 1))]}"
  MODEL_KEY="${PROVIDER}/${MODEL_ID}"

  print_status "ok" "已选择模型: ${MODEL_ID}"
}

confirm_write() {
  echo ""
  print_status "info" "即将写入 Hermes 配置"
  echo ""
  echo -e "    ${WHITE}线路:${NC} ${GREEN}${ROUTE_LABEL}${NC}"
  echo -e "    ${WHITE}接口:${NC} ${GREEN}${PROVIDER_BASE_URL}${NC}"
  echo -e "    ${WHITE}类型:${NC} ${GREEN}${MODEL_LABEL}${NC}"
  echo -e "    ${WHITE}Provider:${NC} ${GREEN}${PROVIDER}${NC}"
  echo -e "    ${WHITE}模型:${NC} ${GREEN}${MODEL_ID}${NC}"
  echo -e "    ${WHITE}API Key:${NC} ${GREEN}$(mask_key "$API_KEY")${NC}"
  echo ""
  echo -en "  ${YELLOW}确认写入配置? (y/N): ${NC}" >&2

  local answer
  read -r answer < /dev/tty
  if [[ "$answer" != "y" && "$answer" != "Y" ]]; then
    print_status "warn" "已取消配置"
    exit 0
  fi
}

confirm_yes() {
  local prompt="$1"
  local answer
  echo -en "  ${YELLOW}${prompt}${NC}" >&2
  read -r answer < /dev/tty
  case "$answer" in
    y|Y|yes|YES|Yes) return 0 ;;
    *) return 1 ;;
  esac
}

yaml_quote() {
  printf "'%s'" "$(printf '%s' "$1" | sed "s/'/''/g")"
}

write_hermes_config() {
  mkdir -p "$HERMES_CONFIG_DIR"

  if [[ -f "$HERMES_CONFIG_FILE" ]]; then
    local stamp backup
    stamp="$(date +%Y%m%d%H%M%S)"
    backup="$HERMES_CONFIG_FILE.bak.$stamp"
    cp "$HERMES_CONFIG_FILE" "$backup"
    print_status "info" "已备份原配置到 $backup"
  fi

  local provider_name env_key
  if [[ "$PROVIDER" == "anthropic" ]]; then
    provider_name="flashapi-claude"
    env_key="ANTHROPIC_API_KEY"
  else
    provider_name="flashapi-codex"
    env_key="OPENAI_API_KEY"
  fi

  cat > "$HERMES_CONFIG_FILE" <<EOF
# 闪电API Hermes 配置
# Claude / Anthropic 接口不要带 /v1，OpenAI / Codex 接口必须带 /v1。
models:
  default: $(yaml_quote "${provider_name}/${MODEL_ID}")

providers:
  ${provider_name}:
    type: $(yaml_quote "$PROVIDER")
    base_url: $(yaml_quote "$PROVIDER_BASE_URL")
    api_key: $(yaml_quote "$API_KEY")
    api_key_env: $(yaml_quote "$env_key")
    default_model: $(yaml_quote "$MODEL_ID")
    models:
      - $(yaml_quote "$MODEL_ID")
EOF
}

detect_hermes() {
  if command -v hermes >/dev/null 2>&1; then
    print_status "ok" "Hermes 已安装: $(command -v hermes)"
    return 0
  fi

  print_status "warn" "未检测到 Hermes 客户端；本脚本只写入配置，不会自动安装或重装 Hermes"
  return 1
}

show_result() {
  echo ""
  print_status "ok" "Hermes 配置已更新"
  echo -e "    ${WHITE}配置文件:${NC} ${GREEN}${HERMES_CONFIG_FILE}${NC}"
  echo -e "    ${WHITE}Provider:${NC} ${GREEN}${PROVIDER}${NC}"
  echo -e "    ${WHITE}Base URL:${NC} ${GREEN}${PROVIDER_BASE_URL}${NC}"
  echo -e "    ${WHITE}Model:${NC} ${GREEN}${MODEL_ID}${NC}"
  echo ""
  print_status "info" "如需使用 Hermes 交互命令调整模型，可运行: hermes model"
  print_status "info" "如果 Hermes 正在运行，建议重启相关进程后再使用"
}

maybe_launch_hermes() {
  detect_hermes || true
  if confirm_yes "是否立即启动 Hermes？[y/N]: "; then
    if command -v hermes >/dev/null 2>&1; then
      attach_terminal_stdin
      exec hermes
    fi
    print_status "warn" "未找到 hermes 命令，请先安装后手动运行: hermes"
  else
    print_status "info" "已跳过启动。请退出当前 Hermes 会话后重新运行: hermes"
  fi
}

main() {
  print_banner
  require_commands
  choose_route
  choose_model_type
  read_api_key
  fetch_models
  choose_model_from_remote
  confirm_write
  write_hermes_config
  show_result
  maybe_launch_hermes
}

main "$@"
