#!/bin/sh

# Claudible Installer for Codex CLI
# Configures Codex CLI to use Claudible

set -e

# Configuration (auto-populated by server)
SERVER_URL='https://claudible.io'
API_KEY=''
ENDPOINT_URL=""
CODEX_MODEL=""

# Colors
RED=$(printf '\033[0;31m')
GREEN=$(printf '\033[0;32m')
YELLOW=$(printf '\033[1;33m')
BLUE=$(printf '\033[0;34m')
NC=$(printf '\033[0m')

echo ""
printf '  \033[42m       \033[0m  \033[42m   \033[0m                              \033[42m   \033[0m \033[42m   \033[0m \033[42m   \033[0m        \033[42m   \033[0m\n'
printf ' \033[42m   \033[0m   \033[42m   \033[0m \033[42m   \033[0m                              \033[42m   \033[0m     \033[42m   \033[0m        \033[42m   \033[0m\n'
printf '\033[42m   \033[0m        \033[42m   \033[0m  \033[42m       \033[0m   \033[42m   \033[0m    \033[42m   \033[0m  \033[42m         \033[0m \033[42m   \033[0m \033[42m         \033[0m  \033[42m   \033[0m  \033[42m        \033[0m\n'
printf '\033[42m   \033[0m        \033[42m   \033[0m       \033[42m   \033[0m  \033[42m   \033[0m    \033[42m   \033[0m \033[42m   \033[0m    \033[42m   \033[0m \033[42m   \033[0m \033[42m   \033[0m    \033[42m   \033[0m \033[42m   \033[0m \033[42m   \033[0m    \033[42m   \033[0m\n'
printf '\033[42m   \033[0m        \033[42m   \033[0m  \033[42m        \033[0m  \033[42m   \033[0m    \033[42m   \033[0m \033[42m   \033[0m    \033[42m   \033[0m \033[42m   \033[0m \033[42m   \033[0m    \033[42m   \033[0m \033[42m   \033[0m \033[42m          \033[0m\n'
printf ' \033[42m   \033[0m   \033[42m   \033[0m \033[42m   \033[0m \033[42m   \033[0m   \033[42m   \033[0m  \033[42m   \033[0m   \033[42m    \033[0m \033[42m   \033[0m   \033[42m    \033[0m \033[42m   \033[0m \033[42m    \033[0m   \033[42m   \033[0m \033[42m   \033[0m \033[42m   \033[0m\n'
printf '  \033[42m       \033[0m  \033[42m   \033[0m  \033[42m         \033[0m  \033[42m         \033[0m  \033[42m         \033[0m \033[42m   \033[0m \033[42m         \033[0m  \033[42m   \033[0m  \033[42m        \033[0m\n'
echo ""
echo "  ${GREEN}Codex CLI Setup${NC}"
echo ""

# Validate API key
if [ "$API_KEY" = "__""API_KEY__" ] || [ -z "$API_KEY" ]; then
    echo "${RED}Error: API key not configured${NC}"
    echo "Please use the install link from your Claudible dashboard."
    exit 1
fi

# Check for jq
if ! command -v jq >/dev/null 2>&1; then
    echo "${RED}Error: jq is required but not installed.${NC}"
    echo ""
    echo "  ${BLUE}macOS:${NC}        brew install jq"
    echo "  ${BLUE}Ubuntu/Debian:${NC} sudo apt-get install -y jq"
    echo "  ${BLUE}Arch Linux:${NC}    sudo pacman -S jq"
    echo ""
    exit 1
fi

# Fetch endpoints from model-hub API
echo "${BLUE}Đang tải danh sách endpoints...${NC}"
HUB_JSON=$(curl -fsSL "$SERVER_URL/api/model-hub" 2>/dev/null)
if [ -z "$HUB_JSON" ]; then
    echo "${RED}Error: Không thể kết nối tới server${NC}"
    exit 1
fi

# Filter endpoints with codexEnabled=true and status=active
ENDPOINTS=$(echo "$HUB_JSON" | jq -r '[.endpoints[] | select(.codexEnabled == true and .status == "active")]')
COUNT=$(echo "$ENDPOINTS" | jq 'length')

if [ "$COUNT" -eq 0 ]; then
    echo "${RED}Error: Không có endpoint nào bật Codex${NC}"
    exit 1
fi

if [ "$COUNT" -eq 1 ]; then
    IDX=0
    ENDPOINT_URL=$(echo "$ENDPOINTS" | jq -r '.[0].url')
    CODEX_MODEL=$(echo "$ENDPOINTS" | jq -r '.[0].codexModels[0]')
    EP_NAME=$(echo "$ENDPOINTS" | jq -r '.[0].name')
    echo "  ${GREEN}✓ $EP_NAME${NC}"
else
    echo ""
    echo "${BLUE}Chọn cổng kết nối:${NC}"
    echo ""
    i=1
    while [ "$i" -le "$COUNT" ]; do
        EP_NAME=$(echo "$ENDPOINTS" | jq -r ".[$((i-1))].name")
        EP_URL=$(echo "$ENDPOINTS" | jq -r ".[$((i-1))].url")
        echo "  ${GREEN}${i})${NC} ${EP_NAME}  ${YELLOW}— ${EP_URL}${NC}"
        i=$((i + 1))
    done
    echo ""
    printf "Nhập lựa chọn [1-${COUNT}]: "
    read -r choice < /dev/tty
    if ! echo "$choice" | grep -qE '^[0-9]+$' || [ "$choice" -lt 1 ] || [ "$choice" -gt "$COUNT" ]; then
        echo "${YELLOW}Lựa chọn không hợp lệ, dùng mặc định: 1${NC}"
        choice=1
    fi
    IDX=$((choice - 1))
    ENDPOINT_URL=$(echo "$ENDPOINTS" | jq -r ".[$IDX].url")
    CODEX_MODEL=$(echo "$ENDPOINTS" | jq -r ".[$IDX].codexModels[0]")
fi

# Ensure https:// prefix and strip trailing slash
case "$ENDPOINT_URL" in
    https://*|http://*) ;;
    *) ENDPOINT_URL="https://$ENDPOINT_URL" ;;
esac
ENDPOINT_URL=$(echo "$ENDPOINT_URL" | sed 's:/*$::')

# Fallback default model
if [ -z "$CODEX_MODEL" ] || [ "$CODEX_MODEL" = "null" ]; then
    CODEX_MODEL="o3"
fi

# Mask API key for display
MASKED_KEY=$(echo "$API_KEY" | cut -c 1-10)
echo "Endpoint URL:  ${GREEN}$ENDPOINT_URL${NC}"
echo "API Key:       ${GREEN}${MASKED_KEY}...${NC}"
echo "Default Model: ${GREEN}$CODEX_MODEL${NC}"
echo ""

# Check Node.js >= 22
echo "${BLUE}Checking prerequisites...${NC}"

if ! command -v node >/dev/null 2>&1; then
    echo "${RED}Error: Node.js is not installed${NC}"
    echo ""
    echo "Codex CLI requires Node.js 22 or later."
    echo "Install Node.js from: ${BLUE}https://nodejs.org${NC}"
    echo ""
    echo "  ${BLUE}macOS:${NC}        brew install node"
    echo "  ${BLUE}Ubuntu/Debian:${NC} curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs"
    exit 1
fi

NODE_MAJOR=$(node --version | sed 's/^v//' | cut -d. -f1)
if [ "$NODE_MAJOR" -lt 22 ] 2>/dev/null; then
    echo "${RED}Error: Node.js 22+ is required (found $(node --version))${NC}"
    echo ""
    echo "Please upgrade Node.js: ${BLUE}https://nodejs.org${NC}"
    exit 1
fi
echo "  ${GREEN}✓ Node.js $(node --version)${NC}"

# Check npm
if ! command -v npm >/dev/null 2>&1; then
    echo "${RED}Error: npm is not installed${NC}"
    echo "Please install npm (usually comes with Node.js)."
    exit 1
fi
echo "  ${GREEN}✓ npm $(npm --version)${NC}"

# Install Codex CLI if not found
echo ""
# Ensure npm global bin is on PATH (needed for nvm/custom prefix)
NPM_GLOBAL_BIN=$(npm bin -g 2>/dev/null || npm prefix -g 2>/dev/null | xargs -I{} echo {}/bin)
if [ -n "$NPM_GLOBAL_BIN" ] && [ -d "$NPM_GLOBAL_BIN" ]; then
    export PATH="$NPM_GLOBAL_BIN:$PATH"
fi

if command -v codex >/dev/null 2>&1; then
    echo "${BLUE}Codex CLI already installed${NC}"
else
    echo "${BLUE}Installing Codex CLI...${NC}"
    npm install -g @openai/codex
    if command -v codex >/dev/null 2>&1; then
        echo "  ${GREEN}✓ Codex CLI installed${NC}"
    else
        echo "${YELLOW}Warning: Codex CLI installed but not found on PATH${NC}"
        echo "You may need to restart your terminal or add npm global bin to PATH."
        echo "  npm global bin: ${BLUE}$NPM_GLOBAL_BIN${NC}"
    fi
fi

# Setup ~/.codex directory
echo ""
echo "${BLUE}Configuring Codex CLI...${NC}"
CODEX_DIR="$HOME/.codex"
mkdir -p "$CODEX_DIR"

# Backup existing config.toml
if [ -f "$CODEX_DIR/config.toml" ]; then
    cp "$CODEX_DIR/config.toml" "$CODEX_DIR/config.toml.backup.$(date +%Y%m%d%H%M%S)"
    echo "  ${YELLOW}Backed up: ~/.codex/config.toml${NC}"
fi

# Write config.toml
cat > "$CODEX_DIR/config.toml" << TOML_EOF
model = "$CODEX_MODEL"
model_provider = "claudible"
model_catalog_json = "~/.codex/models.json"

[model_providers.claudible]
name = "Claudible"
base_url = "$ENDPOINT_URL/v1"
experimental_bearer_token = "$API_KEY"
wire_api = "responses"

[features]
apps = false
TOML_EOF
echo "  ${GREEN}✓ Written ~/.codex/config.toml${NC}"

# Write models.json from endpoint's codexModels list
CODEX_MODELS_JSON=$(echo "$ENDPOINTS" | jq -r ".[$IDX].codexModels // []")
echo "$CODEX_MODELS_JSON" | jq '{models: [to_entries[] | .value as $m | .key as $i | {slug: $m, display_name: $m, description: "\($m) - cung cấp bởi Claudible", default_reasoning_level: "medium", supported_reasoning_levels: [{effort:"low",description:"Minimal reasoning"},{effort:"medium",description:"Balanced reasoning"},{effort:"high",description:"Deep reasoning"},{effort:"xhigh",description:"Maximum reasoning"}], shell_type:"shell_command", visibility:"list", supported_in_api:true, priority:($i+1), availability_nux:null, upgrade:null, base_instructions:"", model_messages:null, supports_reasoning_summaries:false, default_reasoning_summary:"auto", support_verbosity:true, default_verbosity:null, apply_patch_tool_type:null, web_search_tool_type:"text", truncation_policy:{mode:"tokens",limit:200000}, supports_parallel_tool_calls:true, supports_image_detail_original:false, context_window:200000, auto_compact_token_limit:null, effective_context_window_percent:95, experimental_supported_tools:[], input_modalities:["text","image"], supports_search_tool:false}]}' > "$CODEX_DIR/models.json"
echo "  ${GREEN}✓ Written ~/.codex/models.json${NC}"

# Write auth.json only if missing or empty (preserve existing auth state)
if [ ! -f "$CODEX_DIR/auth.json" ] || [ ! -s "$CODEX_DIR/auth.json" ]; then
    echo '{}' > "$CODEX_DIR/auth.json"
    echo "  ${GREEN}✓ Written ~/.codex/auth.json${NC}"
else
    echo "  ${GREEN}✓ Kept existing ~/.codex/auth.json${NC}"
fi

# Remove models cache to prevent stale OpenAI models
if [ -f "$CODEX_DIR/models_cache.json" ]; then
    rm -f "$CODEX_DIR/models_cache.json"
    echo "  ${GREEN}✓ Removed ~/.codex/models_cache.json${NC}"
fi

echo ""
echo "${GREEN}================================${NC}"
echo "${GREEN}  Configuration Complete!${NC}"
echo "${GREEN}================================${NC}"
echo ""
echo "Codex CLI is now configured to use Claudible:"
echo "  Endpoint: ${BLUE}$ENDPOINT_URL/v1${NC}"
echo "  API Key:  ${BLUE}${MASKED_KEY}...${NC}"
echo "  Model:    ${BLUE}$CODEX_MODEL${NC}"
echo ""
echo "${YELLOW}Next steps:${NC}"
echo "  Run: ${BLUE}codex${NC}"
echo ""
