#!/usr/bin/env bash
# 凯洛 Kailoo · Claude Code 一键接入（macOS / Linux）
#
# 裸机可用：没装 Node / Python 也会试着自动装（mac 用 Homebrew，Linux 用系统包管理器）。
# 做的事：
#   1. 检测 Node.js（>= 18），没有就自动装（装不上则引导 nodejs.org）
#   2. 安装 / 检测 Claude Code（npm -g @anthropic-ai/claude-code）
#   3. 写入凯洛后端环境变量（持久写 shell profile + 当前会话）
#   4. 实跑一次最小 /v1/messages 验证，确认密钥和链路通
#   5.（可选）配联网搜索 MCP（需 Python 3.10+，没有也会试着自动装）
#
# 用法（下载后在终端运行；需要交互粘贴密钥，不要用管道 curl | bash）：
#   bash kailoo-claude-code-setup.sh
#
# 鉴权方式与凯洛 /docs 文档一致：x-api-key + anthropic-version: 2023-06-01。

# 不用 -e：改为对每个关键步骤显式判错并给中文提示，避免 read EOF / 命令替换非零状态把脚本闷掉
set -uo pipefail

# ---- 配置（与 sites/domestic-site/src/app/docs/page.tsx 对齐）----
BASE="https://kailoo.ai"
DEFAULT_MODEL="claude-opus-4-8[1m]"            # 重度 agent 首选
HAIKU_MODEL="claude-haiku-4-5-20251001"   # Claude Code 后台小模型（标题/索引等），必须是 kailoo 实际服务的 haiku，否则后台任务报错
MIN_NODE=18

# ---- 颜色 ----
C_CYAN=$'\033[36m'; C_GREEN=$'\033[32m'; C_YELLOW=$'\033[33m'
C_RED=$'\033[31m'; C_MAG=$'\033[35m'; C_GRAY=$'\033[90m'; C_RST=$'\033[0m'
step() { printf '\n%s[%s] %s%s\n' "$C_CYAN" "$1" "$2" "$C_RST"; }
ok()   { printf '  %sOK%s  %s\n' "$C_GREEN" "$C_RST" "$1"; }
warn() { printf '  %s!%s   %s\n'  "$C_YELLOW" "$C_RST" "$1"; }
err()  { printf '  %sX%s   %s\n'  "$C_RED" "$C_RST" "$1"; }

os_kind() {
    case "$(uname -s)" in
        Darwin) echo macos ;;
        Linux)  echo linux ;;
        *)      echo other ;;
    esac
}

# node 主版本号；未安装输出空串
node_major() {
    command -v node >/dev/null 2>&1 || { echo ""; return; }
    node --version 2>/dev/null | sed 's/^v//' | cut -d. -f1
}

# 尽力自动安装 node（成功返回 0）
try_install_node() {
    local os; os="$(os_kind)"
    if [ "$os" = "macos" ]; then
        if command -v brew >/dev/null 2>&1; then
            echo "      正在用 Homebrew 安装 Node..."
            brew install node && return 0
        fi
        warn "未检测到 Homebrew，无法自动装 Node。"
        return 1
    elif [ "$os" = "linux" ]; then
        if command -v apt-get >/dev/null 2>&1; then
            echo "      正在用 apt 安装 Node（可能需要输入 sudo 密码）..."
            sudo apt-get update -y && sudo apt-get install -y nodejs npm && return 0
        elif command -v dnf >/dev/null 2>&1; then
            echo "      正在用 dnf 安装 Node（可能需要输入 sudo 密码）..."
            sudo dnf install -y nodejs npm && return 0
        elif command -v pacman >/dev/null 2>&1; then
            echo "      正在用 pacman 安装 Node（可能需要输入 sudo 密码）..."
            sudo pacman -Sy --noconfirm nodejs npm && return 0
        fi
        warn "未识别的包管理器，无法自动装 Node。"
        return 1
    fi
    return 1
}

# 尽力自动安装 python3（成功返回 0）
try_install_python() {
    local os; os="$(os_kind)"
    if [ "$os" = "macos" ]; then
        command -v brew >/dev/null 2>&1 && { echo "      正在用 Homebrew 安装 Python..."; brew install python && return 0; }
        return 1
    elif [ "$os" = "linux" ]; then
        if command -v apt-get >/dev/null 2>&1; then
            sudo apt-get install -y python3 python3-pip && return 0
        elif command -v dnf >/dev/null 2>&1; then
            sudo dnf install -y python3 python3-pip && return 0
        elif command -v pacman >/dev/null 2>&1; then
            sudo pacman -Sy --noconfirm python python-pip && return 0
        fi
    fi
    return 1
}

printf '%s======================================================%s\n' "$C_MAG" "$C_RST"
printf '%s  凯洛 Kailoo · Claude Code 一键接入 (macOS / Linux)%s\n' "$C_MAG" "$C_RST"
printf '%s======================================================%s\n' "$C_MAG" "$C_RST"

# ---- 1. 检测 / 自动安装 Node.js ----
step 1 "检测 Node.js"
NODE_MAJOR="$(node_major)"
if [ -z "$NODE_MAJOR" ] || [ "$NODE_MAJOR" -lt "$MIN_NODE" ]; then
    if [ -z "$NODE_MAJOR" ]; then warn "未检测到 Node.js。"; else warn "Node.js 版本过低（v$NODE_MAJOR，需 >= v$MIN_NODE）。"; fi
    try_install_node || true
    NODE_MAJOR="$(node_major)"
    if [ -z "$NODE_MAJOR" ] || [ "$NODE_MAJOR" -lt "$MIN_NODE" ]; then
        err "没能自动装好 Node.js（>= v$MIN_NODE）。"
        echo "      请手动安装 LTS：mac 用 'brew install node'，或到 https://nodejs.org 下载；"
        echo "      Linux 若系统源版本过旧，建议用 nvm（https://github.com/nvm-sh/nvm）装 LTS。装完重开终端再重跑本脚本。"
        exit 1
    fi
fi
ok "Node.js v$NODE_MAJOR"

# ---- 2. 安装 / 检测 Claude Code ----
step 2 "安装 Claude Code"
if command -v claude >/dev/null 2>&1; then
    ok "已安装：$(claude --version 2>/dev/null || echo '已存在')"
    echo "      （如需更新可手动跑：npm update -g @anthropic-ai/claude-code）"
else
    echo "      未检测到 claude，开始 npm 全局安装..."
    if ! npm install -g @anthropic-ai/claude-code; then
        err "npm 安装失败。若是权限问题，可配置 npm 用户级前缀后重试（避免 sudo 装全局包）。"
        exit 1
    fi
    ok "Claude Code 安装完成"
fi

# ---- 3. 输入密钥 + 写环境变量 ----
step 3 "配置凯洛后端"
printf '  请粘贴你的凯洛密钥 (zk_ 开头): '
read -r KEY
KEY="$(printf '%s' "$KEY" | tr -d '[:space:]')"
if [ -z "$KEY" ]; then
    err "密钥为空，已中止。"
    exit 1
fi
case "$KEY" in
    zk_*) : ;;
    *) warn "密钥不是 zk_ 开头，可能填错。仍继续，但验证可能失败。" ;;
esac

printf '  默认模型 [回车用 %s]: ' "$DEFAULT_MODEL"
read -r MODEL
MODEL="$(printf '%s' "$MODEL" | tr -d '[:space:]')"
[ -z "$MODEL" ] && MODEL="$DEFAULT_MODEL"

# 选 shell profile：zsh -> ~/.zshrc，否则 ~/.bashrc（macOS 默认 zsh）
case "${SHELL:-}" in
    *zsh) PROFILE="$HOME/.zshrc" ;;
    *)    PROFILE="$HOME/.bashrc" ;;
esac
touch "$PROFILE"

# 幂等：先删旧的凯洛块，再追加新块（避免重复运行堆积）
MARK_START="# >>> kailoo claude code >>>"
MARK_END="# <<< kailoo claude code <<<"
tmp="$(mktemp)"
sed "/$MARK_START/,/$MARK_END/d" "$PROFILE" > "$tmp" && mv "$tmp" "$PROFILE"
{
    echo "$MARK_START"
    echo "export ANTHROPIC_BASE_URL=$BASE"
    echo "export ANTHROPIC_AUTH_TOKEN=$KEY      # 注意：AUTH_TOKEN，不是 API_KEY"
    echo "export ANTHROPIC_MODEL=$MODEL"
    echo "export ANTHROPIC_DEFAULT_HAIKU_MODEL=$HAIKU_MODEL   # 后台小模型，必须是 kailoo 服务的 haiku，否则 claude 后台任务报错"
    echo "export ANTHROPIC_SMALL_FAST_MODEL=$HAIKU_MODEL       # 旧版 Claude Code 变量名，兼容老版本"
    echo "$MARK_END"
} >> "$PROFILE"

# 当前会话也设上，让本脚本能立刻验证
export ANTHROPIC_BASE_URL="$BASE"
export ANTHROPIC_AUTH_TOKEN="$KEY"
export ANTHROPIC_MODEL="$MODEL"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="$HAIKU_MODEL"
export ANTHROPIC_SMALL_FAST_MODEL="$HAIKU_MODEL"
ok "已写入 $PROFILE（BASE_URL / AUTH_TOKEN / MODEL=$MODEL / HAIKU=$HAIKU_MODEL）"
warn "新开终端自动生效；当前终端可先跑 'source $PROFILE'。"

# ---- 4. 实跑验证 ----
step 4 "验证密钥与链路"
if ! command -v curl >/dev/null 2>&1; then
    warn "未找到 curl，跳过验证。请手动启动 claude 测试。"
else
    # 第一步：GET /v1/models 校验密钥（只验密钥，不依赖任何模型 channel 是否在线，
    # 不会因为某模型暂时无可用渠道 503 而把有效密钥误判为无效）。
    auth_ok=0
    auth_code="$(curl -s -o /dev/null -w '%{http_code}' -m 30 "$BASE/v1/models" \
        -H "Authorization: Bearer $KEY" || echo "000")"
    case "$auth_code" in
        200) ok "密钥有效，账号鉴权通过。"; auth_ok=1 ;;
        401) err "401 鉴权失败：密钥错误 / 已过期。请核对 zk_ 密钥。" ;;
        000) err "连接失败：网络不通或 base_url 错误。" ;;
        *)   err "鉴权请求失败，HTTP $auth_code。" ;;
    esac

    # 第二步：1 token 最小请求探所选模型当前是否有可用渠道（与密钥有效性分开判）。
    if [ "$auth_ok" = "1" ]; then
        body="{\"model\":\"$MODEL\",\"max_tokens\":8,\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}]}"
        m_code="$(curl -s -o /dev/null -w '%{http_code}' -m 30 "$BASE/v1/messages" \
            -H "x-api-key: $KEY" \
            -H "anthropic-version: 2023-06-01" \
            -H "content-type: application/json" \
            -d "$body" || echo "000")"
        case "$m_code" in
            200) ok "模型 $MODEL 当前可用，凯洛后端已就绪。" ;;
            403) warn "模型 $MODEL 不在你密钥放行清单内（试用仅 opus-4-7 / sonnet-4-6 / haiku-4-5），换个模型即可。" ;;
            503) warn "密钥有效，但模型 $MODEL 当前无可用渠道（服务端暂时缺后端）。可稍后再试 / 换模型 / 联系 support@kailoo.ai。" ;;
            429) warn "密钥有效，但当前限流（429），稍后再试。" ;;
            *)   warn "模型可用性探测未通过：HTTP $m_code（密钥本身有效）。" ;;
        esac
    fi
fi

# ---- 迁移：恢复内置 WebSearch（旧版安装器曾写 permissions.deny:["WebSearch"]·现统一走官方原生满血搜索）----
if command -v node >/dev/null 2>&1; then
    if node -e "const fs=require('fs'),os=require('os'),path=require('path');const p=path.join(os.homedir(),'.claude','settings.json');try{const d=JSON.parse(fs.readFileSync(p,'utf8'));if(d&&d.permissions&&Array.isArray(d.permissions.deny)&&d.permissions.deny.includes('WebSearch')){d.permissions.deny=d.permissions.deny.filter(x=>x!=='WebSearch');fs.writeFileSync(p,JSON.stringify(d,null,2));console.log('KAILOO_WEBSEARCH_RESTORED');}}catch(e){}" 2>/dev/null | grep -q KAILOO_WEBSEARCH_RESTORED; then
        ok "已移除旧版安装器禁用的内置 WebSearch（恢复官方原生联网搜索）。"
    fi
fi

# ---- 5.（可选）联网搜索 MCP ----
# 2026-06-28 实测：原生 WebSearch（Anthropic web_search server tool）经 kailoo 已满血可用，
# 客户端无需任何额外设置，也【不】再禁用内置 WebSearch（旧做法会把能用的搜索弄没）。
# 故默认【不】装 kailoo-search MCP。仅当要用 /v1/search（SerpAPI·可控成本）替代原生时改 1。
ENABLE_SEARCH_SETUP=0           # 默认走官方原生 WebSearch（满血·无上限）
MCP_SPEC="https://kailoo.ai/install/kailoo_search_mcp-0.1.0-py3-none-any.whl"    # 自托管 wheel

find_python() {
    for cand in python3 python; do
        if command -v "$cand" >/dev/null 2>&1; then
            v="$("$cand" -c 'import sys;print("%d.%d"%sys.version_info[:2])' 2>/dev/null || echo "")"
            major="${v%%.*}"; minor="${v#*.}"
            if [ -n "$v" ] && { [ "$major" -gt 3 ] || { [ "$major" -eq 3 ] && [ "$minor" -ge 10 ]; }; }; then
                echo "$cand"; return 0
            fi
        fi
    done
    echo ""; return 1
}

if [ "$ENABLE_SEARCH_SETUP" = "1" ] && [ "${auth_ok:-0}" = "1" ]; then
    step 5 "配置联网搜索（MCP）"
    PY="$(find_python)"
    if [ -z "$PY" ]; then
        warn "未找到 Python 3.10+，尝试自动安装..."
        try_install_python || true
        PY="$(find_python)"
    fi
    if [ -z "$PY" ]; then
        warn "没有 Python 3.10+（也没装上），跳过联网搜索。装好 Python 后重跑本脚本即可启用（不影响 Claude Code 接入）。"
    elif "$PY" -m pip install --user --quiet "$MCP_SPEC"; then
        # 用户级注册（全项目可用），先删后加保证幂等
        claude mcp remove kailoo-search >/dev/null 2>&1 || true
        if claude mcp add kailoo-search --scope user \
                --env "KAILOO_API_KEY=$KEY" --env "KAILOO_BASE_URL=$BASE" \
                -- "$PY" -m kailoo_search_mcp.server; then
            # 关键：禁用内置 WebSearch（经 kailoo 走不通·会抢着用导致搜不到/降智），
            # 让模型改用 kailoo-search。合并进用户级 settings.json，保留其它配置。
            if "$PY" - <<'PYEOF'
import json, os
p = os.path.expanduser("~/.claude/settings.json")
os.makedirs(os.path.dirname(p), exist_ok=True)
try:
    d = json.load(open(p, encoding="utf-8"))
except Exception:
    d = {}
perm = d.setdefault("permissions", {})
allow = perm.setdefault("allow", []); deny = perm.setdefault("deny", [])
if "WebSearch" in allow: allow.remove("WebSearch")
if "WebSearch" not in deny: deny.append("WebSearch")
json.dump(d, open(p, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
PYEOF
            then
                ok "联网搜索已启用：已禁用走不通的内置 WebSearch，Claude 改用 kailoo-search 联网（带源）。"
            else
                ok "联网搜索 MCP 已注册（但未能自动禁用内置 WebSearch，搜索若不准请手动在 settings.json 加 permissions.deny: [\"WebSearch\"]）。"
            fi
        else
            warn "联网搜索注册失败（不影响上面的 Claude Code 接入）。"
        fi
    else
        warn "联网搜索依赖安装失败（不影响上面的 Claude Code 接入）。装好后重跑。"
    fi
fi

# ---- 完成 ----
printf '\n%s======================================================%s\n' "$C_MAG" "$C_RST"
printf '%s  下一步%s\n' "$C_MAG" "$C_RST"
printf '%s======================================================%s\n' "$C_MAG" "$C_RST"
echo "  1. 新开一个终端（或先 source $PROFILE）"
echo "  2. cd 进你的项目文件夹"
echo "  3. 运行：claude"
echo "  4. 会话内切模型：/model（可选 claude-sonnet-4-6 / claude-haiku-4-5-20251001）"
printf '%s  遇到问题：support@kailoo.ai%s\n' "$C_GRAY" "$C_RST"
