/**
 * SANDCODE Model Options
 *
 * Provider-centric model picker: shows models for the active provider,
 * plus options to switch provider, add a new provider, or enter a model manually.
 *
 * Replaces the upstream Anthropic-centric model picker which had 600 lines
 * of subscription tier logic (Max, Pro, Team Premium, PAYG pricing).
 */
import { getInitialMainLoopModel } from '../../bootstrap/state.js'
import { getSettings_DEPRECATED } from '../settings/settings.js'
import { getConfiguredProviders } from '../providerSetupPrompt.js'
import { getAPIProvider, getCustomProviderConfig } from './providers.js'
import { getGlobalConfig } from '../config.js'
import {
  getDefaultMainLoopModelSetting,
  getUserSpecifiedModelSetting,
  renderDefaultModelSetting,
  type ModelSetting,
} from './model.js'
import { isModelAllowed } from './modelAllowlist.js'

export type ModelOption = {
  value: ModelSetting
  label: string
  description: string
  descriptionForModel?: string
}

/** Sentinel prefix for provider-switch options in the model picker */
export const PROVIDER_SWITCH_PREFIX = '__provider:'

/** Sentinel for the "Add new provider" action */
export const ADD_PROVIDER_ACTION = '__action:add_provider'

/** Sentinel for the "Enter model name" action */
export const ENTER_MODEL_ACTION = '__action:enter_model'

// ─────────────────────────────────────────────────────────────
// Built-in model presets per provider
// ─────────────────────────────────────────────────────────────

const PROVIDER_MODELS: Record<string, Array<{ value: string; label: string; desc: string }>> = {
  zai: [
    { value: 'GLM-5.1', label: 'GLM-5.1', desc: 'Coding plan — most capable' },
    { value: 'glm-5', label: 'GLM-5', desc: 'Flagship model' },
    { value: 'glm-5-turbo', label: 'GLM-5 Turbo', desc: 'Fast' },
    { value: 'glm-4.7', label: 'GLM-4.7', desc: 'Previous generation' },
    { value: 'glm-4.5-air', label: 'GLM-4.5 Air', desc: 'Lightweight' },
  ],
  openai: [
    { value: 'gpt-4o', label: 'GPT-4o', desc: 'Most capable OpenAI model' },
    { value: 'gpt-4o-mini', label: 'GPT-4o Mini', desc: 'Fast and affordable' },
    { value: 'o3', label: 'o3', desc: 'Advanced reasoning' },
    { value: 'o4-mini', label: 'o4-mini', desc: 'Fast reasoning' },
  ],
  deepseek: [
    { value: 'deepseek-chat', label: 'DeepSeek Chat', desc: 'General purpose' },
    { value: 'deepseek-reasoner', label: 'DeepSeek Reasoner', desc: 'Advanced reasoning (R1)' },
  ],
  mistral: [
    { value: 'mistral-large-latest', label: 'Mistral Large', desc: 'Most capable' },
    { value: 'mistral-small-latest', label: 'Mistral Small', desc: 'Fast and efficient' },
    { value: 'codestral-latest', label: 'Codestral', desc: 'Optimized for code' },
  ],
  gemini: [
    { value: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro', desc: 'Most capable' },
    { value: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash', desc: 'Fast and efficient' },
  ],
  openrouter: [
    { value: 'anthropic/claude-sonnet-4', label: 'Claude Sonnet 4', desc: 'via OpenRouter' },
    { value: 'anthropic/claude-opus-4', label: 'Claude Opus 4', desc: 'via OpenRouter' },
    { value: 'openai/gpt-4o', label: 'GPT-4o', desc: 'via OpenRouter' },
    { value: 'google/gemini-2.5-pro', label: 'Gemini 2.5 Pro', desc: 'via OpenRouter' },
    { value: 'deepseek/deepseek-chat', label: 'DeepSeek Chat', desc: 'via OpenRouter' },
    { value: 'meta-llama/llama-4-maverick', label: 'Llama 4 Maverick', desc: 'via OpenRouter' },
  ],
  // Anthropic first-party
  firstParty: [
    { value: 'sonnet', label: 'Sonnet', desc: 'Sonnet 4.6 — best for everyday tasks' },
    { value: 'opus', label: 'Opus', desc: 'Opus 4.6 — most capable' },
    { value: 'haiku', label: 'Haiku', desc: 'Haiku 4.5 — fastest' },
  ],
}

// ─────────────────────────────────────────────────────────────
// Public API
// ─────────────────────────────────────────────────────────────

export function getDefaultOptionForUser(_fastMode = false): ModelOption {
  const currentModel = renderDefaultModelSetting(getDefaultMainLoopModelSetting())
  return {
    value: null,
    label: 'Default (recommended)',
    description: `Use the default model (currently ${currentModel})`,
    descriptionForModel: `Default model (currently ${currentModel})`,
  }
}

export function getModelOptions(fastMode = false): ModelOption[] {
  const provider = getAPIProvider()
  const options: ModelOption[] = []

  // 1. Default option
  options.push(getDefaultOptionForUser(fastMode))

  // 2. Models for the active provider
  const customProvider = getCustomProviderConfig()
  if (customProvider) {
    // User-added custom provider
    if (customProvider.models?.length) {
      for (const m of customProvider.models) {
        options.push({ value: m.value, label: m.label, description: m.desc })
      }
    } else {
      // No preset models — just show the default model as an option
      options.push({
        value: customProvider.defaultModel,
        label: customProvider.defaultModel,
        description: `Default model for ${customProvider.name}`,
      })
    }
  } else {
    // Built-in provider models
    const models = PROVIDER_MODELS[provider] ?? []
    for (const m of models) {
      options.push({ value: m.value, label: m.label, description: m.desc })
    }
  }

  // 3. Add custom model from env var
  const envCustomModel = process.env.ANTHROPIC_CUSTOM_MODEL_OPTION
  if (envCustomModel && !options.some(o => o.value === envCustomModel)) {
    options.push({
      value: envCustomModel,
      label: process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_NAME ?? envCustomModel,
      description: process.env.ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTION ?? `Custom model (${envCustomModel})`,
    })
  }

  // 4. Add additional models from bootstrap cache
  for (const opt of getGlobalConfig().additionalModelOptionsCache ?? []) {
    if (!options.some(o => o.value === opt.value)) {
      options.push(opt)
    }
  }

  // 5. If user has a custom model set that's not in the list, add it
  const currentModel = getUserSpecifiedModelSetting() ?? getInitialMainLoopModel()
  if (currentModel !== null && !options.some(o => o.value === currentModel)) {
    options.push({
      value: currentModel,
      label: currentModel,
      description: 'Current model',
    })
  }

  // 6. Filter by allowlist
  const filtered = filterByAllowlist(options)

  // 7. Provider switch options
  const configured = getConfiguredProviders()
  if (configured.length > 1) {
    for (const p of configured) {
      if (p.isActive) continue
      filtered.push({
        value: `${PROVIDER_SWITCH_PREFIX}${p.id}`,
        label: `━ Switch to ${p.name}`,
        description: p.model ? `Use ${p.name} (${p.model})` : `Switch provider to ${p.name}`,
      })
    }
  }

  // 8. "Add new provider" and "Enter model name" actions
  filtered.push({
    value: ADD_PROVIDER_ACTION,
    label: '━ Add new provider',
    description: 'Add a custom OpenAI-compatible provider',
  })
  filtered.push({
    value: ENTER_MODEL_ACTION,
    label: '━ Enter model name',
    description: 'Type a model name directly',
  })

  return filtered
}

function filterByAllowlist(options: ModelOption[]): ModelOption[] {
  const settings = getSettings_DEPRECATED() || {}
  if (!settings.availableModels) return options
  return options.filter(
    opt => opt.value === null || (opt.value !== null && isModelAllowed(opt.value)),
  )
}

// Re-export for backward compatibility with bootstrap cache
export { type ModelOption as ModelOptionType }
