#!/usr/bin/env bash
################################################################################
# BUZZ AI - Claude Code 一键安装脚本 v2.0
#
# 功能: 安装 Claude Code + 配置 API + 安装余额显示插件
# 用法: curl -fsSL https://buzzai.cc/sh/claudecode.sh | bash
#       bash claudecode.sh --help
#
# 不需要 sudo，所有操作在用户目录下完成
################################################################################

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'
GOLD='\033[38;5;220m'
NC='\033[0m'

CLAUDE_DIR="$HOME/.claude"
SETTINGS_FILE="$CLAUDE_DIR/settings.json"
OS_TYPE=""
IS_WSL=false
LINUX_DISTRO=""

# CLI 参数全局变量
ARG_YES=false
ARG_API_KEY=""
ARG_BASE_URL=""
ARG_NO_COLOR=false
ARG_ACTION=""

################################################################################
# CLI 参数解析
################################################################################

show_help() {
  cat << 'EOF'

  BUZZ AI - Claude Code 一键安装脚本

  用法:
    bash claudecode.sh [选项]

  选项:
    -h, --help              显示帮助信息
    -y, --yes               非交互模式，执行全部安装
    --api-key=KEY           设置 API Key
    --base-url=URL          设置 Base URL
    --no-color              禁用颜色输出
    --install-only          仅安装 Claude Code
    --configure-only        仅配置 API
    --statusline-only       仅安装余额插件
    --uninstall             卸载配置和插件
    --speedtest             测试各端点真实延迟

  示例:
    bash claudecode.sh --yes --api-key=sk-xxx --base-url=https://claude.buzz7.top
    bash claudecode.sh --install-only
    bash claudecode.sh --uninstall

EOF
  exit 0
}

parse_args() {
  while [[ $# -gt 0 ]]; do
    case "$1" in
      -h|--help) show_help ;;
      -y|--yes) ARG_YES=true ;;
      --api-key=*) ARG_API_KEY="${1#*=}" ;;
      --base-url=*) ARG_BASE_URL="${1#*=}" ;;
      --no-color) ARG_NO_COLOR=true ;;
      --install-only) ARG_ACTION="install" ;;
      --configure-only) ARG_ACTION="configure" ;;
      --statusline-only) ARG_ACTION="statusline" ;;
      --uninstall) ARG_ACTION="uninstall" ;;
      --speedtest) ARG_ACTION="speedtest" ;;
      *) echo "未知参数: $1 (使用 --help 查看帮助)"; exit 1 ;;
    esac
    shift
  done
}

apply_color_settings() {
  if [[ "$ARG_NO_COLOR" == "true" ]] || ! [ -t 2 ]; then
    RED="" GREEN="" YELLOW="" CYAN="" WHITE="" GRAY="" BOLD="" GOLD="" NC=""
  fi
}

################################################################################
# 工具函数
################################################################################

print_banner() {
  echo ""
  echo -e "  ${BOLD}${GOLD} ██████  ██    ██ ███████ ███████    ${WHITE} █████  ██${NC}"
  echo -e "  ${BOLD}${GOLD} ██   ██ ██    ██    ██     ██       ${WHITE}██   ██ ██${NC}"
  echo -e "  ${BOLD}${GOLD} ██████  ██    ██   ██     ██        ${WHITE}███████ ██${NC}"
  echo -e "  ${BOLD}${GOLD} ██   ██ ██    ██  ██     ██         ${WHITE}██   ██ ██${NC}"
  echo -e "  ${BOLD}${GOLD} ██████   ██████  ███████ ███████    ${WHITE}██   ██ ██${NC}"
  echo ""
  echo -e "  ${GRAY}────────────────────────────────────────────────${NC}"
  echo -e "  ${WHITE}Claude Code 一键安装${NC}"
  echo -e "  ${BOLD}${GOLD}claude.buzz7.top${NC}  ${GRAY}|${NC}  ${GRAY}主站${NC} ${GOLD}buzzai.cc${NC}  ${GRAY}|${NC}  ${GRAY}镜像${NC} ${GOLD}buzzai.top${NC}"
  echo -e "  ${GRAY}────────────────────────────────────────────────${NC}"
  echo ""
}

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

read_tty() {
  if [[ "$ARG_YES" == "true" ]]; then
    return 1
  fi
  if [[ -e /dev/tty ]]; then
    read "$@" < /dev/tty
  else
    read "$@"
  fi
}

detect_os() {
  local uname_s
  uname_s="$(uname -s)"
  IS_WSL=false

  case "$uname_s" in
    Darwin)
      OS_TYPE="macos"
      ;;
    Linux)
      OS_TYPE="linux"
      if grep -qiE "(microsoft|wsl)" /proc/version 2>/dev/null; then
        IS_WSL=true
      fi
      ;;
    MINGW*|MSYS*|CYGWIN*)
      OS_TYPE="windows"
      ;;
    *)
      OS_TYPE="unknown"
      print_status "warn" "未知操作系统: ${uname_s}，将尝试继续"
      ;;
  esac
}

detect_linux_distro() {
  LINUX_DISTRO=""
  if [[ "$OS_TYPE" != "linux" ]]; then
    return
  fi
  if [[ -f /etc/os-release ]]; then
    local id
    id="$(. /etc/os-release && echo "${ID:-}")"
    case "$id" in
      ubuntu|debian|linuxmint|pop) LINUX_DISTRO="debian" ;;
      fedora|rhel|centos|rocky|alma) LINUX_DISTRO="fedora" ;;
      alpine) LINUX_DISTRO="alpine" ;;
      *) LINUX_DISTRO="other" ;;
    esac
  else
    LINUX_DISTRO="other"
  fi
}

detect_shell_configs() {
  SHELL_CONFIGS=()

  if [[ "$OS_TYPE" == "windows" ]]; then
    for f in "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.profile"; do
      if [[ -f "$f" ]]; then
        SHELL_CONFIGS+=("$f")
      fi
    done
    if [[ ${#SHELL_CONFIGS[@]} -eq 0 ]]; then
      SHELL_CONFIGS=("$HOME/.bashrc")
    fi
  else
    for f in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.bash_profile" "$HOME/.profile"; do
      if [[ -f "$f" ]]; then
        SHELL_CONFIGS+=("$f")
      fi
    done
    if [[ ${#SHELL_CONFIGS[@]} -eq 0 ]]; then
      if [[ "$OS_TYPE" == "macos" ]]; then
        SHELL_CONFIGS=("$HOME/.zshrc")
      else
        SHELL_CONFIGS=("$HOME/.bashrc")
      fi
    fi
  fi
}

native_path() {
  local p="$1"
  if [[ "$OS_TYPE" == "windows" ]] && command -v cygpath >/dev/null 2>&1; then
    cygpath -m "$p"
  else
    echo "$p"
  fi
}

sed_inplace() {
  if [[ "$OS_TYPE" == "macos" ]]; then
    sed -i '' "$@"
  else
    sed -i "$@"
  fi
}

set_env_var() {
  local var_name="$1"
  local var_value="$2"

  export "$var_name=$var_value"

  for config_file in "${SHELL_CONFIGS[@]}"; do
    if [[ -f "$config_file" ]]; then
      sed_inplace "/^[[:space:]]*\(export[[:space:]]\+\)\{0,1\}${var_name}[[:space:]]*=/d" "$config_file" 2>/dev/null || true
    fi
    echo "export ${var_name}=\"${var_value}\"" >> "$config_file"
  done

  if [[ "$OS_TYPE" == "windows" ]]; then
    if command -v setx.exe >/dev/null 2>&1; then
      setx.exe "$var_name" "$var_value" >/dev/null 2>&1 || true
    elif command -v setx >/dev/null 2>&1; then
      setx "$var_name" "$var_value" >/dev/null 2>&1 || true
    fi
  fi
}

remove_env_var() {
  local var_name="$1"
  unset "$var_name" 2>/dev/null || true
  for config_file in "${SHELL_CONFIGS[@]}"; do
    if [[ -f "$config_file" ]]; then
      sed_inplace "/^[[:space:]]*\(export[[:space:]]\+\)\{0,1\}${var_name}[[:space:]]*=/d" "$config_file" 2>/dev/null || true
    fi
  done
}

################################################################################
# JSON 工具函数
################################################################################

detect_json_runtime() {
  if command -v jq >/dev/null 2>&1; then
    echo "jq"
  elif command -v node >/dev/null 2>&1; then
    echo "node"
  elif command -v python3 >/dev/null 2>&1; then
    echo "python3"
  elif command -v python >/dev/null 2>&1; then
    echo "python"
  else
    echo ""
  fi
}

merge_json() {
  local file="$1"
  local key="$2"
  local value="$3"
  local native_file
  native_file="$(native_path "$file")"

  local json_rt
  json_rt="$(detect_json_runtime)"

  if [[ -z "$json_rt" ]]; then
    print_status "error" "无法写入配置 (需要 jq / node / python3 之一)"
    return 1
  fi

  local val_tmp key_tmp
  val_tmp="$(mktemp)"
  key_tmp="$(mktemp)"
  printf '%s' "$value" > "$val_tmp"
  printf '%s' "$key" > "$key_tmp"
  local native_val_tmp native_key_tmp
  native_val_tmp="$(native_path "$val_tmp")"
  native_key_tmp="$(native_path "$key_tmp")"

  local success=false

  case "$json_rt" in
    jq)
      local out_tmp
      out_tmp="$(mktemp)"
      if jq --arg keyname "$key" --argjson val "$value" '.[$keyname] = $val' "$native_file" > "$out_tmp" 2>/dev/null; then
        mv "$out_tmp" "$native_file"
        success=true
      else
        rm -f "$out_tmp"
        print_status "warn" "配置合并失败，尝试备用方式 ..."
        if command -v node >/dev/null 2>&1; then
          json_rt="node"
        elif command -v python3 >/dev/null 2>&1; then
          json_rt="python3"
        elif command -v python >/dev/null 2>&1; then
          json_rt="python"
        fi
      fi
      ;;
  esac

  if [[ "$success" == "false" && "$json_rt" == "node" ]]; then
    if node -e "
      const fs = require('fs');
      const key = fs.readFileSync('${native_key_tmp}', 'utf8').trim();
      const data = JSON.parse(fs.readFileSync('${native_file}', 'utf8'));
      const val = JSON.parse(fs.readFileSync('${native_val_tmp}', 'utf8'));
      data[key] = val;
      fs.writeFileSync('${native_file}', JSON.stringify(data, null, 2) + '\n');
    " 2>/dev/null; then
      success=true
    else
      print_status "warn" "配置合并失败 ..."
    fi
  fi

  if [[ "$success" == "false" && ("$json_rt" == "python3" || "$json_rt" == "python") ]]; then
    if $json_rt -c "
import json, sys
try:
    with open('${native_key_tmp}', 'r', encoding='utf-8') as f:
        key = f.read().strip()
    with open('${native_file}', 'r', encoding='utf-8') as f:
        data = json.load(f)
    with open('${native_val_tmp}', 'r', encoding='utf-8') as f:
        val = json.load(f)
    data[key] = val
    with open('${native_file}', 'w', encoding='utf-8') as f:
        json.dump(data, f, indent=2, ensure_ascii=False)
        f.write('\n')
except Exception as e:
    print(f'Error: {e}', file=sys.stderr)
    sys.exit(1)
" 2>/dev/null; then
      success=true
    else
      print_status "warn" "配置合并失败 ..."
    fi
  fi

  rm -f "$val_tmp" "$key_tmp"

  if [[ "$success" == "true" ]]; then
    return 0
  fi

  print_status "error" "所有配置合并方式均失败"
  return 1
}

remove_json_key() {
  local file="$1"
  local key="$2"
  local native_file
  native_file="$(native_path "$file")"

  local key_tmp
  key_tmp="$(mktemp)"
  printf '%s' "$key" > "$key_tmp"
  local native_key_tmp
  native_key_tmp="$(native_path "$key_tmp")"

  local json_rt
  json_rt="$(detect_json_runtime)"

  local ret=1
  case "$json_rt" in
    jq)
      local out_tmp
      out_tmp="$(mktemp)"
      if jq --arg k "$key" 'del(.[$k])' "$native_file" > "$out_tmp" 2>/dev/null; then
        mv "$out_tmp" "$native_file"
        ret=0
      else
        rm -f "$out_tmp"
      fi
      ;;
    node)
      if node -e "
        const fs = require('fs');
        const key = fs.readFileSync('${native_key_tmp}', 'utf8').trim();
        const data = JSON.parse(fs.readFileSync('${native_file}', 'utf8'));
        delete data[key];
        fs.writeFileSync('${native_file}', JSON.stringify(data, null, 2) + '\n');
      " 2>/dev/null; then
        ret=0
      fi
      ;;
    python3|python)
      if $json_rt -c "
import json
with open('${native_key_tmp}', 'r') as f:
    key = f.read().strip()
with open('${native_file}', 'r') as f:
    data = json.load(f)
data.pop(key, None)
with open('${native_file}', 'w') as f:
    json.dump(data, f, indent=2, ensure_ascii=False)
    f.write('\n')
" 2>/dev/null; then
        ret=0
      fi
      ;;
  esac
  rm -f "$key_tmp"
  return $ret
}

ensure_onboarding_flag() {
  local claude_json="$HOME/.claude.json"
  if [[ ! -f "$claude_json" ]]; then
    echo '{"hasCompletedOnboarding": true}' > "$claude_json"
    print_status "info" "已创建 ~/.claude.json"
    return 0
  fi
  if merge_json "$claude_json" "hasCompletedOnboarding" "true" 2>/dev/null; then
    print_status "info" "已更新 ~/.claude.json"
    return 0
  fi
  cp "$claude_json" "${claude_json}.bak" 2>/dev/null || true
  echo '{"hasCompletedOnboarding": true}' > "$claude_json"
  print_status "warn" "已重写 ~/.claude.json (原文件备份为 .claude.json.bak)"
}

################################################################################
# 功能 1: 安装 Claude Code（原生安装优先）
################################################################################

check_claude_installed() {
  if command -v claude >/dev/null 2>&1; then
    local ver
    ver="$(claude --version 2>/dev/null || echo "未知版本")"
    echo "$ver"
    return 0
  fi
  return 1
}

detect_install_type() {
  local claude_path
  claude_path="$(command -v claude 2>/dev/null || true)"
  if [[ -z "$claude_path" ]]; then
    echo "none"
    return
  fi
  # 解析符号链接
  local real_path
  real_path="$(readlink -f "$claude_path" 2>/dev/null || echo "$claude_path")"

  if [[ "$real_path" == *"/.local/share/claude/"* ]]; then
    echo "native"
  elif [[ "$real_path" == *"/node_modules/"* || "$real_path" == *"/npm/"* || "$real_path" == *"/lib/node_modules/"* ]]; then
    echo "npm"
  elif [[ "$real_path" == *"/homebrew/"* || "$real_path" == *"/Cellar/"* ]]; then
    echo "brew"
  elif [[ "$real_path" == *"/usr/bin/"* || "$real_path" == *"/usr/local/bin/"* ]]; then
    echo "system"
  else
    echo "other"
  fi
}

uninstall_npm_claude() {
  if command -v npm >/dev/null 2>&1; then
    print_status "info" "正在卸载 npm 版本 ..."
    npm uninstall -g @anthropic-ai/claude-code 2>/dev/null || true
  fi
}

install_via_native_script() {
  print_status "info" "使用官方原生安装器 ..."
  echo ""
  curl -fsSL https://claude.ai/install.sh | bash || true
  export PATH="$HOME/.local/bin:$HOME/.claude/local/bin:$PATH"
  if command -v claude >/dev/null 2>&1; then
    return 0
  fi
  print_status "warn" "原生安装器未能成功安装 (可能是网络问题)"
  return 1
}

install_via_brew() {
  if ! command -v brew >/dev/null 2>&1; then
    return 1
  fi
  print_status "info" "使用 Homebrew 安装 ..."
  echo ""
  brew install --cask claude-code
}

install_via_apt() {
  print_status "info" "使用 apt 安装 (需要 sudo) ..."
  echo ""
  local keyring="/usr/share/keyrings/claude-code.gpg"
  if [[ ! -f "$keyring" ]]; then
    curl -fsSL https://downloads.claude.ai/claude-code/claude-code-signing-key.pub | sudo gpg --dearmor -o "$keyring" 2>/dev/null || return 1
    echo "deb [signed-by=${keyring}] https://downloads.claude.ai/claude-code/debian stable main" | sudo tee /etc/apt/sources.list.d/claude-code.list >/dev/null
  fi
  sudo apt-get update -qq && sudo apt-get install -y claude-code
}

install_via_dnf() {
  print_status "info" "使用 dnf 安装 (需要 sudo) ..."
  echo ""
  if [[ ! -f /etc/yum.repos.d/claude-code.repo ]]; then
    sudo rpm --import https://downloads.claude.ai/claude-code/claude-code-signing-key.pub 2>/dev/null || return 1
    cat << 'REPO' | sudo tee /etc/yum.repos.d/claude-code.repo >/dev/null
[claude-code]
name=Claude Code
baseurl=https://downloads.claude.ai/claude-code/rpm
enabled=1
gpgcheck=1
gpgkey=https://downloads.claude.ai/claude-code/claude-code-signing-key.pub
REPO
  fi
  sudo dnf install -y claude-code
}

install_via_apk() {
  print_status "info" "使用 apk 安装 (需要 sudo) ..."
  echo ""
  sudo apk add --no-cache libgcc libstdc++ ripgrep 2>/dev/null || true
  install_via_native_script
}

install_via_winget() {
  if ! command -v winget >/dev/null 2>&1 && ! command -v winget.exe >/dev/null 2>&1; then
    return 1
  fi
  print_status "info" "使用 WinGet 安装 ..."
  echo ""
  local wg="winget"
  command -v winget.exe >/dev/null 2>&1 && wg="winget.exe"
  $wg install Anthropic.ClaudeCode --accept-source-agreements --accept-package-agreements
}

install_via_powershell() {
  local ps=""
  if command -v powershell.exe >/dev/null 2>&1; then
    ps="powershell.exe"
  elif command -v pwsh.exe >/dev/null 2>&1; then
    ps="pwsh.exe"
  elif command -v pwsh >/dev/null 2>&1; then
    ps="pwsh"
  else
    return 1
  fi
  print_status "info" "使用 PowerShell 原生安装器 ..."
  echo ""
  $ps -NoProfile -Command "irm https://claude.ai/install.ps1 | iex"
  # 验证是否真的安装成功
  export PATH="$HOME/.local/bin:$HOME/.claude/local/bin:$PATH"
  if command -v claude >/dev/null 2>&1; then
    return 0
  fi
  print_status "warn" "PowerShell 安装器未能成功安装 (可能是网络问题)"
  return 1
}

install_via_npm() {
  if ! command -v npm >/dev/null 2>&1; then
    print_status "error" "未找到 npm，请先安装 Node.js: https://nodejs.org/"
    return 1
  fi
  print_status "info" "使用 npm 安装 ..."
  echo ""
  npm install -g @anthropic-ai/claude-code
}

install_native_auto() {
  case "$OS_TYPE" in
    macos)
      install_via_brew 2>/dev/null || install_via_native_script || install_via_npm
      ;;
    linux)
      if [[ "$IS_WSL" == "true" ]]; then
        print_status "info" "检测到 WSL 环境"
      fi
      case "$LINUX_DISTRO" in
        debian)
          install_via_apt 2>/dev/null || install_via_native_script || install_via_npm
          ;;
        fedora)
          install_via_dnf 2>/dev/null || install_via_native_script || install_via_npm
          ;;
        alpine)
          install_via_apk 2>/dev/null || install_via_npm
          ;;
        *)
          install_via_native_script || install_via_npm
          ;;
      esac
      ;;
    windows)
      print_status "info" "检测到 Windows (Git Bash) 环境"
      if ! { install_via_powershell 2>/dev/null || install_via_winget 2>/dev/null || install_via_npm; }; then
        echo ""
        print_status "error" "所有安装方式均失败"
        print_status "info" "如果无法连接 downloads.claude.ai，可能需要配置代理"
        print_status "info" "或手动下载: https://claude.ai/download"
        return 1
      fi
      ;;
    *)
      install_via_native_script || install_via_npm
      ;;
  esac
}

install_claude_code() {
  echo ""
  print_status "info" "正在安装 Claude Code ..."
  echo ""

  local ver
  if ver="$(check_claude_installed)"; then
    local install_type
    install_type="$(detect_install_type)"

    local type_label=""
    case "$install_type" in
      native) type_label="原生版本" ;;
      npm)    type_label="npm 版本" ;;
      brew)   type_label="Homebrew 版本" ;;
      system) type_label="系统包版本" ;;
      *)      type_label="未知来源" ;;
    esac

    print_status "ok" "Claude Code 已安装 ($ver)"
    print_status "info" "安装类型: ${type_label}"
    echo ""

    if [[ "$install_type" != "native" ]]; then
      if [[ "$ARG_YES" == "true" ]]; then
        print_status "info" "检测到非原生版本，自动升级到原生版本 ..."
        uninstall_npm_claude
        install_native_auto
      else
        echo -e "  ${WHITE}检测到非原生版本，建议升级:${NC}"
        echo -e "    ${CYAN}1)${NC} ${GREEN}升级到原生版本 (推荐)${NC} - 更快、自动更新"
        echo -e "    ${CYAN}2)${NC} 重新安装当前版本"
        echo -e "    ${CYAN}3)${NC} 跳过"
        echo ""
        local choice=""
        echo -en "  ${WHITE}请输入选项 (1/2/3) [默认: 1]: ${NC}" >&2
        read_tty -r choice || choice="1"

        case "$choice" in
          2)
            install_native_auto
            ;;
          3)
            print_status "info" "跳过安装"
            return 0
            ;;
          *)
            print_status "info" "正在升级到原生版本 ..."
            uninstall_npm_claude
            install_native_auto
            ;;
        esac
      fi
    else
      if [[ "$ARG_YES" == "true" ]]; then
        print_status "info" "已是原生版本，跳过"
        return 0
      fi
      local answer=""
      echo -en "  ${YELLOW}已是原生版本，是否重新安装? (y/N): ${NC}" >&2
      read_tty -r answer || answer="n"
      if [[ "$answer" != "y" && "$answer" != "Y" ]]; then
        print_status "info" "跳过安装"
        return 0
      fi
      install_native_auto
    fi
  else
    if [[ "$ARG_YES" == "true" ]]; then
      install_native_auto
    else
      echo -e "  ${WHITE}请选择安装方式:${NC}"
      echo -e "    ${CYAN}1)${NC} 原生安装 ${GREEN}(推荐)${NC} - 自动检测最佳方式"
      echo -e "    ${CYAN}2)${NC} npm 安装 - 需要 Node.js"
      echo -e "    ${CYAN}3)${NC} 跳过安装"
      echo ""
      local choice=""
      echo -en "  ${WHITE}请输入选项 (1/2/3) [默认: 1]: ${NC}" >&2
      read_tty -r choice || choice="1"

      case "$choice" in
        2) install_via_npm ;;
        3) print_status "info" "跳过安装"; return 0 ;;
        *) install_native_auto ;;
      esac
    fi
  fi

  echo ""
  export PATH="$HOME/.local/bin:$HOME/.claude/local/bin:$PATH"
  if ver="$(check_claude_installed)"; then
    print_status "ok" "Claude Code 安装成功 ($ver)"
    print_status "info" "可使用 'claude update' 更新版本"
  else
    print_status "warn" "安装已完成，但未在 PATH 中找到 claude"
    print_status "info" "请重新打开终端后再试"
  fi
}

################################################################################
# 功能 2: 配置 API
################################################################################

validate_api_key() {
  local base_url="$1"
  local api_key="$2"

  print_status "info" "正在验证 API Key ..."

  local http_code
  http_code="$(curl -s -o /dev/null -w '%{http_code}' \
    --max-time 10 \
    -H "x-api-key: ${api_key}" \
    -H "anthropic-version: 2023-06-01" \
    "${base_url}/v1/models" 2>/dev/null || echo "000")"

  if [[ "$http_code" == "200" ]]; then
    print_status "ok" "API Key 验证通过"
    return 0
  elif [[ "$http_code" == "401" ]]; then
    print_status "error" "API Key 无效 (401 Unauthorized)"
    return 1
  elif [[ "$http_code" == "000" ]]; then
    print_status "warn" "无法连接到 ${base_url} (网络错误)"
    return 1
  else
    print_status "warn" "API 返回状态码: ${http_code} (可能仍可用)"
    return 0
  fi
}

configure_api() {
  echo ""
  print_status "info" "配置 API 密钥和地址"
  echo ""

  local existing_key="${ANTHROPIC_API_KEY:-}"
  local existing_url="${ANTHROPIC_BASE_URL:-}"

  if [[ -n "$existing_key" ]]; then
    local masked="${existing_key:0:8}...${existing_key: -4}"
    print_status "info" "当前 API Key: ${masked}"
  fi
  if [[ -n "$existing_url" ]]; then
    print_status "info" "当前 BASE URL: ${existing_url}"
  fi
  echo ""

  local api_key=""

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

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

  local base_url=""

  if [[ -n "$ARG_BASE_URL" ]]; then
    base_url="$ARG_BASE_URL"
  else
    echo ""
    echo -e "  ${WHITE}请选择 API 地址:${NC}"
    echo -e "    ${CYAN}1)${NC} claude.buzz7.top ${GREEN}(推荐)${NC}"
    echo -e "    ${CYAN}2)${NC} 主站 - https://buzzai.cc"
    echo -e "    ${CYAN}3)${NC} 镜像 - https://buzzai.top"
    echo ""
    local choice=""
    echo -en "  ${WHITE}请输入选项 (1/2/3) [默认: 1]: ${NC}" >&2
    read_tty -r choice || choice="1"

    case "$choice" in
      2) base_url="https://buzzai.cc" ;;
      3) base_url="https://buzzai.top" ;;
      1|"") base_url="https://claude.buzz7.top" ;;
      *)
        print_status "error" "无效选项，已取消"
        return 1
        ;;
    esac
  fi

  echo ""
  print_status "info" "已选择: ${base_url}"
  echo ""

  if validate_api_key "$base_url" "$api_key"; then
    :
  else
    if [[ "$ARG_YES" == "true" ]]; then
      print_status "warn" "验证未通过，非交互模式下继续保存"
    else
      local answer=""
      echo -en "  ${YELLOW}验证未通过，是否仍要保存? (y/N): ${NC}" >&2
      read_tty -r answer || answer="n"
      if [[ "$answer" != "y" && "$answer" != "Y" ]]; then
        print_status "info" "已取消配置"
        return 1
      fi
    fi
  fi

  set_env_var "ANTHROPIC_API_KEY" "$api_key"
  set_env_var "ANTHROPIC_BASE_URL" "$base_url"

  ensure_onboarding_flag

  echo ""
  local masked="${api_key:0:8}...${api_key: -4}"
  print_status "ok" "API Key 已保存: ${masked}"
  print_status "ok" "BASE URL 已保存: ${base_url}"

  for config_file in "${SHELL_CONFIGS[@]}"; do
    print_status "info" "  -> ${config_file}"
  done
}

################################################################################
# 功能 3: 安装 StatusLine 余额显示插件
################################################################################

detect_statusline_runtime() {
  if command -v node >/dev/null 2>&1; then
    echo "node"
  elif command -v python3 >/dev/null 2>&1; then
    echo "python3"
  elif command -v python >/dev/null 2>&1; then
    local pyver
    pyver="$(python -c 'import sys; print(sys.version_info.major)' 2>/dev/null || echo "2")"
    if [[ "$pyver" == "3" ]]; then
      echo "python"
    elif command -v jq >/dev/null 2>&1 && command -v curl >/dev/null 2>&1; then
      echo "bash"
    else
      echo ""
    fi
  elif command -v jq >/dev/null 2>&1 && command -v curl >/dev/null 2>&1; then
    echo "bash"
  else
    echo ""
  fi
}

install_statusline_script() {
  local runtime="$1"
  local script_file=""
  local script_cmd=""

  mkdir -p "$CLAUDE_DIR"

  local native_home
  native_home="$(native_path "$HOME")"

  case "$runtime" in
    node)
      script_file="$CLAUDE_DIR/statusline.js"
      script_cmd="node ${native_home}/.claude/statusline.js"
      cat > "$script_file" << 'NODESCRIPT'
#!/usr/bin/env node
const https = require("https");
const http = require("http");
const fs = require("fs");
const os = require("os");
const path = require("path");

const ALLOWED_HOSTS = ["buzzai.cc", "buzzai.top", "claude.buzz7.top"];
const ALLOWED_SUFFIX = ".buzz7.top";
const CACHE_FILE = path.join(os.tmpdir(), "buzzai-balance-cache.json");
const CACHE_MAX_AGE = 60;

const GREEN = "\x1b[32m";
const YELLOW = "\x1b[33m";
const RED = "\x1b[31m";
const BOLD = "\x1b[1m";
const GOLD = "\x1b[38;5;220m";
const RESET = "\x1b[0m";
const LOGO = `${BOLD}${GOLD}BUZZ · AI${RESET}`;

function getConfig() {
  let apiKey = process.env.ANTHROPIC_API_KEY
    || process.env.ANTHROPIC_AUTH_TOKEN
    || "";
  let baseUrl = (process.env.ANTHROPIC_BASE_URL || "").replace(/\/+$/, "");

  if (apiKey && baseUrl) return { apiKey, baseUrl };

  const candidates = [
    path.join(os.homedir(), ".claude", "settings.json"),
    path.join(os.homedir(), ".claude", "settings.local.json"),
  ];
  for (const settingsPath of candidates) {
    if (apiKey && baseUrl) break;
    try {
      const settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
      const env = settings.env || {};
      if (!apiKey) {
        apiKey = env.ANTHROPIC_API_KEY || env.ANTHROPIC_AUTH_TOKEN || "";
      }
      if (!baseUrl) {
        baseUrl = (env.ANTHROPIC_BASE_URL || "").replace(/\/+$/, "");
      }
    } catch {}
  }

  return { apiKey, baseUrl };
}

function isAllowedHost(baseUrl) {
  try {
    const host = new URL(baseUrl).hostname;
    if (ALLOWED_HOSTS.includes(host)) return true;
    if (host.endsWith(ALLOWED_SUFFIX)) return true;
    return false;
  } catch { return false; }
}

function fetchJson(url, apiKey) {
  return new Promise((resolve) => {
    const mod = url.startsWith("https") ? https : http;
    const req = mod.get(url, {
      headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
      timeout: 3000,
    }, (res) => {
      let data = "";
      res.on("data", (c) => (data += c));
      res.on("end", () => { try { resolve(JSON.parse(data)); } catch { resolve(null); } });
    });
    req.on("error", () => resolve(null));
    req.on("timeout", () => { req.destroy(); resolve(null); });
  });
}

async function getBalance(baseUrl, apiKey) {
  try {
    const stat = fs.statSync(CACHE_FILE);
    if ((Date.now() - stat.mtimeMs) / 1000 < CACHE_MAX_AGE)
      return JSON.parse(fs.readFileSync(CACHE_FILE, "utf8"));
  } catch {}
  const [sub, usage] = await Promise.all([
    fetchJson(`${baseUrl}/v1/dashboard/billing/subscription`, apiKey),
    fetchJson(`${baseUrl}/v1/dashboard/billing/usage`, apiKey),
  ]);
  if (!sub || !usage) return null;
  const total = sub.hard_limit_usd || 0;
  const used = (usage.total_usage || 0) / 100;
  const remaining = total - used;
  const result = { total, used, remaining };
  try { fs.writeFileSync(CACHE_FILE, JSON.stringify(result)); } catch {}
  return result;
}

async function main() {
  let input = "";
  for await (const chunk of process.stdin) input += chunk;
  let info = {};
  try { info = JSON.parse(input); } catch {}
  const model = info.model?.display_name || "Unknown";

  const { apiKey, baseUrl } = getConfig();
  const showBalance = apiKey && baseUrl && isAllowedHost(baseUrl);

  if (showBalance) {
    const b = await getBalance(baseUrl, apiKey);
    if (b) {
      const color = b.remaining < 10 ? RED : b.remaining < 30 ? YELLOW : GREEN;
      console.log(`${LOGO} ${BOLD}${model}${RESET} | ${color}余额: \$${b.remaining.toFixed(2)}${RESET}`);
    } else {
      console.log(`${LOGO} ${BOLD}${model}${RESET} | 余额: 查询失败`);
    }
  } else {
    console.log(`${BOLD}${model}${RESET}`);
  }
}
main();
NODESCRIPT
      ;;

    python3|python)
      script_file="$CLAUDE_DIR/statusline.py"
      script_cmd="${runtime} ${native_home}/.claude/statusline.py"
      cat > "$script_file" << 'PYTHONSCRIPT'
#!/usr/bin/env python3
import sys, os, json, time, tempfile, urllib.request, ssl
from pathlib import Path

ALLOWED_HOSTS = ["buzzai.cc", "buzzai.top", "claude.buzz7.top"]
ALLOWED_SUFFIX = ".buzz7.top"
CACHE_FILE = os.path.join(tempfile.gettempdir(), "buzzai-balance-cache.json")
CACHE_MAX_AGE = 60

GREEN = "\x1b[32m"
YELLOW = "\x1b[33m"
RED = "\x1b[31m"
BOLD = "\x1b[1m"
GOLD = "\x1b[38;5;220m"
RESET = "\x1b[0m"
LOGO = f"{BOLD}{GOLD}BUZZ · AI{RESET}"


def get_config():
    api_key = os.environ.get("ANTHROPIC_API_KEY") or os.environ.get("ANTHROPIC_AUTH_TOKEN") or ""
    base_url = os.environ.get("ANTHROPIC_BASE_URL", "").rstrip("/")

    if api_key and base_url:
        return api_key, base_url

    home = Path.home()
    candidates = [
        home / ".claude" / "settings.json",
        home / ".claude" / "settings.local.json",
    ]
    for settings_path in candidates:
        if api_key and base_url:
            break
        try:
            with open(settings_path, "r", encoding="utf-8") as f:
                settings = json.load(f)
            env = settings.get("env", {})
            if not api_key:
                api_key = env.get("ANTHROPIC_API_KEY") or env.get("ANTHROPIC_AUTH_TOKEN") or ""
            if not base_url:
                base_url = env.get("ANTHROPIC_BASE_URL", "").rstrip("/")
        except Exception:
            pass

    return api_key, base_url


def is_allowed_host(base_url):
    try:
        from urllib.parse import urlparse
        host = urlparse(base_url).hostname or ""
        if host in ALLOWED_HOSTS:
            return True
        if host.endswith(ALLOWED_SUFFIX):
            return True
    except Exception:
        pass
    return False


def fetch_json(url, api_key):
    try:
        req = urllib.request.Request(url, headers={
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        })
        ctx = ssl.create_default_context()
        with urllib.request.urlopen(req, timeout=3, context=ctx) as resp:
            return json.loads(resp.read().decode())
    except Exception:
        return None


def get_balance(base_url, api_key):
    try:
        mtime = os.path.getmtime(CACHE_FILE)
        if time.time() - mtime < CACHE_MAX_AGE:
            with open(CACHE_FILE, "r") as f:
                return json.load(f)
    except Exception:
        pass
    sub = fetch_json(f"{base_url}/v1/dashboard/billing/subscription", api_key)
    usage = fetch_json(f"{base_url}/v1/dashboard/billing/usage", api_key)
    if not sub or not usage:
        return None
    total = sub.get("hard_limit_usd", 0)
    used = usage.get("total_usage", 0) / 100
    remaining = total - used
    result = {"total": total, "used": used, "remaining": remaining}
    try:
        with open(CACHE_FILE, "w") as f:
            json.dump(result, f)
    except Exception:
        pass
    return result


def main():
    raw = sys.stdin.read()
    try:
        info = json.loads(raw)
    except Exception:
        info = {}
    model = (info.get("model") or {}).get("display_name", "Unknown")

    api_key, base_url = get_config()
    show_balance = bool(api_key and base_url and is_allowed_host(base_url))

    if show_balance:
        b = get_balance(base_url, api_key)
        if b:
            r = b["remaining"]
            color = RED if r < 10 else YELLOW if r < 30 else GREEN
            print(f"{LOGO} {BOLD}{model}{RESET} | {color}余额: ${r:.2f}{RESET}")
        else:
            print(f"{LOGO} {BOLD}{model}{RESET} | 余额: 查询失败")
    else:
        print(f"{BOLD}{model}{RESET}")


if __name__ == "__main__":
    main()
PYTHONSCRIPT
      ;;

    bash)
      script_file="$CLAUDE_DIR/statusline.sh"
      script_cmd="${native_home}/.claude/statusline.sh"
      cat > "$script_file" << 'BASHSCRIPT'
#!/usr/bin/env bash
INPUT="$(cat)"

MODEL="$(printf '%s' "$INPUT" | jq -r '.model.display_name // "Unknown"' 2>/dev/null || echo "Unknown")"

RESET=$'\x1b[0m'
BOLD=$'\x1b[1m'
GOLD=$'\x1b[38;5;220m'
GREEN=$'\x1b[32m'
YELLOW=$'\x1b[33m'
RED=$'\x1b[31m'
LOGO="${BOLD}${GOLD}BUZZ · AI${RESET}"

API_KEY="${ANTHROPIC_API_KEY:-${ANTHROPIC_AUTH_TOKEN:-}}"
BASE_URL="$(printf '%s' "${ANTHROPIC_BASE_URL:-}" | sed 's|/\+$||')"

if { [ -z "$API_KEY" ] || [ -z "$BASE_URL" ]; } && command -v jq >/dev/null 2>&1; then
  for _sf in "$HOME/.claude/settings.json" "$HOME/.claude/settings.local.json"; do
    [ -f "$_sf" ] || continue
    [ -n "$API_KEY" ] && [ -n "$BASE_URL" ] && break
    if [ -z "$API_KEY" ]; then
      API_KEY="$(jq -r '.env.ANTHROPIC_API_KEY // .env.ANTHROPIC_AUTH_TOKEN // empty' "$_sf" 2>/dev/null || true)"
    fi
    if [ -z "$BASE_URL" ]; then
      BASE_URL="$(jq -r '.env.ANTHROPIC_BASE_URL // empty' "$_sf" 2>/dev/null | sed 's|/\+$||' || true)"
    fi
  done
fi

is_allowed() {
  local host
  host="$(printf '%s' "$1" | sed -E 's|^https?://||;s|[/:].*||')"
  case "$host" in
    buzzai.cc|buzzai.top|claude.buzz7.top) return 0 ;;
    *.buzz7.top) return 0 ;;
    *) return 1 ;;
  esac
}

SHOW=0
[ -n "$API_KEY" ] && [ -n "$BASE_URL" ] && is_allowed "$BASE_URL" && SHOW=1

if [ "$SHOW" -eq 1 ]; then
  CACHE="/tmp/buzzai-balance-cache.json"
  NEED_REFRESH=1
  if [ -f "$CACHE" ]; then
    MTIME="$(stat -f %m "$CACHE" 2>/dev/null || stat -c %Y "$CACHE" 2>/dev/null || echo 0)"
    AGE=$(( $(date +%s) - MTIME ))
    [ "$AGE" -lt 60 ] && NEED_REFRESH=0
  fi
  if [ "$NEED_REFRESH" -eq 1 ]; then
    SUB="$(curl -sf --max-time 3 -H "Authorization: Bearer $API_KEY" "$BASE_URL/v1/dashboard/billing/subscription" 2>/dev/null || echo "")"
    USE="$(curl -sf --max-time 3 -H "Authorization: Bearer $API_KEY" "$BASE_URL/v1/dashboard/billing/usage" 2>/dev/null || echo "{}")"
    TOTAL="$(printf '%s' "$SUB" | jq -r '.hard_limit_usd // 0')"
    USED_RAW="$(printf '%s' "$USE" | jq -r '.total_usage // 0')"
    REMAINING="$(awk "BEGIN { printf \"%.2f\", ${TOTAL} - ${USED_RAW}/100 }")"
    printf '{"remaining":%s}' "$REMAINING" > "$CACHE" 2>/dev/null || true
  fi
  REMAINING="$(jq -r '.remaining // 0' "$CACHE" 2>/dev/null || echo "0")"
  COLOR="$GREEN"
  awk "BEGIN { exit (${REMAINING}+0 < 10) ? 0 : 1 }" && COLOR="$RED"
  awk "BEGIN { exit (${REMAINING}+0 >= 10 && ${REMAINING}+0 < 30) ? 0 : 1 }" && COLOR="$YELLOW"
  if [ "$REMAINING" = "0" ] && [ ! -f "$CACHE" ]; then
    echo "${LOGO} ${BOLD}${MODEL}${RESET} | 余额: 查询失败"
  else
    echo "${LOGO} ${BOLD}${MODEL}${RESET} | ${COLOR}余额: \$${REMAINING}${RESET}"
  fi
else
  echo "${BOLD}${MODEL}${RESET}"
fi
BASHSCRIPT
      ;;
  esac

  chmod +x "$script_file"
  echo "$script_cmd"
}

configure_statusline_settings() {
  local script_cmd="$1"

  mkdir -p "$CLAUDE_DIR"

  if [[ ! -f "$SETTINGS_FILE" ]]; then
    echo '{}' > "$SETTINGS_FILE"
  fi

  local value="{\"type\": \"command\", \"command\": \"${script_cmd}\"}"

  if merge_json "$SETTINGS_FILE" "statusLine" "$value" 2>/dev/null; then
    return 0
  fi

  print_status "warn" "自动配置失败，尝试备用方案 ..."
  local native_file
  native_file="$(native_path "$SETTINGS_FILE")"

  if command -v node >/dev/null 2>&1; then
    local tmp_cmd
    tmp_cmd="$(mktemp)"
    printf '%s' "$script_cmd" > "$tmp_cmd"
    local native_tmp_cmd
    native_tmp_cmd="$(native_path "$tmp_cmd")"

    if node -e "
      const fs = require('fs');
      const cmd = fs.readFileSync('${native_tmp_cmd}', 'utf8').trim();
      let data = {};
      try { data = JSON.parse(fs.readFileSync('${native_file}', 'utf8')); } catch {}
      data.statusLine = { type: 'command', command: cmd };
      fs.writeFileSync('${native_file}', JSON.stringify(data, null, 2) + '\n');
    " 2>/dev/null; then
      rm -f "$tmp_cmd"
      return 0
    fi
    rm -f "$tmp_cmd"
  fi

  print_status "error" "自动写入 settings.json 失败"
  echo ""
  print_status "info" "请手动编辑 ${SETTINGS_FILE}，添加以下内容:"
  echo ""
  echo -e "    ${WHITE}\"statusLine\": {${NC}"
  echo -e "    ${WHITE}  \"type\": \"command\",${NC}"
  echo -e "    ${WHITE}  \"command\": \"${script_cmd}\"${NC}"
  echo -e "    ${WHITE}}${NC}"
  echo ""
  return 1
}

detect_existing_statusline() {
  local found=""
  if [[ -f "$CLAUDE_DIR/statusline.js" ]]; then
    found="node"
  elif [[ -f "$CLAUDE_DIR/statusline.py" ]]; then
    found="python"
  elif [[ -f "$CLAUDE_DIR/statusline.sh" ]]; then
    found="bash"
  fi
  echo "$found"
}

is_old_statusline_version() {
  local existing_rt="$1"
  case "$existing_rt" in
    node)
      grep -q "getConfig" "$CLAUDE_DIR/statusline.js" 2>/dev/null && return 1
      return 0
      ;;
    python)
      grep -q "get_config" "$CLAUDE_DIR/statusline.py" 2>/dev/null && return 1
      return 0
      ;;
    bash)
      grep -q "settings.json" "$CLAUDE_DIR/statusline.sh" 2>/dev/null && return 1
      return 0
      ;;
  esac
  return 0
}

cleanup_old_statusline() {
  local new_runtime="$1"
  local old_runtime="$2"

  if [[ -z "$old_runtime" || "$new_runtime" == "$old_runtime" ]]; then
    return
  fi

  local old_file=""
  case "$old_runtime" in
    node)   old_file="$CLAUDE_DIR/statusline.js" ;;
    python) old_file="$CLAUDE_DIR/statusline.py" ;;
    bash)   old_file="$CLAUDE_DIR/statusline.sh" ;;
  esac

  if [[ -n "$old_file" && -f "$old_file" ]]; then
    rm -f "$old_file"
    print_status "info" "已清理旧版脚本: $(basename "$old_file")"
  fi
}

install_statusline() {
  echo ""
  print_status "info" "安装余额显示插件 (StatusLine)"
  echo ""

  mkdir -p "$CLAUDE_DIR"

  local existing_rt
  existing_rt="$(detect_existing_statusline)"
  local is_upgrade=false

  if [[ -n "$existing_rt" ]]; then
    if is_old_statusline_version "$existing_rt"; then
      is_upgrade=true
      print_status "warn" "检测到旧版插件 (${existing_rt})，将自动升级"
    else
      print_status "info" "检测到已安装的插件 (${existing_rt})，将重新安装"
    fi
  fi

  local runtime
  runtime="$(detect_statusline_runtime)"

  if [[ -z "$runtime" ]]; then
    print_status "error" "未找到可用的运行环境 (需要 node/python3/bash+jq+curl 之一)"
    return 1
  fi

  print_status "info" "[1/3] 检测到运行环境: ${runtime}"

  cleanup_old_statusline "$runtime" "$existing_rt"

  local script_cmd
  script_cmd="$(install_statusline_script "$runtime")"
  print_status "ok" "[2/3] 脚本已创建"

  if configure_statusline_settings "$script_cmd"; then
    print_status "ok" "[3/3] 配置已写入: ${SETTINGS_FILE}"
  else
    print_status "warn" "[3/3] 自动配置失败，请按上述提示手动配置"
    return 0
  fi

  rm -f "/tmp/buzzai-balance-cache.json" 2>/dev/null || true

  echo ""
  if [[ "$is_upgrade" == "true" ]]; then
    print_status "ok" "插件已从旧版升级到新版，重启 Claude Code 即可生效"
    print_status "info" "新版改进: 支持从 settings.json 读取 API 配置，无需设置环境变量"
  else
    print_status "ok" "余额插件安装完成，重启 Claude Code 即可生效"
  fi
}

################################################################################
# 功能 4: 卸载
################################################################################

uninstall() {
  echo ""
  print_status "info" "卸载配置和插件"
  echo ""

  if [[ "$ARG_YES" != "true" ]]; then
    local confirm=""
    echo -en "  ${YELLOW}此操作将移除余额插件和 API 配置，是否继续? (y/N): ${NC}" >&2
    read_tty -r confirm || confirm="n"
    if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
      print_status "info" "已取消"
      return 0
    fi
  fi

  # 删除 statusline 脚本
  local removed=false
  for f in "$CLAUDE_DIR/statusline.js" "$CLAUDE_DIR/statusline.py" "$CLAUDE_DIR/statusline.sh"; do
    if [[ -f "$f" ]]; then
      rm -f "$f"
      print_status "ok" "已删除: $(basename "$f")"
      removed=true
    fi
  done

  # 从 settings.json 移除 statusLine
  if [[ -f "$SETTINGS_FILE" ]] && grep -q "statusLine" "$SETTINGS_FILE" 2>/dev/null; then
    if remove_json_key "$SETTINGS_FILE" "statusLine"; then
      print_status "ok" "已从 settings.json 移除 statusLine 配置"
    fi
  fi

  # 移除环境变量
  remove_env_var "ANTHROPIC_API_KEY"
  remove_env_var "ANTHROPIC_BASE_URL"
  print_status "ok" "已从 shell 配置文件移除 ANTHROPIC_API_KEY 和 ANTHROPIC_BASE_URL"

  # 清理缓存
  rm -f "/tmp/buzzai-balance-cache.json" 2>/dev/null || true

  echo ""
  if [[ "$removed" == "true" ]]; then
    print_status "ok" "卸载完成，重启终端生效"
  else
    print_status "info" "未发现已安装的插件，已清理环境变量"
  fi
  print_status "info" "注意: Claude Code 本身未被卸载 (如需卸载请使用 npm uninstall -g @anthropic-ai/claude-code)"
}

################################################################################
# 功能 5: 端点测速
################################################################################

test_endpoint_latency() {
  local url="$1"
  local label="$2"
  local api_key="${ANTHROPIC_API_KEY:-}"

  local curl_format='%{time_namelookup} %{time_connect} %{time_appconnect} %{time_starttransfer} %{time_total} %{http_code}'

  local raw
  if [[ -n "$api_key" ]]; then
    raw="$(curl -s -o /dev/null -w "$curl_format" \
      --max-time 10 \
      -H "x-api-key: ${api_key}" \
      -H "anthropic-version: 2023-06-01" \
      "${url}/v1/models" 2>/dev/null)" || raw="0 0 0 0 99 0"
  else
    raw="$(curl -s -o /dev/null -w "$curl_format" \
      --max-time 10 \
      "${url}/v1/models" 2>/dev/null)" || raw="0 0 0 0 99 0"
  fi

  local dns tcp tls ttfb total code
  read -r dns tcp tls ttfb total code <<< "$raw"

  local dns_ms tcp_ms tls_ms ttfb_ms total_ms
  dns_ms="$(awk "BEGIN { printf \"%.0f\", ${dns:-0} * 1000 }")"
  tcp_ms="$(awk "BEGIN { printf \"%.0f\", ${tcp:-0} * 1000 }")"
  tls_ms="$(awk "BEGIN { printf \"%.0f\", ${tls:-0} * 1000 }")"
  ttfb_ms="$(awk "BEGIN { printf \"%.0f\", ${ttfb:-0} * 1000 }")"
  total_ms="$(awk "BEGIN { printf \"%.0f\", ${total:-0} * 1000 }")"

  local color="$GREEN"
  if [[ "$total_ms" -gt 3000 ]] || [[ "${code:-0}" == "0" ]]; then
    color="$RED"
  elif [[ "$total_ms" -gt 1000 ]]; then
    color="$YELLOW"
  fi

  if [[ "${code:-0}" == "0" ]]; then
    printf "    %-24s ${RED}连接失败${NC}\n" "$label" >&2
    echo "99999"
  else
    printf "    %-24s ${color}%4sms${NC}  ${GRAY}DNS:%sms  TCP:%sms  TLS:%sms  首字节:%sms${NC}\n" \
      "$label" "$total_ms" "$dns_ms" "$tcp_ms" "$tls_ms" "$ttfb_ms" >&2
    echo "$total_ms"
  fi
}

test_endpoint_ttft() {
  local url="$1"
  local label="$2"
  local api_key="${ANTHROPIC_API_KEY:-}"
  local test_model="claude-haiku-4-5-20251001"

  if [[ -z "$api_key" ]]; then
    printf "    %-24s ${RED}需要 API Key${NC}\n" "$label" >&2
    echo "99999"
    return
  fi

  local body="{\"model\":\"${test_model}\",\"max_tokens\":1,\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}]}"

  local curl_format='%{time_starttransfer} %{time_total} %{http_code}'
  local raw
  raw="$(curl -s -o /dev/null -w "$curl_format" \
    --max-time 30 \
    -X POST \
    -H "x-api-key: ${api_key}" \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -d "$body" \
    "${url}/v1/messages" 2>/dev/null)" || raw="0 0 0"

  local ttfb total code
  read -r ttfb total code <<< "$raw"

  local ttfb_ms total_ms
  ttfb_ms="$(awk "BEGIN { printf \"%.0f\", ${ttfb:-0} * 1000 }")"
  total_ms="$(awk "BEGIN { printf \"%.0f\", ${total:-0} * 1000 }")"

  local color="$GREEN"
  if [[ "$total_ms" -gt 10000 ]] || [[ "${code:-0}" == "0" ]]; then
    color="$RED"
  elif [[ "$total_ms" -gt 5000 ]]; then
    color="$YELLOW"
  fi

  if [[ "${code:-0}" == "0" ]]; then
    printf "    %-24s ${RED}连接失败${NC}\n" "$label" >&2
    echo "99999"
  elif [[ "$code" != "200" ]]; then
    printf "    %-24s ${YELLOW}HTTP ${code}${NC}  ${GRAY}(API Key 无效或额度不足)${NC}\n" "$label" >&2
    echo "99999"
  else
    printf "    %-24s ${color}%4sms${NC}  ${GRAY}首字节:%sms  总耗时:%sms${NC}\n" \
      "$label" "$total_ms" "$ttfb_ms" "$total_ms" >&2
    echo "$total_ms"
  fi
}

speedtest() {
  echo ""
  print_status "info" "端点测速"
  echo ""

  local endpoints=(
    "https://claude.buzz7.top|claude.buzz7.top"
    "https://buzzai.cc|buzzai.cc (主站)"
    "https://buzzai.top|buzzai.top (镜像)"
  )

  # ── 第一步: 快速测速（自动执行，不消耗额度）──
  if [[ -n "${ANTHROPIC_API_KEY:-}" ]]; then
    print_status "info" "网络延迟测试 (不调用模型，不消耗额度)"
  else
    print_status "info" "网络延迟测试 (匿名请求)"
  fi
  echo ""
  echo -e "  ${WHITE}正在测速 ...${NC}" >&2
  echo "" >&2

  local best_name=""
  local best_ms=99999
  local best_url=""

  for entry in "${endpoints[@]}"; do
    local url="${entry%%|*}"
    local label="${entry##*|}"
    local ms
    ms="$(test_endpoint_latency "$url" "$label")"
    if [[ "$ms" -lt "$best_ms" && "$ms" -gt 0 ]]; then
      best_ms="$ms"
      best_name="$label"
      best_url="$url"
    fi
  done

  echo "" >&2

  if [[ -z "$best_name" || "$best_ms" -ge 99000 ]]; then
    print_status "warn" "所有端点均连接失败，请检查网络"
    return 1
  fi

  print_status "ok" "网络最快: ${best_name} (${best_ms}ms)"

  # ── 第二步: 询问是否深度测速 ──
  if [[ -n "${ANTHROPIC_API_KEY:-}" && "$ARG_YES" != "true" ]]; then
    echo ""
    echo -e "  ${GRAY}────────────────────────────────────────────────${NC}"
    echo ""
    echo -e "  ${WHITE}以上为网络延迟，不代表实际 API 调用速度。${NC}"
    echo -e "  ${WHITE}深度测速将调用 ${BOLD}claude-haiku-4-5-20251001${NC}${WHITE} 模型，${NC}"
    echo -e "  ${WHITE}每个端点消耗约 ${YELLOW}2000 token${NC}${WHITE}，费用从余额中扣除。${NC}"
    echo ""
    local deep=""
    echo -en "  ${YELLOW}是否进行深度测速? (y/N): ${NC}" >&2
    read_tty -r deep || deep="n"

    if [[ "$deep" == "y" || "$deep" == "Y" ]]; then
      echo ""
      print_status "info" "深度测速: 调用 claude-haiku-4-5-20251001，每个端点约需 3-15 秒"
      echo "" >&2

      local deep_best_name=""
      local deep_best_ms=99999
      local deep_best_url=""

      for entry in "${endpoints[@]}"; do
        local url="${entry%%|*}"
        local label="${entry##*|}"
        local ms
        ms="$(test_endpoint_ttft "$url" "$label")"
        if [[ "$ms" -lt "$deep_best_ms" && "$ms" -gt 0 ]]; then
          deep_best_ms="$ms"
          deep_best_name="$label"
          deep_best_url="$url"
        fi
      done

      echo "" >&2

      if [[ -n "$deep_best_name" && "$deep_best_ms" -lt 99000 ]]; then
        print_status "ok" "API 最快: ${deep_best_name} (首 token ${deep_best_ms}ms)"
        best_name="$deep_best_name"
        best_ms="$deep_best_ms"
        best_url="$deep_best_url"
      else
        print_status "warn" "深度测速失败，以网络延迟结果为准"
      fi
    fi
  fi

  # ── 第三步: 提示切换端点 ──
  local current_url="${ANTHROPIC_BASE_URL:-}"
  if [[ -n "$current_url" && "$current_url" != "$best_url" ]]; then
    echo ""
    if [[ "$ARG_YES" == "true" ]]; then
      return 0
    fi
    local switch=""
    echo -en "  ${YELLOW}当前端点不是最快的，是否切换到 ${best_name}? (y/N): ${NC}" >&2
    read_tty -r switch || switch="n"
    if [[ "$switch" == "y" || "$switch" == "Y" ]]; then
      set_env_var "ANTHROPIC_BASE_URL" "$best_url"
      print_status "ok" "已切换到: ${best_url}"
    fi
  elif [[ -z "$current_url" ]]; then
    echo ""
    if [[ "$ARG_YES" == "true" ]]; then
      return 0
    fi
    local setit=""
    echo -en "  ${YELLOW}尚未配置端点，是否设置为最快的 ${best_name}? (y/N): ${NC}" >&2
    read_tty -r setit || setit="n"
    if [[ "$setit" == "y" || "$setit" == "Y" ]]; then
      set_env_var "ANTHROPIC_BASE_URL" "$best_url"
      print_status "ok" "已设置: ${best_url}"
    fi
  else
    echo ""
    print_status "info" "当前端点已是最快的"
  fi
}

################################################################################
# 状态检测与菜单
################################################################################

show_status_summary() {
  echo -e "  ${WHITE}当前环境:${NC}"
  echo ""

  local os_label="$OS_TYPE"
  if [[ "$IS_WSL" == "true" ]]; then
    os_label="Linux (WSL)"
  fi
  if [[ -n "$LINUX_DISTRO" && "$LINUX_DISTRO" != "other" ]]; then
    os_label="${os_label} (${LINUX_DISTRO})"
  fi
  echo -e "    系统         ${CYAN}${os_label}${NC}"

  local claude_ver
  if claude_ver="$(check_claude_installed 2>/dev/null)"; then
    local itype
    itype="$(detect_install_type)"
    local itype_label=""
    case "$itype" in
      native) itype_label="原生" ;;
      npm)    itype_label="npm" ;;
      brew)   itype_label="Homebrew" ;;
      system) itype_label="系统包" ;;
      *)      itype_label="其他" ;;
    esac
    echo -e "    Claude Code  ${GREEN}已安装${NC} ${GRAY}${claude_ver} (${itype_label})${NC}"
  else
    echo -e "    Claude Code  ${RED}未安装${NC}"
  fi

  if [[ -n "${ANTHROPIC_API_KEY:-}" ]]; then
    local masked="${ANTHROPIC_API_KEY:0:8}...${ANTHROPIC_API_KEY: -4}"
    echo -e "    API 密钥     ${GREEN}已配置${NC} ${GRAY}${masked}${NC}"
  else
    echo -e "    API 密钥     ${RED}未配置${NC}"
  fi

  if [[ -f "$SETTINGS_FILE" ]] && grep -q "statusLine" "$SETTINGS_FILE" 2>/dev/null; then
    echo -e "    余额插件     ${GREEN}已安装${NC}"
  else
    echo -e "    余额插件     ${RED}未安装${NC}"
  fi

  echo ""
}

show_menu() {
  print_banner
  show_status_summary

  echo -e "  ${GRAY}────────────────────────────────────────────────${NC}"
  echo ""
  echo -e "  ${WHITE}请选择操作:${NC}"
  echo ""
  echo -e "    ${CYAN}1)${NC} 安装 Claude Code"
  echo -e "    ${CYAN}2)${NC} 配置 API 密钥"
  echo -e "    ${CYAN}3)${NC} 安装余额显示插件"
  echo ""
  echo -e "    ${CYAN}4)${NC} ${GREEN}一键全部安装 (推荐)${NC}"
  echo -e "    ${CYAN}5)${NC} 端点测速"
  echo ""
  echo -e "    ${CYAN}6)${NC} ${GRAY}卸载配置和插件${NC}"
  echo -e "    ${CYAN}0)${NC} ${GRAY}退出${NC}"
  echo ""
}

run_all() {
  install_claude_code
  echo ""
  echo -e "  ${BOLD}--------------------------------------${NC}"
  configure_api || print_status "warn" "API 配置已跳过，可稍后单独配置"
  echo ""
  echo -e "  ${BOLD}--------------------------------------${NC}"
  install_statusline
}

################################################################################
# 入口
################################################################################

main() {
  detect_os
  detect_linux_distro
  detect_shell_configs

  # 从 shell 配置文件中提取已有的 API 配置（不 source 整个文件，避免副作用）
  for config_file in "${SHELL_CONFIGS[@]}"; do
    if [[ -f "$config_file" ]]; then
      if [[ -z "${ANTHROPIC_API_KEY:-}" ]]; then
        local _key
        _key="$(grep -E '^export ANTHROPIC_API_KEY=' "$config_file" 2>/dev/null | tail -1 | sed 's/^export ANTHROPIC_API_KEY=//' | tr -d '"' | tr -d "'")" || true
        [[ -n "$_key" ]] && export ANTHROPIC_API_KEY="$_key"
      fi
      if [[ -z "${ANTHROPIC_BASE_URL:-}" ]]; then
        local _url
        _url="$(grep -E '^export ANTHROPIC_BASE_URL=' "$config_file" 2>/dev/null | tail -1 | sed 's/^export ANTHROPIC_BASE_URL=//' | tr -d '"' | tr -d "'")" || true
        [[ -n "$_url" ]] && export ANTHROPIC_BASE_URL="$_url"
      fi
    fi
  done

  if [[ "$OS_TYPE" == "windows" ]]; then
    if [[ -z "${ANTHROPIC_API_KEY:-}" ]] && command -v cmd.exe >/dev/null 2>&1; then
      local win_key
      win_key="$(cmd.exe /C "echo %ANTHROPIC_API_KEY%" 2>/dev/null | tr -d '\r')" || true
      if [[ -n "$win_key" && "$win_key" != "%ANTHROPIC_API_KEY%" ]]; then
        export ANTHROPIC_API_KEY="$win_key"
      fi
      local win_url
      win_url="$(cmd.exe /C "echo %ANTHROPIC_BASE_URL%" 2>/dev/null | tr -d '\r')" || true
      if [[ -n "$win_url" && "$win_url" != "%ANTHROPIC_BASE_URL%" ]]; then
        export ANTHROPIC_BASE_URL="$win_url"
      fi
    fi
  fi

  # 非交互模式或指定动作时直接执行
  if [[ -n "$ARG_ACTION" ]]; then
    print_banner
    case "$ARG_ACTION" in
      install) install_claude_code ;;
      configure) configure_api ;;
      statusline) install_statusline ;;
      uninstall) uninstall ;;
      speedtest) speedtest ;;
    esac
    return 0
  fi

  if [[ "$ARG_YES" == "true" ]]; then
    print_banner
    run_all
    return 0
  fi

  # 交互式菜单
  while true; do
    show_menu

    local choice=""
    echo -en "  ${WHITE}请输入数字: ${NC}" >&2
    read_tty -r choice || break

    case "$choice" in
      1) install_claude_code ;;
      2) configure_api ;;
      3) install_statusline ;;
      4) run_all ;;
      5) speedtest ;;
      6) uninstall ;;
      0)
        echo ""
        print_status "ok" "再见!"
        exit 0
        ;;
      *)
        print_status "warn" "无效选项，请重试"
        ;;
    esac

    echo ""
    echo -en "  按 Enter 继续 ..." >&2
    read_tty -r || break
  done
}

# 解析参数并应用设置
parse_args "$@"
apply_color_settings
main
