#!/bin/bash
# XCodeCLI Setup Launcher (macOS / Linux)
# 一站式安装和配置 Claude Code, Gemini CLI, Codex

set -e

# 确保 PATH 包含常见的包管理器路径
export PATH="$HOME/.local/share/fnm:$HOME/.fnm:$HOME/.local/bin:$HOME/.npm-global/bin:/usr/local/bin:$PATH"

# ========== 颜色定义 ==========
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# ========== 输出函数 ==========
info()    { echo -e "${BLUE}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
error()   { echo -e "${RED}[ERROR]${NC} $1"; }

# ========== 检测 shell 配置文件 ==========
get_shell_rc() {
    if [ -n "${ZSH_VERSION:-}" ] || [ "${SHELL##*/}" = "zsh" ]; then
        echo "$HOME/.zshrc"
    elif [ -n "${BASH_VERSION:-}" ] || [ "${SHELL##*/}" = "bash" ]; then
        if [ -f "$HOME/.bashrc" ]; then
            echo "$HOME/.bashrc"
        else
            echo "$HOME/.bash_profile"
        fi
    else
        error "不支持当前 shell: ${SHELL##*/}"
        error "仅支持 bash 和 zsh"
        exit 1
    fi
}

# ========== 刷新环境变量 ==========
reload_env() {
    local rc_file
    rc_file=$(get_shell_rc)

    # 重新加载 PATH
    export PATH="$HOME/.local/share/fnm:$HOME/.fnm:$HOME/.local/bin:$HOME/.npm-global/bin:/usr/local/bin:$PATH"

    # 加载 fnm 环境（如果存在）
    if command_exists fnm; then
        eval "$(fnm env)" 2>/dev/null || true
    fi

    # 从配置文件中提取并加载环境变量
    if [ -f "$rc_file" ]; then
        while IFS= read -r line; do
            if [[ "$line" =~ ^export\ ([A-Za-z_][A-Za-z0-9_]*)= ]]; then
                eval "$line" 2>/dev/null || true
            fi
        done < "$rc_file"
    fi

    # 刷新命令缓存
    hash -r 2>/dev/null || true
}

# ========== 工具配置（兼容 bash 3.x）==========
TOOL_NAMES_1="Claude Code"
TOOL_NAMES_2="Gemini CLI"
TOOL_NAMES_3="Codex"

TOOL_CMDS_1="claude"
TOOL_CMDS_2="gemini"
TOOL_CMDS_3="codex"

TOOL_PKGS_1="@anthropic-ai/claude-code"
TOOL_PKGS_2="@google/gemini-cli@latest"
TOOL_PKGS_3="@openai/codex"

TOOL_URLS_1="https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/ClaudeCode/setup-claude-code.sh"
TOOL_URLS_2="https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/GeminiCLI/setup-gemini.sh"
TOOL_URLS_3="https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/codex/setup-codex.sh"

# Helper functions to get tool properties
get_tool_name() { eval echo \"\$TOOL_NAMES_$1\"; }
get_tool_cmd() { eval echo \"\$TOOL_CMDS_$1\"; }
get_tool_pkg() { eval echo \"\$TOOL_PKGS_$1\"; }
get_tool_url() { eval echo \"\$TOOL_URLS_$1\"; }

# ========== 检测系统包管理器 ==========
get_sys_pkg_manager() {
    if command_exists apt-get; then
        echo "apt"
    elif command_exists yum; then
        echo "yum"
    elif command_exists dnf; then
        echo "dnf"
    elif command_exists apk; then
        echo "apk"
    elif command_exists brew; then
        echo "brew"
    elif command_exists pacman; then
        echo "pacman"
    else
        echo ""
    fi
}

# ========== 安装系统依赖 ==========
install_sys_deps() {
    local deps=("$@")
    local pkg_mgr=$(get_sys_pkg_manager)

    if [[ -z "$pkg_mgr" ]]; then
        error "无法检测系统包管理器，请手动安装: ${deps[*]}"
        return 1
    fi

    info "正在安装: ${deps[*]} ..."

    case "$pkg_mgr" in
        apt)
            apt-get update -qq && apt-get install -y "${deps[@]}"
            ;;
        yum)
            yum install -y "${deps[@]}"
            ;;
        dnf)
            dnf install -y "${deps[@]}"
            ;;
        apk)
            apk add "${deps[@]}"
            ;;
        brew)
            brew install "${deps[@]}"
            ;;
        pacman)
            pacman -S --noconfirm "${deps[@]}"
            ;;
    esac

    # 验证所有依赖是否安装成功
    local failed=()
    for dep in "${deps[@]}"; do
        if command_exists "$dep"; then
            success "$dep 安装成功!"
        else
            failed+=("$dep")
        fi
    done

    if [[ ${#failed[@]} -gt 0 ]]; then
        error "以下依赖安装失败: ${failed[*]}"
        return 1
    fi
    return 0
}

# ========== 检测并安装系统依赖 ==========
check_system_deps() {
    local missing_deps=()

    # 检测 curl
    if ! command_exists curl; then
        missing_deps+=("curl")
    fi

    # 检测 unzip (fnm 安装需要)
    if ! command_exists unzip; then
        missing_deps+=("unzip")
    fi

    # 检测 jq (Claude Code 配置需要)
    if ! command_exists jq; then
        missing_deps+=("jq")
    fi

    if [[ ${#missing_deps[@]} -eq 0 ]]; then
        return 0
    fi

    echo ""
    warning "检测到缺少以下系统依赖: ${missing_deps[*]}"
    echo ""

    read -p "是否自动安装这些依赖? (Y/n) " -n 1 -r
    echo ""

    if [[ $REPLY =~ ^[Nn]$ ]]; then
        error "请手动安装依赖后重新运行脚本"
        echo ""
        local pkg_mgr=$(get_sys_pkg_manager)
        case "$pkg_mgr" in
            apt)
                echo -e "  ${CYAN}apt-get update && apt-get install -y ${missing_deps[*]}${NC}"
                ;;
            yum)
                echo -e "  ${CYAN}yum install -y ${missing_deps[*]}${NC}"
                ;;
            dnf)
                echo -e "  ${CYAN}dnf install -y ${missing_deps[*]}${NC}"
                ;;
            apk)
                echo -e "  ${CYAN}apk add ${missing_deps[*]}${NC}"
                ;;
            brew)
                echo -e "  ${CYAN}brew install ${missing_deps[*]}${NC}"
                ;;
            pacman)
                echo -e "  ${CYAN}pacman -S ${missing_deps[*]}${NC}"
                ;;
            *)
                echo -e "  请使用系统包管理器安装: ${missing_deps[*]}"
                ;;
        esac
        echo ""
        return 1
    fi

    # 一次性安装所有缺失的依赖
    if ! install_sys_deps "${missing_deps[@]}"; then
        return 1
    fi

    return 0
}

# ========== 帮助信息 ==========
show_help() {
    cat << 'EOF'
XCodeCLI Setup Launcher (macOS / Linux)
一站式安装和配置 Claude Code, Gemini CLI, Codex

Usage: ./setup.sh [OPTIONS]

Options:
  --key <KEY>   预设 API 密钥（必填）
  --help        显示此帮助信息

一行命令快速使用:
  API_KEY='YOUR_API_KEY' bash -c "$(curl -fsSL https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/setup.sh)"
EOF
    exit 0
}

# ========== 命令检测 ==========
command_exists() {
    command -v "$1" &> /dev/null
}

# ========== Node.js 版本检测 ==========
get_node_version() {
    if command_exists node; then
        node --version 2>/dev/null | sed 's/v//'
    fi
}

get_node_major_version() {
    local version
    version=$(get_node_version)
    if [ -n "$version" ]; then
        echo "$version" | cut -d. -f1
    fi
}

# ========== 安装 fnm ==========
install_fnm() {
    echo ""
    info "正在安装 fnm (Fast Node Manager)..."

    if curl -fsSL https://fnm.vercel.app/install | bash; then
        export PATH="$HOME/.local/share/fnm:$PATH"
        if [ -f "$HOME/.local/share/fnm/fnm" ]; then
            eval "$($HOME/.local/share/fnm/fnm env)" 2>/dev/null || true
        fi

        if command_exists fnm; then
            success "fnm 安装成功!"
            return 0
        else
            warning "fnm 可能已安装，但需要重新打开终端才能生效"
            info "请重新打开终端后再运行此脚本"
            return 1
        fi
    else
        error "fnm 安装失败"
        return 1
    fi
}

# ========== 使用 fnm 安装 Node.js ==========
install_node_with_fnm() {
    info "使用 fnm 安装 Node.js 24.x..."

    if fnm install 24 && fnm use 24 && fnm default 24; then
        eval "$(fnm env)" 2>/dev/null || true

        if command_exists node; then
            local version
            version=$(get_node_version)
            success "Node.js v$version 安装成功!"
            return 0
        else
            warning "Node.js 可能已安装，但需要重新打开终端才能生效"
            return 1
        fi
    else
        error "Node.js 安装失败"
        return 1
    fi
}

# ========== 确保 Node.js 环境就绪 ==========
ensure_node_environment() {
    local version major

    version=$(get_node_version)
    if [ -n "$version" ]; then
        major=$(get_node_major_version)
        info "检测到 Node.js v$version"

        if [ "$major" -lt 20 ]; then
            warning "Node.js 版本过低 (需要 >= 20.x)"
            echo ""

            read -p "是否使用 fnm 安装 Node.js 24.x? (Y/n) " -n 1 -r
            echo ""
            if [[ $REPLY =~ ^[Nn]$ ]]; then
                error "Node.js 版本不满足要求，请手动升级后重试"
                return 1
            fi

            if ! command_exists fnm; then
                install_fnm || return 1
            fi

            install_node_with_fnm || return 1
        fi

        return 0
    fi

    warning "未检测到 Node.js"
    info "将使用 fnm 安装 Node.js 24.x"
    echo ""

    read -p "是否继续? (Y/n) " -n 1 -r
    echo ""
    if [[ $REPLY =~ ^[Nn]$ ]]; then
        return 1
    fi

    if ! command_exists fnm; then
        install_fnm || return 1
    fi

    install_node_with_fnm || return 1
}

# ========== 安装工具 ==========
install_tool() {
    local tool_num=$1
    local tool_name=$(get_tool_name "$tool_num")
    local tool_pkg=$(get_tool_pkg "$tool_num")

    info "安装 $tool_name..."

    # 所有工具统一使用 npm 安装 (需要 Node.js)
    if ! ensure_node_environment; then
        return 1
    fi
    local install_cmd="npm install -g $tool_pkg"
    echo -e "  执行: ${CYAN}$install_cmd${NC}"
    if eval "$install_cmd"; then
        hash -r 2>/dev/null || true
        local tool_cmd=$(get_tool_cmd "$tool_num")
        if command -v "$tool_cmd" >/dev/null 2>&1; then
            success "$tool_name 安装成功!"
            return 0
        else
            warning "$tool_name 可能已安装，但需要重新打开终端才能生效"
            return 0
        fi
    else
        error "$tool_name 安装失败"
        return 1
    fi
}

# ========== 配置工具 ==========
configure_tool() {
    local tool_num=$1
    local api_key=$2
    local tool_name=$(get_tool_name "$tool_num")
    local setup_url=$(get_tool_url "$tool_num")

    info "配置 $tool_name..."

    # 先下载脚本到临时文件，避免 curl 失败时空脚本静默执行
    local tmp_script
    tmp_script=$(mktemp) || { error "无法创建临时文件"; return 1; }
    trap "rm -f '$tmp_script'" RETURN

    if ! curl -fsSL "$setup_url" -o "$tmp_script"; then
        error "下载 $tool_name 配置脚本失败 (请检查网络连接)"
        return 1
    fi

    if [ ! -s "$tmp_script" ]; then
        error "下载的配置脚本为空"
        return 1
    fi

    if API_KEY="$api_key" bash "$tmp_script"; then
        success "$tool_name 配置完成!"
        return 0
    else
        error "$tool_name 配置失败"
        return 1
    fi
}

# ========== 显示状态 ==========
show_status() {
    echo ""
    echo -e "${CYAN}========================================${NC}"
    echo -e "${CYAN}       XCodeCLI Setup Launcher${NC}"
    echo -e "${CYAN}========================================${NC}"
    echo ""
    echo -e "获取 API 密钥: ${CYAN}https://api2.xcodecli.com/console/token${NC}"
    echo -e "步骤: 添加令牌 → 输入令牌名称 → 提交"
    echo ""

    # 显示 Node.js 状态
    local version major
    version=$(get_node_version)
    if [ -n "$version" ]; then
        major=$(get_node_major_version)
        local status color
        if [ "$major" -ge 20 ]; then
            status="[OK]"
            color="${GREEN}"
        else
            status="[需升级]"
            color="${YELLOW}"
        fi
        echo -e "  Node.js: v$version ${color}${status}${NC}"
    else
        echo -e "  Node.js: ${RED}[未安装]${NC}"
    fi
    echo ""

    echo -e "${YELLOW}工具安装状态:${NC}"
    echo ""

    for i in 1 2 3; do
        local tool_name=$(get_tool_name "$i")
        local tool_cmd=$(get_tool_cmd "$i")
        local status
        local color

        if command_exists "$tool_cmd"; then
            status="[已安装]"
            color="${GREEN}"
        else
            status="[未安装]"
            color="${RED}"
        fi

        printf "  [%d] %-12s %b%s%b\n" "$i" "$tool_name" "$color" "$status" "$NC"
    done
    echo ""
    echo -e "  [${CYAN}a${NC}] 配置全部工具"
    echo -e "  [${CYAN}0${NC}] 退出"
    echo ""
}

# ========== 主函数 ==========
main() {
    local api_key="${API_KEY:-}"

    # 解析参数
    while [[ $# -gt 0 ]]; do
        case $1 in
            --key)
                api_key="$2"
                shift 2
                ;;
            --help|-h)
                show_help
                ;;
            *)
                shift
                ;;
        esac
    done

    # 检测并安装系统依赖 (curl, unzip, jq)
    if ! check_system_deps; then
        exit 1
    fi

    # 显示状态
    show_status

    # 选择要配置的工具
    echo -e "${YELLOW}请选择要配置的工具 (1/2/3/a/0):${NC}"
    read -r choice

    # 退出
    if [[ "$choice" == "0" ]]; then
        info "再见!"
        exit 0
    fi

    # 验证选择
    local tools_to_configure=""
    if [[ "$choice" == "a" || "$choice" == "A" ]]; then
        tools_to_configure="1 2 3"
    elif [[ "$choice" =~ ^[1-3]$ ]]; then
        tools_to_configure="$choice"
    else
        error "无效的选择"
        exit 1
    fi

    # 检查 API Key
    if [[ -z "$api_key" ]]; then
        echo ""
        echo -e "${YELLOW}请输入 API 密钥:${NC}"
        read -r api_key
        if [[ -z "$api_key" ]]; then
            error "API 密钥不能为空"
            exit 1
        fi
    fi

    info "API 密钥: ${api_key:0:8}..."
    echo ""

    # Node.js 环境检查已移至 install_tool 内部 (三个工具均需要)

    echo ""
    echo -e "${CYAN}========================================${NC}"
    echo -e "${CYAN}         开始安装和配置工具${NC}"
    echo -e "${CYAN}========================================${NC}"
    echo ""

    local failed=0
    local total=$(echo $tools_to_configure | wc -w | tr -d ' ')
    local current=0

    # 安装和配置选中的工具
    for i in $tools_to_configure; do
        current=$((current + 1))
        local tool_name=$(get_tool_name "$i")
        local tool_cmd=$(get_tool_cmd "$i")

        echo ""
        echo -e "${YELLOW}>>> [$current/$total] $tool_name${NC}"
        echo ""

        # 检测是否已安装
        if ! command_exists "$tool_cmd"; then
            if ! install_tool "$i"; then
                failed=$((failed + 1))
                continue
            fi
        else
            info "$tool_name 已安装，跳过安装步骤"
        fi

        # 配置工具
        if ! configure_tool "$i" "$api_key"; then
            failed=$((failed + 1))
        fi
    done

    # 显示结果
    echo ""
    echo -e "${CYAN}========================================${NC}"
    echo -e "${CYAN}             配置完成${NC}"
    echo -e "${CYAN}========================================${NC}"
    echo ""

    # 自动刷新环境变量
    info "正在刷新环境变量..."
    reload_env

    if [[ $failed -eq 0 ]]; then
        success "所有选中的工具配置成功!"
        echo ""

        # 验证工具是否可用
        local all_ok=true
        for i in $tools_to_configure; do
            local tool_cmd=$(get_tool_cmd "$i")
            local tool_name=$(get_tool_name "$i")
            if command_exists "$tool_cmd"; then
                echo -e "  ${GREEN}✓${NC} $tool_name ($tool_cmd) 可用"
            else
                echo -e "  ${RED}✗${NC} $tool_name ($tool_cmd) 未找到"
                all_ok=false
            fi
        done

        echo ""
        if [[ "$all_ok" == "false" ]]; then
            warning "部分工具在当前会话中不可用"
            echo -e "${YELLOW}请执行以下命令刷新环境:${NC}"
            echo ""
            local rc_file=$(get_shell_rc)
            echo -e "  ${CYAN}source $rc_file${NC}"
            echo ""
            echo -e "或者重新打开终端"
        else
            success "所有工具已就绪，可以直接使用!"
        fi
    else
        warning "有 $failed 个工具配置失败"
    fi

    # 询问是否启动新 shell 以使环境变量生效
    echo ""
    echo -e "${YELLOW}是否启动新的 shell 会话以使环境变量立即生效? (Y/n)${NC}"
    read -r -n 1 start_new_shell
    echo ""

    if [[ ! "$start_new_shell" =~ ^[Nn]$ ]]; then
        info "正在启动新的 shell..."
        exec "$SHELL" -l
    fi
}

main "$@"
