#!/usr/bin/env bash

################################################################################
# 闪电API - OpenAI Codex CLI 一键安装脚本
#
# 功能: 安装 Codex CLI + 配置 API
# 官网: flashapi.top
# 模型调用: ai.flashapi.top (国内直连) / cdn.flashapi.top (海外CDN)
#
# 用法: curl -fsSL https://flashapi.top/sh/codex.sh | bash
#
# 不需要 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'
BLUE='\033[38;5;33m'
BRIGHT_YELLOW='\033[38;5;226m'
BRIGHT_GREEN='\033[38;5;46m'
NC='\033[0m'

OS_TYPE=""
IS_WSL=false
NPM_MIRROR="https://registry.npmmirror.com"

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

print_banner() {
  echo ""
  echo -e "  ${BOLD}${BRIGHT_GREEN}    ⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡${NC}"
  echo -e "  ${BOLD}${BRIGHT_GREEN}   ██████╗ ██████╗ ██████╗ ███████╗██╗  ██╗${NC}"
  echo -e "  ${BOLD}${BRIGHT_GREEN}  ██╔════╝██╔═══██╗██╔══██╗██╔════╝╚██╗██╔╝${NC}"
  echo -e "  ${BOLD}${BRIGHT_GREEN}  ██║     ██║   ██║██║  ██║█████╗   ╚███╔╝${NC}"
  echo -e "  ${BOLD}${BRIGHT_GREEN}  ██║     ██║   ██║██║  ██║██╔══╝   ██╔██╗${NC}"
  echo -e "  ${BOLD}${BRIGHT_GREEN}  ╚██████╗╚██████╔╝██████╔╝███████╗██╔╝ ██╗${NC}"
  echo -e "  ${BOLD}${BRIGHT_GREEN}   ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝  ╚═╝${NC}"
  echo -e "  ${BOLD}${BRIGHT_YELLOW}        ⚡ 闪电API × Codex CLI ⚡${NC}"
  echo -e "  ${BOLD}${BRIGHT_GREEN}    ⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡⚡${NC}"
  echo ""
  echo -e "  ${GRAY}───────────────────────────────────────────────────────${NC}"
  echo -e "  ${WHITE}⚡ 闪电API${NC} ${GRAY}|${NC} ${CYAN}官网${NC} ${BOLD}${BRIGHT_YELLOW}flashapi.top${NC}"
  echo -e "  ${WHITE}Codex CLI 一键安装${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
}

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_shell_configs() {
  SHELL_CONFIGS=()
  if [[ "$OS_TYPE" == "windows" ]]; then
    for f in "$HOME/.bashrc" "$HOME/.bash_profile" "$HOME/.profile"; do
      [[ -f "$f" ]] && SHELL_CONFIGS+=("$f")
    done
    [[ ${#SHELL_CONFIGS[@]} -eq 0 ]] && SHELL_CONFIGS=("$HOME/.bashrc")
  else
    for f in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.bash_profile" "$HOME/.profile"; do
      [[ -f "$f" ]] && SHELL_CONFIGS+=("$f")
    done
    if [[ ${#SHELL_CONFIGS[@]} -eq 0 ]]; then
      [[ "$OS_TYPE" == "macos" ]] && SHELL_CONFIGS=("$HOME/.zshrc") || SHELL_CONFIGS=("$HOME/.bashrc")
    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
}

# 读取密码输入 (bash/zsh 兼容，带 * 遮盖)
read_secret() {
  local prompt="$1"
  local varname="$2"
  local input=""
  local char

  echo -en "$prompt" >&2

  while true; do
    if [[ -n "${ZSH_VERSION:-}" ]]; then
      IFS= read -r -s -k1 char < /dev/tty
    else
      IFS= read -r -s -n1 char < /dev/tty
    fi

    if [[ $char == $'\n' ]] || [[ $char == $'\r' ]] || [[ -z "$char" ]]; then
      break
    elif [[ $char == $'\177' ]] || [[ $char == $'\b' ]]; then
      if [[ -n "$input" ]]; then
        input="${input%?}"
        echo -en "\b \b" >&2
      fi
    else
      input+="$char"
      echo -n "*" >&2
    fi
  done
  echo "" >&2

  eval "$varname=\$input"
}

set_env_var() {
  local var_name="$1" var_value="$2"
  export "$var_name=$var_value"
  for config_file in "${SHELL_CONFIGS[@]}"; do
    [[ -f "$config_file" ]] && sed_inplace "/^export ${var_name}=/d" "$config_file" 2>/dev/null || true
    echo "export ${var_name}=\"${var_value}\"" >> "$config_file"
  done
  if [[ "$OS_TYPE" == "windows" ]]; then
    command -v setx.exe >/dev/null 2>&1 && setx.exe "$var_name" "$var_value" >/dev/null 2>&1 || \
    command -v setx >/dev/null 2>&1 && setx "$var_name" "$var_value" >/dev/null 2>&1 || true
  fi
}

################################################################################
# 功能 1: 安装 Codex CLI
################################################################################

check_codex_installed() {
  if command -v codex >/dev/null 2>&1; then
    codex --version 2>/dev/null || echo "unknown"
    return 0
  fi
  return 1
}

install_with_mirror() {
  print_status "info" "切换国内镜像 (npmmirror.com) 安装 ..."
  npm install -g @openai/codex --registry="$NPM_MIRROR"
}

install_codex_cli() {
  echo ""
  print_status "info" "⚡ 正在安装 Codex CLI ..."
  echo ""

  [[ "$IS_WSL" == "true" ]] && print_status "info" "检测到 WSL 环境"
  [[ "$OS_TYPE" == "windows" ]] && print_status "info" "检测到 Windows (Git Bash) 环境"

  local ver
  if ver="$(check_codex_installed)"; then
    print_status "ok" "Codex CLI 已安装 ($ver)"
    echo ""
    local answer
    echo -en "  ${YELLOW}是否重新安装? (y/N): ${NC}" >&2
    read -r answer < /dev/tty
    [[ "$answer" != "y" && "$answer" != "Y" ]] && { print_status "info" "跳过安装"; return 0; }
  fi

  # 检查 npm
  if ! command -v npm >/dev/null 2>&1; then
    print_status "error" "未找到 npm，请先安装 Node.js (需要 v22+)"
    echo ""
    echo -e "  ${WHITE}安装方式:${NC}"
    echo -e "    ${CYAN}官网下载:${NC} https://nodejs.org/"
    echo -e "    ${CYAN}macOS:${NC}    brew install node"
    echo -e "    ${CYAN}Ubuntu:${NC}   sudo apt install nodejs npm"
    return 1
  fi

  # 检查 Node 版本 (Codex 需要 v22+)
  local node_major
  node_major="$(node -v 2>/dev/null | sed 's/v//' | cut -d. -f1)"
  if [[ -n "$node_major" ]] && [[ "$node_major" -lt 22 ]]; then
    print_status "warn" "当前 Node.js 版本 $(node -v)，Codex CLI 建议 v22+"
    print_status "info" "建议升级: https://nodejs.org/"
    echo ""
    local answer
    echo -en "  ${YELLOW}是否仍然继续安装? (y/N): ${NC}" >&2
    read -r answer < /dev/tty
    [[ "$answer" != "y" && "$answer" != "Y" ]] && { print_status "info" "已取消"; return 1; }
  fi

  print_status "ok" "npm 已就绪 ($(npm --version 2>/dev/null)), Node $(node -v 2>/dev/null)"

  # 安装
  print_status "info" "使用 npm 安装 @openai/codex ..."
  echo ""
  if ! npm install -g @openai/codex 2>/dev/null; then
    print_status "warn" "默认源安装失败，可能是网络问题"
    if ! install_with_mirror; then
      print_status "error" "所有安装方式均失败，请检查网络连接"
      return 1
    fi
  fi

  echo ""
  if ver="$(check_codex_installed)"; then
    print_status "ok" "⚡ Codex CLI 安装成功 ($ver)"
  else
    print_status "warn" "安装已完成，但未在 PATH 中找到 codex"
    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 "Authorization: Bearer ${api_key}" \
    "${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="${OPENAI_API_KEY:-}"
  local existing_url="${OPENAI_BASE_URL:-}"
  if [[ -n "$existing_key" ]]; then
    local masked="${existing_key:0:8}...${existing_key: -4}"
    print_status "info" "当前 API Key: ${masked}"
  fi
  [[ -n "$existing_url" ]] && print_status "info" "当前 BASE URL: ${existing_url}"
  echo ""

  # ── 选择线路 ──
  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

  local base_url
  case "$choice" in
    1) base_url="https://ai.flashapi.top" ;;
    2) base_url="https://cdn.flashapi.top" ;;
    *) print_status "error" "无效选项，已取消"; return 1 ;;
  esac

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

  # ── 令牌分组提醒 ──
  echo -e "  ${YELLOW}╔══════════════════════════════════════════════════════╗${NC}"
  echo -e "  ${YELLOW}║${NC}  ${WHITE}⚡ 重要提示${NC}                                       ${YELLOW}║${NC}"
  echo -e "  ${YELLOW}║${NC}                                                      ${YELLOW}║${NC}"
  echo -e "  ${YELLOW}║${NC}  ${GRAY}请先在官网${NC} ${BRIGHT_YELLOW}flashapi.top${NC} ${GRAY}创建${NC} ${GREEN}令牌分组${NC}             ${YELLOW}║${NC}"
  echo -e "  ${YELLOW}║${NC}  ${GRAY}未创建令牌分组将无法获取模型列表!${NC}                 ${YELLOW}║${NC}"
  echo -e "  ${YELLOW}╚══════════════════════════════════════════════════════╝${NC}"
  echo ""

  # ── 输入 API Key (密码遮盖) ──
  local api_key=""
  read_secret "  ${WHITE}请输入 API Key: ${NC}" api_key

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

  # ── 验证 ──
  if ! validate_api_key "$base_url" "$api_key"; then
    local answer
    echo -en "  ${YELLOW}验证未通过，是否仍要保存? (y/N): ${NC}" >&2
    read -r answer < /dev/tty
    [[ "$answer" != "y" && "$answer" != "Y" ]] && { print_status "info" "已取消配置"; return 1; }
  fi

  # ── 写入环境变量 ──
  set_env_var "OPENAI_API_KEY" "$api_key"
  set_env_var "OPENAI_BASE_URL" "${base_url}/v1"

  echo ""
  local masked="${api_key:0:8}...${api_key: -4}"
  print_status "ok" "API Key 已保存: ${masked}"
  print_status "ok" "BASE URL 已保存: ${base_url}/v1"
  for config_file in "${SHELL_CONFIGS[@]}"; do
    print_status "info" "  -> ${config_file}"
  done
}

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

show_status_summary() {
  echo -e "  ${WHITE}当前状态:${NC}"
  local os_label="$OS_TYPE"
  [[ "$IS_WSL" == "true" ]] && os_label="linux (WSL)"
  echo -e "    系统环境:     ${CYAN}${os_label}${NC}"

  local codex_ver
  if codex_ver="$(check_codex_installed 2>/dev/null)"; then
    echo -e "    Codex CLI:    ${GREEN}已安装${NC} (${codex_ver})"
  else
    echo -e "    Codex CLI:    ${RED}未安装${NC}"
  fi

  if [[ -n "${OPENAI_API_KEY:-}" ]]; then
    local masked="${OPENAI_API_KEY:0:8}...${OPENAI_API_KEY: -4}"
    echo -e "    API 配置:     ${GREEN}已配置${NC} (${masked})"
  else
    echo -e "    API 配置:     ${RED}未配置${NC}"
  fi
  [[ -n "${OPENAI_BASE_URL:-}" ]] && echo -e "    API 线路:     ${GREEN}${OPENAI_BASE_URL}${NC}"
  echo ""
}

show_menu() {
  echo -e "  ${WHITE}请选择操作:${NC}"
  echo ""
  echo -e "    ${BRIGHT_YELLOW}⚡${NC} ${CYAN}1)${NC} 安装 Codex CLI"
  echo -e "    ${BRIGHT_YELLOW}⚡${NC} ${CYAN}2)${NC} 配置 API 密钥和线路"
  echo -e "    ${BRIGHT_YELLOW}⚡${NC} ${CYAN}3)${NC} 一键全部安装 (安装 + 配置)"
  echo -e "    ${BRIGHT_YELLOW}⚡${NC} ${CYAN}0)${NC} 退出"
  echo ""
  echo -en "  ${WHITE}请输入选项: ${NC}" >&2
}

################################################################################
# 主流程
################################################################################

main() {
  detect_os
  detect_shell_configs
  print_banner
  show_status_summary

  while true; do
    show_menu
    local choice
    read -r choice < /dev/tty
    case "$choice" in
      1)
        install_codex_cli
        echo ""
        ;;
      2)
        configure_api
        echo ""
        ;;
      3)
        install_codex_cli
        echo ""
        echo -e "  ${GRAY}───────────────────────────────────────────────────────${NC}"
        configure_api
        echo ""
        echo -e "  ${GRAY}───────────────────────────────────────────────────────${NC}"
        echo ""
        print_status "ok" "⚡ 全部完成! 请重新打开终端后运行 codex 即可使用"
        echo ""
        ;;
      0)
        echo ""
        echo -e "  ${BRIGHT_YELLOW}⚡${NC} ${WHITE}感谢使用闪电API，祝你编码愉快!${NC}"
        echo -e "  ${GRAY}官网: flashapi.top${NC}"
        echo ""
        exit 0
        ;;
      *)
        print_status "error" "无效选项，请重新选择"
        echo ""
        ;;
    esac
  done
}

main "$@"
