#!/usr/bin/env bash
set -euo pipefail

# Version (updated by scripts/bump-version.sh)
CCS_VERSION="4.1.4"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly CONFIG_FILE="${CCS_CONFIG:-$HOME/.ccs/config.json}"
readonly PROFILES_JSON="$HOME/.ccs/profiles.json"
readonly INSTANCES_DIR="$HOME/.ccs/instances"

# Determine dependency location (git vs installed)
# Git: lib/ccs and dependencies are in same dir (lib/)
# Installed: lib/ccs is symlinked from ~/.local/bin/ccs, dependencies in ~/.ccs/lib/
if [[ -f "$SCRIPT_DIR/error-codes.sh" ]]; then
  # Git install - files in same directory
  DEP_DIR="$SCRIPT_DIR"
else
  # Standalone install - files in ~/.ccs/lib/
  DEP_DIR="$HOME/.ccs/lib"
fi

# Source error codes
source "$DEP_DIR/error-codes.sh"

# Source progress indicators
source "$DEP_DIR/progress-indicator.sh"

# Source interactive prompts
source "$DEP_DIR/prompt.sh"

# --- Color/Format Functions ---
setup_colors() {
  # Enable colors if: FORCE_COLOR set OR (TTY detected AND NO_COLOR not set) OR (TERM supports colors AND NO_COLOR not set)
  if [[ -n "${FORCE_COLOR:-}" ]] || \
     ([[ -t 1 || -t 2 ]] && [[ -z "${NO_COLOR:-}" ]]) || \
     ([[ -n "${TERM:-}" && "${TERM}" != "dumb" ]] && [[ -z "${NO_COLOR:-}" ]]); then
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    CYAN='\033[0;36m'
    BOLD='\033[1m'
    RESET='\033[0m'
  else
    RED='' GREEN='' YELLOW='' CYAN='' BOLD='' RESET=''
  fi
}

msg_error() {
  echo "" >&2
  echo -e "${RED}${BOLD}=============================================${RESET}" >&2
  echo -e "${RED}${BOLD}  ERROR${RESET}" >&2
  echo -e "${RED}${BOLD}=============================================${RESET}" >&2
  echo "" >&2
  echo -e "${RED}$1${RESET}" >&2
  echo "" >&2
}

# Enhanced error message with error codes
show_enhanced_error() {
  local error_code="$1"
  local short_msg="$2"
  local context="${3:-}"
  local suggestions="${4:-}"

  echo "" >&2
  echo -e "${RED}[X] $short_msg${RESET}" >&2
  echo "" >&2

  [[ -n "$context" ]] && {
    echo -e "$context" >&2
    echo "" >&2
  }

  [[ -n "$suggestions" ]] && {
    echo -e "${YELLOW}Solutions:${RESET}" >&2
    echo -e "$suggestions" >&2
    echo "" >&2
  }

  echo -e "${YELLOW}Error: $error_code${RESET}" >&2
  echo -e "${YELLOW}$(get_error_doc_url "$error_code")${RESET}" >&2
  echo "" >&2
}

# Calculate Levenshtein distance between two strings
levenshtein_distance() {
  local a="$1"
  local b="$2"
  local len_a=${#a}
  local len_b=${#b}

  # Return early for empty strings
  [[ $len_a -eq 0 ]] && { echo "$len_b"; return; }
  [[ $len_b -eq 0 ]] && { echo "$len_a"; return; }

  # Initialize matrix using associative array
  declare -A matrix

  # Initialize first row and column
  for ((j=0; j<=len_a; j++)); do
    matrix[0,$j]=$j
  done
  for ((i=0; i<=len_b; i++)); do
    matrix[$i,0]=$i
  done

  # Fill matrix
  for ((i=1; i<=len_b; i++)); do
    for ((j=1; j<=len_a; j++)); do
      if [[ "${a:j-1:1}" == "${b:i-1:1}" ]]; then
        matrix[$i,$j]=${matrix[$((i-1)),$((j-1))]}
      else
        local sub=${matrix[$((i-1)),$((j-1))]}
        local ins=${matrix[$i,$((j-1))]}
        local del=${matrix[$((i-1)),$j]}
        local min=$sub
        [[ $ins -lt $min ]] && min=$ins
        [[ $del -lt $min ]] && min=$del
        matrix[$i,$j]=$((min + 1))
      fi
    done
  done

  echo "${matrix[$len_b,$len_a]}"
}

# Find similar strings using fuzzy matching
find_similar_strings() {
  local target="$1"
  shift
  local candidates=("$@")
  local max_distance=2
  local target_lower="${target,,}"

  declare -A distances
  local matches=()

  # Calculate distances
  for candidate in "${candidates[@]}"; do
    local candidate_lower="${candidate,,}"
    local dist=$(levenshtein_distance "$target_lower" "$candidate_lower")
    if [[ $dist -le $max_distance && $dist -gt 0 ]]; then
      distances["$candidate"]=$dist
      matches+=("$candidate")
    fi
  done

  # Sort by distance (simple bubble sort for small arrays)
  for ((i=0; i<${#matches[@]}; i++)); do
    for ((j=i+1; j<${#matches[@]}; j++)); do
      if [[ ${distances[${matches[i]}]} -gt ${distances[${matches[j]}]} ]]; then
        local temp="${matches[i]}"
        matches[i]="${matches[j]}"
        matches[j]="$temp"
      fi
    done
  done

  # Return first 3 matches
  for ((i=0; i<${#matches[@]} && i<3; i++)); do
    echo "${matches[i]}"
  done
}

show_help() {
  echo -e "${BOLD}CCS (Claude Code Switch) - Instant profile switching for Claude CLI${RESET}"
  echo ""
  echo -e "${CYAN}Usage:${RESET}"
  echo -e "  ${YELLOW}ccs${RESET} [profile] [claude-args...]"
  echo -e "  ${YELLOW}ccs auth${RESET} <command> [options]"
  echo -e "  ${YELLOW}ccs${RESET} [flags]"
  echo ""
  echo -e "${CYAN}Description:${RESET}"
  echo -e "  Switch between multiple Claude accounts and alternative models"
  echo -e "  (GLM, Kimi) instantly. Run different Claude CLI sessions concurrently"
  echo -e "  with auto-recovery. Zero downtime."
  echo ""
  echo -e "${CYAN}Model Switching:${RESET}"
  echo -e "  ${YELLOW}ccs${RESET}                         Use default Claude account"
  echo -e "  ${YELLOW}ccs glm${RESET}                     Switch to GLM 4.6 model"
  echo -e "  ${YELLOW}ccs glmt${RESET}                    Switch to GLM with thinking mode"
  echo -e "  ${YELLOW}ccs kimi${RESET}                    Switch to Kimi for Coding"
  echo -e "  ${YELLOW}ccs glm${RESET} \"debug this code\"   Use GLM and run command"
  echo ""
  echo -e "${CYAN}Account Management:${RESET}"
  echo -e "  ${YELLOW}ccs auth --help${RESET}             Manage multiple Claude accounts"
  echo ""
  echo -e "${CYAN}Delegation (inside Claude Code CLI):${RESET}"
  echo -e "  ${YELLOW}/ccs:glm \"task\"${RESET}             Delegate to GLM-4.6 for simple tasks"
  echo -e "  ${YELLOW}/ccs:kimi \"task\"${RESET}            Delegate to Kimi for long context"
  echo -e "  Save tokens by delegating simple tasks to cost-optimized models"
  echo ""
  echo -e "${CYAN}Diagnostics:${RESET}"
  echo -e "  ${YELLOW}ccs doctor${RESET}                  Run health check and diagnostics"
  echo ""
  echo -e "${CYAN}Flags:${RESET}"
  echo -e "  ${YELLOW}-h, --help${RESET}                  Show this help message"
  echo -e "  ${YELLOW}-v, --version${RESET}               Show version and installation info"
  echo -e "  ${YELLOW}--shell-completion${RESET}          Install shell auto-completion"
  echo ""
  echo -e "${CYAN}Configuration:${RESET}"
  echo -e "  Config:    ~/.ccs/config.json"
  echo -e "  Profiles:  ~/.ccs/profiles.json"
  echo -e "  Instances: ~/.ccs/instances/"
  echo -e "  Settings:  ~/.ccs/*.settings.json"
  echo ""
  echo -e "${CYAN}Shared Data:${RESET}"
  echo -e "  Commands:  ~/.ccs/shared/commands/"
  echo -e "  Skills:    ~/.ccs/shared/skills/"
  echo -e "  Note: Commands, skills, and agents are symlinked across all profiles"
  echo ""
  echo -e "${CYAN}Examples:${RESET}"
  echo -e "  ${YELLOW}\$ ccs${RESET}                        # Use default account"
  echo -e "  ${YELLOW}\$ ccs glm \"implement API\"${RESET}    # Cost-optimized model"
  echo ""
  echo -e "  For more: ${CYAN}https://github.com/kaitranntt/ccs#usage${RESET}"
  echo ""
  echo -e "${YELLOW}Uninstall:${RESET}"
  echo "  npm:          npm uninstall -g @kaitranntt/ccs"
  echo "  macOS/Linux:  curl -fsSL ccs.kaitran.ca/uninstall | bash"
  echo "  Windows:      irm ccs.kaitran.ca/uninstall | iex"
  echo ""
  echo -e "${CYAN}Documentation:${RESET}"
  echo -e "  GitHub:  ${CYAN}https://github.com/kaitranntt/ccs${RESET}"
  echo -e "  Docs:    https://github.com/kaitranntt/ccs/blob/main/README.md"
  echo ""
  echo -e "${CYAN}License:${RESET} MIT"
}

setup_colors

# Check dependencies early
command -v jq &>/dev/null || {
  msg_error "jq required but not installed. Install: brew install jq (macOS) or apt install jq (Ubuntu)"
  exit 1
}

# --- Auto-Recovery Functions ---

ensure_ccs_directory() {
  [[ -d "$HOME/.ccs" ]] && return 0

  mkdir -p "$HOME/.ccs" 2>/dev/null || {
    msg_error "Cannot create ~/.ccs/ directory. Check permissions."
    return 1
  }

  echo "[i] Auto-recovery: Created ~/.ccs/ directory"
  return 0
}

ensure_config_json() {
  local config_file="$HOME/.ccs/config.json"

  # Check if exists and valid
  if [[ -f "$config_file" ]]; then
    jq empty "$config_file" 2>/dev/null && return 0

    # Corrupted - backup and recreate
    local backup_file="${config_file}.backup.$(date +%s)"
    mv "$config_file" "$backup_file" 2>/dev/null
    echo "[i] Auto-recovery: Backed up corrupted config.json"
  fi

  # Create default config
  cat > "$config_file" <<'EOF'
{
  "profiles": {
    "glm": "~/.ccs/glm.settings.json",
    "kimi": "~/.ccs/kimi.settings.json",
    "default": "~/.claude/settings.json"
  }
}
EOF

  echo "[i] Auto-recovery: Created ~/.ccs/config.json"
  return 0
}

ensure_claude_settings() {
  local claude_dir="$HOME/.claude"
  local settings_file="$claude_dir/settings.json"

  # Create ~/.claude/ if missing
  if [[ ! -d "$claude_dir" ]]; then
    mkdir -p "$claude_dir" 2>/dev/null || return 1
    echo "[i] Auto-recovery: Created ~/.claude/ directory"
  fi

  # Create settings.json if missing
  if [[ ! -f "$settings_file" ]]; then
    echo '{}' > "$settings_file" 2>/dev/null || return 1
    echo "[i] Auto-recovery: Created ~/.claude/settings.json"
    echo "[i] Next step: Run 'claude /login' to authenticate"
    return 0
  fi

  return 0
}

# Run auto-recovery
auto_recover() {
  ensure_ccs_directory || return 1
  ensure_config_json || return 1
  ensure_claude_settings || return 1
  return 0
}

# --- Doctor Command ---

doctor_check() {
  local check_name="$1"
  local status="$2"  # success, warning, error
  local message="${3:-}"

  case "$status" in
    success)
      echo -e "${GREEN}[OK]${RESET} $check_name"
      ;;
    warning)
      echo -e "${YELLOW}[!]${RESET} $check_name${message:+: $message}"
      ;;
    error)
      echo -e "${RED}[X]${RESET} $check_name: $message"
      ;;
  esac
}

doctor_run() {
  echo -e "${CYAN}Running CCS Health Check...${RESET}"
  echo ""

  local has_errors=false
  local total_checks=9
  local current_check=0

  # Check Claude CLI
  current_check=$((current_check + 1))
  show_progress_step $current_check $total_checks "Checking Claude CLI"
  if command -v "$(detect_claude_cli)" &>/dev/null; then
    clear_progress
    doctor_check "Claude CLI" "success"
  else
    clear_progress
    doctor_check "Claude CLI" "error" "Not found in PATH"
    has_errors=true
  fi

  # Check ~/.ccs/
  current_check=$((current_check + 1))
  show_progress_step $current_check $total_checks "Checking CCS directory"
  if [[ -d "$HOME/.ccs" ]]; then
    clear_progress
    doctor_check "CCS Directory" "success"
  else
    clear_progress
    doctor_check "CCS Directory" "error" "~/.ccs/ not found"
    has_errors=true
  fi

  # Check config.json
  current_check=$((current_check + 1))
  show_progress_step $current_check $total_checks "Checking config.json"
  if [[ -f "$CONFIG_FILE" ]]; then
    if jq empty "$CONFIG_FILE" 2>/dev/null; then
      clear_progress
      doctor_check "config.json" "success"
    else
      clear_progress
      doctor_check "config.json" "error" "Invalid JSON"
      has_errors=true
    fi
  else
    clear_progress
    doctor_check "config.json" "error" "Not found"
    has_errors=true
  fi

  # Check glm.settings.json
  current_check=$((current_check + 1))
  show_progress_step $current_check $total_checks "Checking glm.settings.json"
  local glm_file="$HOME/.ccs/glm.settings.json"
  if [[ -f "$glm_file" ]]; then
    if jq empty "$glm_file" 2>/dev/null; then
      clear_progress
      doctor_check "glm.settings.json" "success"
    else
      clear_progress
      doctor_check "glm.settings.json" "error" "Invalid JSON"
      has_errors=true
    fi
  else
    clear_progress
    doctor_check "glm.settings.json" "error" "Not found"
    has_errors=true
  fi

  # Check kimi.settings.json
  current_check=$((current_check + 1))
  show_progress_step $current_check $total_checks "Checking kimi.settings.json"
  local kimi_file="$HOME/.ccs/kimi.settings.json"
  if [[ -f "$kimi_file" ]]; then
    if jq empty "$kimi_file" 2>/dev/null; then
      clear_progress
      doctor_check "kimi.settings.json" "success"
    else
      clear_progress
      doctor_check "kimi.settings.json" "error" "Invalid JSON"
      has_errors=true
    fi
  else
    clear_progress
    doctor_check "kimi.settings.json" "error" "Not found"
    has_errors=true
  fi

  # Check ~/.claude/settings.json
  current_check=$((current_check + 1))
  show_progress_step $current_check $total_checks "Checking Claude settings"
  if [[ -f "$HOME/.claude/settings.json" ]]; then
    if jq empty "$HOME/.claude/settings.json" 2>/dev/null; then
      clear_progress
      doctor_check "Claude Settings" "success"
    else
      clear_progress
      doctor_check "Claude Settings" "warning" "Invalid JSON"
    fi
  else
    clear_progress
    doctor_check "Claude Settings" "warning" "Not found - run 'claude /login'"
  fi

  # Check profiles
  current_check=$((current_check + 1))
  show_progress_step $current_check $total_checks "Checking profiles"
  if [[ -f "$CONFIG_FILE" ]]; then
    local profile_count=$(jq -r '.profiles | length' "$CONFIG_FILE" 2>/dev/null || echo "0")
    clear_progress
    doctor_check "Profiles" "success" "($profile_count configured)"
  fi

  # Check instances
  current_check=$((current_check + 1))
  show_progress_step $current_check $total_checks "Checking instances"
  if [[ -d "$INSTANCES_DIR" ]]; then
    local instance_count=$(find "$INSTANCES_DIR" -maxdepth 1 -type d 2>/dev/null | wc -l)
    instance_count=$((instance_count - 1))  # Exclude parent dir
    clear_progress
    doctor_check "Instances" "success" "($instance_count account profiles)"
  else
    clear_progress
    doctor_check "Instances" "success" "(no account profiles)"
  fi

  # Check permissions
  current_check=$((current_check + 1))
  show_progress_step $current_check $total_checks "Checking permissions"
  local test_file="$HOME/.ccs/.permission-test"
  if echo "test" > "$test_file" 2>/dev/null; then
    rm -f "$test_file" 2>/dev/null
    clear_progress
    doctor_check "Permissions" "success"
  else
    clear_progress
    doctor_check "Permissions" "error" "Cannot write to ~/.ccs/"
    has_errors=true
  fi

  # Summary
  echo ""
  echo -e "${CYAN}═══════════════════════════════════════════${RESET}"
  if $has_errors; then
    echo -e "${RED}Status: Installation has errors${RESET}"
    echo "Run: npm install -g @kaitranntt/ccs --force"
  else
    echo -e "${GREEN}✓ All checks passed!${RESET}"
  fi
  echo ""

  $has_errors && exit 1 || exit 0
}

# --- Claude CLI Detection Logic ---

detect_claude_cli() {
  echo "${CCS_CLAUDE_PATH:-claude}"
}

show_claude_not_found_error() {
  msg_error "Claude CLI not found in PATH

CCS requires Claude CLI to be installed and available in your PATH.

Solutions:
  1. Install Claude CLI:
     https://docs.claude.com/en/docs/claude-code/installation

  2. Verify installation:
     command -v claude

  3. If installed but not in PATH, add it:
     # Find Claude installation
     which claude

     # Or set custom path
     export CCS_CLAUDE_PATH='/path/to/claude'

Restart your terminal after installation."
}

show_version() {
  echo -e "${BOLD}CCS (Claude Code Switch) v${CCS_VERSION}${RESET}"
  echo ""
  echo -e "${CYAN}Installation:${RESET}"

  # Simple location - just show what 'command -v' returns
  local location=$(command -v ccs 2>/dev/null || echo "(not installed)")
  echo -e "  ${CYAN}Location:${RESET} ${location}"

  # Simple config display
  local config="${CCS_CONFIG:-$HOME/.ccs/config.json}"
  echo -e "  ${CYAN}Config:${RESET} ${config}"

  # Delegation status
  local delegation_rules="$HOME/.ccs/delegation-rules.json"
  if [[ -f "$delegation_rules" ]]; then
    echo -e "  ${CYAN}Delegation:${RESET} Enabled"

    # Check which profiles are delegation-ready
    local ready_profiles=()
    for profile in glm kimi; do
      local settings_file="$HOME/.ccs/profiles/$profile/settings.json"
      if [[ -f "$settings_file" ]]; then
        # Check if API key is configured (not a placeholder)
        local api_key=$(jq -r '.env.ANTHROPIC_AUTH_TOKEN // empty' "$settings_file" 2>/dev/null)
        if [[ -n "$api_key" ]] && [[ ! "$api_key" =~ YOUR_.*_API_KEY_HERE ]]; then
          ready_profiles+=("$profile")
        fi
      fi
    done

    if [[ ${#ready_profiles[@]} -gt 0 ]]; then
      echo -e "  ${CYAN}Ready:${RESET} ${ready_profiles[*]}"
    else
      echo -e "  ${CYAN}Ready:${RESET} None (configure profiles first)"
    fi
  else
    echo -e "  ${CYAN}Delegation:${RESET} Not configured"
  fi
  echo ""

  echo -e "${CYAN}Documentation:${RESET} https://github.com/kaitranntt/ccs"
  echo -e "${CYAN}License:${RESET} MIT"
  echo ""
  echo -e "${YELLOW}Run 'ccs --help' for usage information${RESET}"
}

# --- Profile Registry Functions (Phase 4) ---

# Initialize empty registry if missing
init_profiles_json() {
  [[ -f "$PROFILES_JSON" ]] && return 0

  local init_data='{
  "version": "2.0.0",
  "profiles": {},
  "default": null
}'

  echo "$init_data" > "$PROFILES_JSON"
  chmod 0600 "$PROFILES_JSON"
}

# Read entire profiles.json
read_profiles_json() {
  init_profiles_json
  cat "$PROFILES_JSON"
}

# Write entire profiles.json (atomic)
write_profiles_json() {
  local content="$1"
  local temp_file="$PROFILES_JSON.tmp"

  echo "$content" > "$temp_file" || {
    msg_error "Failed to write profiles registry"
    return 1
  }

  chmod 0600 "$temp_file"
  mv "$temp_file" "$PROFILES_JSON" || {
    rm -f "$temp_file"
    msg_error "Failed to update profiles registry"
    return 1
  }
}

# Check if profile exists
profile_exists() {
  local profile_name="$1"
  init_profiles_json

  local exists=$(jq -r ".profiles.\"$profile_name\" // empty" "$PROFILES_JSON")
  [[ -n "$exists" ]]
}

# Create new profile
register_profile() {
  local profile_name="$1"
  local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")

  init_profiles_json

  # Check if exists
  profile_exists "$profile_name" && {
    msg_error "Profile already exists: $profile_name"
    return 1
  }

  # Read current data
  local data=$(read_profiles_json)

  # Add new profile
  data=$(echo "$data" | jq \
    --arg name "$profile_name" \
    --arg timestamp "$timestamp" \
    '.profiles[$name] = {
      "type": "account",
      "created": $timestamp,
      "last_used": null
    }')

  # Note: No longer auto-set as default
  # Users must explicitly run: ccs auth default <profile>
  # Default always stays on implicit 'default' profile (uses ~/.claude/)

  write_profiles_json "$data"
}

# Delete profile
unregister_profile() {
  local profile_name="$1"

  init_profiles_json

  profile_exists "$profile_name" || return 0  # Idempotent

  local data=$(read_profiles_json)

  # Remove profile
  data=$(echo "$data" | jq --arg name "$profile_name" 'del(.profiles[$name])')

  # Update default if it was the deleted profile
  local current_default=$(echo "$data" | jq -r '.default // empty')
  if [[ "$current_default" == "$profile_name" ]]; then
    # Set to first remaining profile or null
    local first_profile=$(echo "$data" | jq -r '.profiles | keys[0] // empty')
    data=$(echo "$data" | jq --arg first "$first_profile" '
      .default = if $first != "" then $first else null end
    ')
  fi

  write_profiles_json "$data"
}

# Update last_used timestamp
touch_profile() {
  local profile_name="$1"
  local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")

  profile_exists "$profile_name" || return 0  # Silent fail if not exists

  local data=$(read_profiles_json)

  data=$(echo "$data" | jq \
    --arg name "$profile_name" \
    --arg timestamp "$timestamp" \
    '.profiles[$name].last_used = $timestamp')

  write_profiles_json "$data"
}

# Get default profile
get_default_profile() {
  init_profiles_json
  jq -r '.default // empty' "$PROFILES_JSON"
}

# Set default profile
set_default_profile() {
  local profile_name="$1"

  profile_exists "$profile_name" || {
    msg_error "Profile not found: $profile_name"
    return 1
  }

  local data=$(read_profiles_json)
  data=$(echo "$data" | jq --arg name "$profile_name" '.default = $name')

  write_profiles_json "$data"
}

# --- Instance Management Functions (Phase 2) ---

# Sanitize profile name for filesystem
sanitize_profile_name() {
  local name="$1"
  # Replace unsafe chars with dash, lowercase
  echo "$name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_-]/-/g'
}

# Link shared directories (Phase 1: Shared Global Data)
link_shared_directories() {
  local instance_path="$1"
  local shared_dir="$HOME/.ccs/shared"

  # Ensure shared directories exist
  mkdir -p "$shared_dir"/{commands,skills,agents}

  # Create symlinks (remove existing first if present)
  for dir in commands skills agents; do
    local link_path="$instance_path/$dir"
    local target_path="$shared_dir/$dir"

    # Remove existing directory/link
    [[ -e "$link_path" ]] && rm -rf "$link_path"

    # Create symlink
    ln -sf "$target_path" "$link_path"
  done
}

# Migrate to shared structure (Phase 1: Auto-migration)
migrate_to_shared_structure() {
  local shared_dir="$HOME/.ccs/shared"

  # Check if migration is needed (shared dirs exist but are empty)
  if [[ -d "$shared_dir" ]]; then
    local needs_migration=false
    for dir in commands skills agents; do
      if [[ ! -d "$shared_dir/$dir" ]] || [[ -z "$(ls -A "$shared_dir/$dir" 2>/dev/null)" ]]; then
        needs_migration=true
        break
      fi
    done

    [[ "$needs_migration" == "false" ]] && return 0
  fi

  # Create shared directory
  mkdir -p "$shared_dir"/{commands,skills,agents}

  # Copy from ~/.claude/ (actual Claude CLI directory)
  local claude_dir="$HOME/.claude"

  if [[ -d "$claude_dir" ]]; then
    # Copy commands to shared (if exists)
    [[ -d "$claude_dir/commands" ]] && \
      cp -r "$claude_dir/commands"/* "$shared_dir/commands/" 2>/dev/null || true

    # Copy skills to shared (if exists)
    [[ -d "$claude_dir/skills" ]] && \
      cp -r "$claude_dir/skills"/* "$shared_dir/skills/" 2>/dev/null || true

    # Copy agents to shared (if exists)
    [[ -d "$claude_dir/agents" ]] && \
      cp -r "$claude_dir/agents"/* "$shared_dir/agents/" 2>/dev/null || true
  fi

  # Update all instances to use symlinks
  for instance_path in "$INSTANCES_DIR"/*; do
    [[ -d "$instance_path" ]] || continue
    link_shared_directories "$instance_path"
  done

  echo "[OK] Migrated to shared structure"
}

# Initialize new instance directory
initialize_instance() {
  local instance_path="$1"

  # Create base directory
  mkdir -m 0700 -p "$instance_path"

  # Create subdirectories (profile-specific only)
  local subdirs=(session-env todos logs file-history shell-snapshots debug .anthropic)
  for dir in "${subdirs[@]}"; do
    mkdir -m 0700 -p "$instance_path/$dir"
  done

  # Symlink shared directories
  link_shared_directories "$instance_path"

  # Copy global configs (optional)
  copy_global_configs "$instance_path"
}

# Validate instance structure (auto-repair)
validate_instance() {
  local instance_path="$1"
  local required_dirs=(session-env todos logs file-history shell-snapshots debug .anthropic)

  for dir in "${required_dirs[@]}"; do
    if [[ ! -d "$instance_path/$dir" ]]; then
      mkdir -m 0700 -p "$instance_path/$dir"
    fi
  done
}

# Copy global Claude configs to instance
copy_global_configs() {
  local instance_path="$1"
  local global_claude="$HOME/.claude"

  # Copy settings.json only (commands/skills are now symlinked to shared/)
  [[ -f "$global_claude/settings.json" ]] && \
    cp "$global_claude/settings.json" "$instance_path/settings.json" 2>/dev/null || true
}

# Ensure instance exists (lazy initialization)
ensure_instance() {
  local profile_name="$1"
  local safe_name=$(sanitize_profile_name "$profile_name")
  local instance_path="$INSTANCES_DIR/$safe_name"

  # Create if missing
  if [[ ! -d "$instance_path" ]]; then
    initialize_instance "$instance_path"
  fi

  # Validate structure
  validate_instance "$instance_path"

  echo "$instance_path"
}

# --- Profile Detection Logic (Phase 1) ---

# List available profiles for error messages
# Get all profile names (for fuzzy matching)
get_all_profile_names() {
  local names=()

  # Settings-based profiles
  if [[ -f "$CONFIG_FILE" ]]; then
    while IFS= read -r name; do
      names+=("$name")
    done < <(jq -r '.profiles | keys[]' "$CONFIG_FILE" 2>/dev/null || true)
  fi

  # Account-based profiles
  if [[ -f "$PROFILES_JSON" ]]; then
    while IFS= read -r name; do
      names+=("$name")
    done < <(jq -r '.profiles | keys[]' "$PROFILES_JSON" 2>/dev/null || true)
  fi

  printf '%s\n' "${names[@]}"
}

list_available_profiles() {
  local lines=()

  # Settings-based profiles
  if [[ -f "$CONFIG_FILE" ]]; then
    local settings_profiles=$(jq -r '.profiles | keys[]' "$CONFIG_FILE" 2>/dev/null || true)
    if [[ -n "$settings_profiles" ]]; then
      lines+=("Settings-based profiles (GLM, Kimi, etc.):")
      while IFS= read -r name; do
        lines+=("  - $name")
      done <<< "$settings_profiles"
    fi
  fi

  # Account-based profiles
  if [[ -f "$PROFILES_JSON" ]]; then
    local account_profiles=$(jq -r '.profiles | keys[]' "$PROFILES_JSON" 2>/dev/null || true)
    local default_profile=$(jq -r '.default // empty' "$PROFILES_JSON" 2>/dev/null || true)

    if [[ -n "$account_profiles" ]]; then
      lines+=("Account-based profiles:")
      while IFS= read -r name; do
        local is_default=""
        [[ "$name" == "$default_profile" ]] && is_default=" [DEFAULT]"
        lines+=("  - $name$is_default")
      done <<< "$account_profiles"
    fi
  fi

  if [[ ${#lines[@]} -eq 0 ]]; then
    echo "  (no profiles configured)"
    echo "  Run \"ccs auth create <profile>\" to create your first account profile."
  else
    printf '%s\n' "${lines[@]}"
  fi
}

# Detect profile type and return info
# Sets global variables: PROFILE_TYPE, PROFILE_PATH/INSTANCE_PATH
detect_profile_type() {
  local profile_name="$1"

  # Special case: 'default' resolves to default profile
  if [[ "$profile_name" == "default" ]]; then
    # Check account-based default first
    if [[ -f "$PROFILES_JSON" ]]; then
      local default_account=$(jq -r '.default // empty' "$PROFILES_JSON" 2>/dev/null || true)
      if [[ -n "$default_account" ]] && profile_exists "$default_account"; then
        PROFILE_TYPE="account"
        PROFILE_NAME="$default_account"
        return 0
      fi
    fi

    # Check settings-based default
    if [[ -f "$CONFIG_FILE" ]]; then
      local default_settings=$(jq -r '.profiles.default // empty' "$CONFIG_FILE" 2>/dev/null || true)
      if [[ -n "$default_settings" ]]; then
        PROFILE_TYPE="settings"
        PROFILE_PATH="$default_settings"
        PROFILE_NAME="default"
        return 0
      fi
    fi

    # No default configured, use Claude's defaults
    PROFILE_TYPE="default"
    PROFILE_NAME="default"
    return 0
  fi

  # Priority 1: Check settings-based profiles (backward compatibility)
  if [[ -f "$CONFIG_FILE" ]]; then
    local settings_path=$(jq -r ".profiles.\"$profile_name\" // empty" "$CONFIG_FILE" 2>/dev/null || true)
    if [[ -n "$settings_path" ]]; then
      PROFILE_TYPE="settings"
      PROFILE_PATH="$settings_path"
      PROFILE_NAME="$profile_name"
      return 0
    fi
  fi

  # Priority 2: Check account-based profiles
  if [[ -f "$PROFILES_JSON" ]] && profile_exists "$profile_name"; then
    PROFILE_TYPE="account"
    PROFILE_NAME="$profile_name"
    return 0
  fi

  # Not found
  PROFILE_TYPE="error"
  return 1
}

# --- Auth Commands (Phase 3) ---

auth_help() {
  echo -e "${BOLD}CCS Account Management${RESET}"
  echo ""
  echo -e "${CYAN}Usage:${RESET}"
  echo -e "  ${YELLOW}ccs auth${RESET} <command> [options]"
  echo ""
  echo -e "${CYAN}Commands:${RESET}"
  echo -e "  ${YELLOW}create <profile>${RESET}        Create new profile and login"
  echo -e "  ${YELLOW}list${RESET}                   List all saved profiles"
  echo -e "  ${YELLOW}show <profile>${RESET}         Show profile details"
  echo -e "  ${YELLOW}remove <profile>${RESET}       Remove saved profile"
  echo -e "  ${YELLOW}default <profile>${RESET}      Set default profile"
  echo ""
  echo -e "${CYAN}Examples:${RESET}"
  echo -e "  ${YELLOW}ccs auth create work${RESET}                     # Create & login to work profile"
  echo -e "  ${YELLOW}ccs auth default work${RESET}                    # Set work as default"
  echo -e "  ${YELLOW}ccs auth list${RESET}                            # List all profiles"
  echo -e "  ${YELLOW}ccs work \"review code\"${RESET}                   # Use work profile"
  echo -e "  ${YELLOW}ccs \"review code\"${RESET}                        # Use default profile"
  echo ""
  echo -e "${CYAN}Options:${RESET}"
  echo -e "  ${YELLOW}--force${RESET}                   Allow overwriting existing profile (create)"
  echo -e "  ${YELLOW}--yes, -y${RESET}                 Skip confirmation prompts (remove)"
  echo -e "  ${YELLOW}--json${RESET}                    Output in JSON format (list, show)"
  echo -e "  ${YELLOW}--verbose${RESET}                 Show additional details (list)"
  echo ""
  echo -e "${CYAN}Note:${RESET}"
  echo -e "  By default, ${YELLOW}ccs${RESET} uses Claude CLI defaults from ~/.claude/"
  echo -e "  Use ${YELLOW}ccs auth default <profile>${RESET} to change the default profile."
  echo ""
}

auth_create() {
  local profile_name=""
  local force=false

  # Parse arguments
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --force) force=true ;;
      -*) msg_error "Unknown option: $1"; return 1 ;;
      *) profile_name="$1" ;;
    esac
    shift
  done

  # Validate profile name
  [[ -z "$profile_name" ]] && {
    msg_error "Profile name is required"
    echo ""
    echo "Usage: ${YELLOW}ccs auth create <profile> [--force]${RESET}"
    return 1
  }

  # Check if exists
  if ! $force && profile_exists "$profile_name"; then
    msg_error "Profile already exists: $profile_name"
    echo "Use ${YELLOW}--force${RESET} to overwrite"
    return 1
  fi

  # Create instance
  echo "[i] Creating profile: $profile_name"
  local instance_path=$(ensure_instance "$profile_name")
  echo "[i] Instance directory: $instance_path"
  echo ""

  # Register profile
  register_profile "$profile_name"

  # Launch Claude for login
  echo -e "${YELLOW}[i] Starting Claude in isolated instance...${RESET}"
  echo -e "${YELLOW}[i] You will be prompted to login with your account.${RESET}"
  echo ""

  CLAUDE_CONFIG_DIR="$instance_path" $(detect_claude_cli) || {
    msg_error "Login failed or cancelled"
    echo "To retry: ${YELLOW}ccs auth create $profile_name --force${RESET}"
    return 1
  }

  echo ""
  echo -e "${GREEN}[OK] Profile created successfully${RESET}"
  echo ""
  echo "  Profile: $profile_name"
  echo "  Instance: $instance_path"
  echo ""
  echo "Usage:"
  echo "  ${YELLOW}ccs $profile_name \"your prompt here\"${RESET}        # Use this specific profile"
  echo ""
  echo "To set as default (so you can use just \"ccs\"):"
  echo "  ${YELLOW}ccs auth default $profile_name${RESET}"
  echo ""
}

auth_list() {
  local verbose=false
  local json=false

  # Parse arguments
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --verbose) verbose=true ;;
      --json) json=true ;;
      *) ;;
    esac
    shift
  done

  # Read profiles.json
  [[ ! -f "$PROFILES_JSON" ]] && {
    if $json; then
      echo "{\"version\":\"$CCS_VERSION\",\"profiles\":[]}"
      return 0
    fi
    echo -e "${YELLOW}No account profiles found${RESET}"
    echo ""
    echo "To create your first profile:"
    echo "  ${YELLOW}ccs auth create <profile>${RESET}"
    return 0
  }

  local default_profile=$(jq -r '.default // empty' "$PROFILES_JSON" 2>/dev/null || true)

  # JSON output mode
  if $json; then
    jq -n \
      --arg version "$CCS_VERSION" \
      --arg default "$default_profile" \
      --argjson data "$(cat "$PROFILES_JSON")" \
      '{
        version: $version,
        profiles: [
          $data.profiles | to_entries[] | {
            name: .key,
            type: (.value.type // "account"),
            is_default: (.key == $default),
            created: .value.created,
            last_used: (.value.last_used // null),
            instance_path: ($ENV.INSTANCES_DIR + "/" + .key)
          }
        ]
      }'
    return 0
  fi

  # Human-readable output
  local profiles=$(jq -r '.profiles | keys[]' "$PROFILES_JSON" 2>/dev/null || true)

  [[ -z "$profiles" ]] && {
    echo -e "${YELLOW}No account profiles found${RESET}"
    return 0
  }

  echo -e "${BOLD}Saved Account Profiles:${RESET}"
  echo ""

  # Display profiles
  while IFS= read -r profile; do
    local is_default=false
    [[ "$profile" == "$default_profile" ]] && is_default=true

    if $is_default; then
      echo -e "${GREEN}[*] ${CYAN}$profile${GREEN} (default)${RESET}"
    else
      echo -e "[ ] ${CYAN}$profile${RESET}"
    fi

    local type=$(jq -r ".profiles.\"$profile\".type // \"account\"" "$PROFILES_JSON" 2>/dev/null || true)
    echo "    Type: $type"

    if $verbose; then
      local created=$(jq -r ".profiles.\"$profile\".created" "$PROFILES_JSON" 2>/dev/null || true)
      local last_used=$(jq -r ".profiles.\"$profile\".last_used // \"Never\"" "$PROFILES_JSON" 2>/dev/null || true)
      echo "    Created: $created"
      echo "    Last used: $last_used"
    fi

    echo ""
  done <<< "$profiles"
}

auth_show() {
  local profile_name=""
  local json=false

  # Parse arguments
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --json) json=true ;;
      -*) msg_error "Unknown option: $1"; return 1 ;;
      *) profile_name="$1" ;;
    esac
    shift
  done

  [[ -z "$profile_name" ]] && {
    msg_error "Profile name is required"
    echo "Usage: ${YELLOW}ccs auth show <profile> [--json]${RESET}"
    return 1
  }

  # Check if exists
  profile_exists "$profile_name" || {
    msg_error "Profile not found: $profile_name"
    return 1
  }

  local default_profile=$(jq -r '.default // empty' "$PROFILES_JSON" 2>/dev/null || true)
  local is_default=false
  [[ "$profile_name" == "$default_profile" ]] && is_default=true

  local type=$(jq -r ".profiles.\"$profile_name\".type // \"account\"" "$PROFILES_JSON" 2>/dev/null || true)
  local created=$(jq -r ".profiles.\"$profile_name\".created" "$PROFILES_JSON" 2>/dev/null || true)
  local last_used=$(jq -r ".profiles.\"$profile_name\".last_used // null" "$PROFILES_JSON" 2>/dev/null || true)
  local instance_path="$INSTANCES_DIR/$(sanitize_profile_name "$profile_name")"

  # Count sessions
  local session_count=0
  if [[ -d "$instance_path/session-env" ]]; then
    session_count=$(find "$instance_path/session-env" -name "*.json" 2>/dev/null | wc -l | tr -d ' ')
  fi

  # JSON output mode
  if $json; then
    jq -n \
      --arg name "$profile_name" \
      --arg type "$type" \
      --argjson is_default "$is_default" \
      --arg created "$created" \
      --arg last_used "$last_used" \
      --arg instance_path "$instance_path" \
      --argjson session_count "$session_count" \
      '{
        name: $name,
        type: $type,
        is_default: $is_default,
        created: $created,
        last_used: $last_used,
        instance_path: $instance_path,
        session_count: $session_count
      }'
    return 0
  fi

  # Human-readable output
  echo -e "${BOLD}Profile: $profile_name${RESET}"
  echo ""

  echo "  Type: $type"
  echo "  Default: $($is_default && echo "Yes" || echo "No")"
  echo "  Instance: $instance_path"
  echo "  Created: $created"
  [[ "$last_used" != "null" ]] && echo "  Last used: $last_used" || echo "  Last used: Never"
  echo ""
}

auth_remove() {
  local profile_name=""

  # Parse arguments
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --yes|-y) export CCS_YES=1 ;;  # Auto-confirm (export for confirm_action)
      -*) msg_error "Unknown option: $1"; return 1 ;;
      *) profile_name="$1" ;;
    esac
    shift
  done

  [[ -z "$profile_name" ]] && {
    msg_error "Profile name is required"
    echo ""
    echo "Usage: ${YELLOW}ccs auth remove <profile> [--yes]${RESET}"
    return 1
  }

  profile_exists "$profile_name" || {
    msg_error "Profile not found: $profile_name"
    return 1
  }

  # Get instance path and session count for impact display
  local instance_path="$INSTANCES_DIR/$(sanitize_profile_name "$profile_name")"
  local session_count=0

  if [[ -d "$instance_path/session-env" ]]; then
    session_count=$(find "$instance_path/session-env" -name "*.json" 2>/dev/null | wc -l | tr -d ' ')
  fi

  # Display impact
  echo ""
  echo "Profile '${CYAN}$profile_name${RESET}' will be permanently deleted."
  echo "  Instance path: $instance_path"
  echo "  Sessions: $session_count conversation$([ "$session_count" -ne 1 ] && echo "s" || echo "")"
  echo ""

  # Interactive confirmation (or --yes flag)
  if ! confirm_action "Delete this profile?" "no"; then
    echo "[i] Cancelled"
    return 0
  fi

  # Delete instance directory
  rm -rf "$instance_path"

  # Remove from registry
  unregister_profile "$profile_name"

  echo -e "${GREEN}[OK] Profile removed successfully${RESET}"
  echo "    Profile: $profile_name"
  echo ""
}

auth_default() {
  local profile_name="${1:-}"

  [[ -z "$profile_name" ]] && {
    msg_error "Profile name is required"
    echo "Usage: ${YELLOW}ccs auth default <profile>${RESET}"
    return 1
  }

  profile_exists "$profile_name" || {
    msg_error "Profile not found: $profile_name"
    return 1
  }

  set_default_profile "$profile_name"

  echo -e "${GREEN}[OK] Default profile set${RESET}"
  echo "    Profile: $profile_name"
  echo ""
  echo "Now you can use:"
  echo "  ${YELLOW}ccs \"your prompt\"${RESET}  # Uses $profile_name profile"
  echo ""
}

handle_auth_commands() {
  shift  # Remove 'auth'

  local subcommand="${1:-}"
  shift || true

  case "$subcommand" in
    create) auth_create "$@" ;;
    list) auth_list "$@" ;;
    show) auth_show "$@" ;;
    remove) auth_remove "$@" ;;
    default) auth_default "$@" ;;
    *) auth_help ;;
  esac
}

# --- Shell Completion Installer ---

install_shell_completion() {
  shift  # Remove --shell-completion

  echo -e "${BOLD}Shell Completion Installer${RESET}"
  echo ""

  # Parse flags for manual shell selection
  local target_shell=""
  for arg in "$@"; do
    case "$arg" in
      --bash) target_shell="bash" ;;
      --zsh) target_shell="zsh" ;;
      --fish) target_shell="fish" ;;
      *) ;;
    esac
  done

  # Auto-detect shell if not specified
  if [[ -z "$target_shell" ]]; then
    if [[ -n "$BASH_VERSION" ]]; then
      target_shell="bash"
    elif [[ -n "$ZSH_VERSION" ]]; then
      target_shell="zsh"
    elif [[ -n "$FISH_VERSION" ]]; then
      target_shell="fish"
    else
      echo -e "${RED}[X] Could not detect shell${RESET}" >&2
      echo "" >&2
      echo -e "${YELLOW}Usage:${RESET}" >&2
      echo "  ccs --shell-completion           # Auto-detect shell" >&2
      echo "  ccs --shell-completion --bash    # Install for bash" >&2
      echo "  ccs --shell-completion --zsh     # Install for zsh" >&2
      echo "  ccs --shell-completion --fish    # Install for fish" >&2
      echo "" >&2
      return 1
    fi
  fi

  # Ensure completion files exist in ~/.ccs/completions/
  local completions_dir="$HOME/.ccs/completions"
  if [[ ! -d "$completions_dir" ]]; then
    mkdir -p "$completions_dir"
  fi

  # Copy from scripts if not present
  local script_dir="$(dirname "$0")"
  if [[ -f "$script_dir/../scripts/completion/ccs.bash" ]]; then
    cp "$script_dir/../scripts/completion/ccs.bash" "$completions_dir/" 2>/dev/null || true
    cp "$script_dir/../scripts/completion/ccs.zsh" "$completions_dir/" 2>/dev/null || true
    cp "$script_dir/../scripts/completion/ccs.fish" "$completions_dir/" 2>/dev/null || true
  fi

  # Install based on target shell
  case "$target_shell" in
    bash)
      local rc_file="$HOME/.bashrc"
      local completion_file="$completions_dir/ccs.bash"
      local marker="# CCS shell completion"

      if [[ ! -f "$completion_file" ]]; then
        echo -e "${RED}[X] Completion file not found: $completion_file${RESET}" >&2
        echo "    Please reinstall CCS." >&2
        return 1
      fi

      # Check if already installed
      if grep -q "$marker" "$rc_file" 2>/dev/null; then
        echo -e "${GREEN}[OK] Shell completion already installed${RESET}"
        echo ""
        return 0
      fi

      # Append to .bashrc
      {
        echo ""
        echo "$marker"
        echo "source \"$completion_file\""
      } >> "$rc_file"

      echo -e "${GREEN}[OK] Shell completion installed successfully!${RESET}"
      echo ""
      echo "Added to $rc_file"
      echo ""
      echo -e "${CYAN}To activate:${RESET}"
      echo "  source ~/.bashrc"
      echo ""
      echo -e "${CYAN}Then test:${RESET}"
      echo "  ccs <TAB>        # See available profiles"
      echo "  ccs auth <TAB>   # See auth subcommands"
      echo ""
      ;;

    zsh)
      local rc_file="$HOME/.zshrc"
      local completion_dir="$HOME/.zsh/completion"
      local completion_file="$completions_dir/ccs.zsh"
      local marker="# CCS shell completion"

      if [[ ! -f "$completion_file" ]]; then
        echo -e "${RED}[X] Completion file not found: $completion_file${RESET}" >&2
        echo "    Please reinstall CCS." >&2
        return 1
      fi

      # Create zsh completion directory
      mkdir -p "$completion_dir"

      # Copy to zsh completion directory
      cp "$completion_file" "$completion_dir/_ccs"

      # Check if already installed
      if grep -q "$marker" "$rc_file" 2>/dev/null; then
        echo -e "${GREEN}[OK] Shell completion already installed${RESET}"
        echo ""
        return 0
      fi

      # Append to .zshrc
      {
        echo ""
        echo "$marker"
        echo "fpath=(~/.zsh/completion \$fpath)"
        echo "autoload -Uz compinit && compinit"
      } >> "$rc_file"

      echo -e "${GREEN}[OK] Shell completion installed successfully!${RESET}"
      echo ""
      echo "Added to $rc_file"
      echo ""
      echo -e "${CYAN}To activate:${RESET}"
      echo "  source ~/.zshrc"
      echo ""
      echo -e "${CYAN}Then test:${RESET}"
      echo "  ccs <TAB>        # See available profiles"
      echo "  ccs auth <TAB>   # See auth subcommands"
      echo ""
      ;;

    fish)
      local fish_dir="$HOME/.config/fish/completions"
      local completion_file="$completions_dir/ccs.fish"

      if [[ ! -f "$completion_file" ]]; then
        echo -e "${RED}[X] Completion file not found: $completion_file${RESET}" >&2
        echo "    Please reinstall CCS." >&2
        return 1
      fi

      # Create fish completion directory
      mkdir -p "$fish_dir"

      # Copy to fish completion directory (fish auto-loads from here)
      cp "$completion_file" "$fish_dir/ccs.fish"

      echo -e "${GREEN}[OK] Shell completion installed successfully!${RESET}"
      echo ""
      echo "Installed to $fish_dir/ccs.fish"
      echo ""
      echo -e "${CYAN}To activate:${RESET}"
      echo "  Fish auto-loads completions (no reload needed)"
      echo ""
      echo -e "${CYAN}Then test:${RESET}"
      echo "  ccs <TAB>        # See available profiles"
      echo "  ccs auth <TAB>   # See auth subcommands"
      echo ""
      ;;

    *)
      echo -e "${RED}[X] Unsupported shell: $target_shell${RESET}" >&2
      return 1
      ;;
  esac

  return 0
}

# --- Main Execution Logic ---

# Special case: version command (check BEFORE profile detection)
if [[ $# -gt 0 ]] && [[ "${1}" == "version" || "${1}" == "--version" || "${1}" == "-v" ]]; then
  show_version
  exit 0
fi

# Special case: help command (check BEFORE profile detection)
if [[ $# -gt 0 ]] && [[ "${1}" == "--help" || "${1}" == "-h" || "${1}" == "help" ]]; then
  show_help
  exit 0
fi

# Special case: auth commands
if [[ $# -gt 0 ]] && [[ "${1}" == "auth" ]]; then
  handle_auth_commands "$@"
  exit $?
fi

# Special case: shell completion installer
if [[ $# -gt 0 ]] && [[ "${1}" == "--shell-completion" ]]; then
  install_shell_completion "$@"
  exit $?
fi

# Special case: doctor command
if [[ $# -gt 0 ]] && [[ "${1}" == "doctor" || "${1}" == "--doctor" ]]; then
  doctor_run
  exit $?
fi

# Run auto-recovery before main logic
auto_recover || {
  msg_error "Auto-recovery failed. Check permissions."
  exit 1
}

# Smart profile detection: if first arg starts with '-', it's a flag not a profile
if [[ $# -eq 0 ]] || [[ "${1}" =~ ^- ]]; then
  # No args or first arg is a flag → use default profile
  PROFILE="default"
else
  # First arg doesn't start with '-' → treat as profile name
  PROFILE="${1}"
fi

# Validate profile name (alphanumeric, dash, underscore only)
if [[ "$PROFILE" =~ [^a-zA-Z0-9_-] ]]; then
  msg_error "Invalid profile name: $PROFILE

Use only alphanumeric characters, dash, or underscore."
  exit 1
fi

# Detect profile type
if ! detect_profile_type "$PROFILE"; then
  # Get suggestions using fuzzy matching
  mapfile -t all_profiles < <(get_all_profile_names)
  mapfile -t suggestions < <(find_similar_strings "$PROFILE" "${all_profiles[@]}")

  echo "" >&2
  echo -e "${RED}[X] Profile '$PROFILE' not found${RESET}" >&2
  echo "" >&2

  # Show suggestions if any
  if [[ ${#suggestions[@]} -gt 0 ]]; then
    echo -e "${YELLOW}Did you mean:${RESET}" >&2
    for suggestion in "${suggestions[@]}"; do
      echo "  $suggestion" >&2
    done
    echo "" >&2
  fi

  echo -e "${CYAN}Available profiles:${RESET}" >&2
  list_available_profiles >&2
  echo "" >&2
  echo -e "${YELLOW}Solutions:${RESET}" >&2
  echo "  # Use existing profile" >&2
  echo "  ccs <profile> \"your prompt\"" >&2
  echo "" >&2
  echo "  # Create new account profile" >&2
  echo "  ccs auth create <name>" >&2
  echo "" >&2
  echo -e "${YELLOW}Error: $E_PROFILE_NOT_FOUND${RESET}" >&2
  echo -e "${YELLOW}$(get_error_doc_url "$E_PROFILE_NOT_FOUND")${RESET}" >&2
  echo "" >&2
  exit 1
fi

# Shift profile arg only if first arg was NOT a flag
if [[ $# -gt 0 ]] && [[ ! "${1}" =~ ^- ]]; then
  shift
fi

# Detect Claude CLI executable
CLAUDE_CLI=$(detect_claude_cli)

# Execute based on profile type (Phase 5)
case "$PROFILE_TYPE" in
  account)
    # Account-based profile: use CLAUDE_CONFIG_DIR
    INSTANCE_PATH=$(ensure_instance "$PROFILE_NAME")
    touch_profile "$PROFILE_NAME"  # Update last_used

    # Execute Claude with isolated config
    CLAUDE_CONFIG_DIR="$INSTANCE_PATH" exec "$CLAUDE_CLI" "$@" || {
      show_claude_not_found_error
      exit 1
    }
    ;;

  settings)
    # Settings-based profile: use --settings flag
    SETTINGS_PATH="${PROFILE_PATH/#\~/$HOME}"

    [[ ! -f "$SETTINGS_PATH" ]] && {
      msg_error "Settings file not found: $SETTINGS_PATH"
      exit 1
    }

    exec "$CLAUDE_CLI" --settings "$SETTINGS_PATH" "$@" || {
      show_claude_not_found_error
      exit 1
    }
    ;;

  default)
    # Default: no special handling
    exec "$CLAUDE_CLI" "$@" || {
      show_claude_not_found_error
      exit 1
    }
    ;;

  *)
    msg_error "Unknown profile type: $PROFILE_TYPE"
    exit 1
    ;;
esac
