import type { AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS } from '../../services/analytics/index.js'
import { getGlobalConfig } from '../config.js'
import { isEnvTruthy } from '../envUtils.js'

export type APIProvider =
  | 'firstParty' | 'bedrock' | 'vertex' | 'foundry'
  | 'openai' | 'deepseek' | 'mistral' | 'gemini'
  | 'openai-compat' | 'zai' | 'openrouter'
  | (string & {}) // allow custom provider IDs

/** All providers that use the OpenAI-compatible adapter */
export const OPENAI_COMPAT_PROVIDERS: APIProvider[] = [
  'openai', 'deepseek', 'mistral', 'gemini', 'openai-compat', 'zai', 'openrouter',
]

export function getAPIProvider(): APIProvider {
  if (isEnvTruthy(process.env.SANDCODE_USE_BEDROCK)) return 'bedrock'
  if (isEnvTruthy(process.env.SANDCODE_USE_VERTEX)) return 'vertex'
  if (isEnvTruthy(process.env.SANDCODE_USE_FOUNDRY)) return 'foundry'
  if (isEnvTruthy(process.env.SANDCODE_USE_OPENAI)) return 'openai'
  if (isEnvTruthy(process.env.SANDCODE_USE_DEEPSEEK)) return 'deepseek'
  if (isEnvTruthy(process.env.SANDCODE_USE_MISTRAL)) return 'mistral'
  if (isEnvTruthy(process.env.SANDCODE_USE_GEMINI)) return 'gemini'
  // OpenRouter must be checked BEFORE openai-compat (switching sets both env vars)
  if (isEnvTruthy(process.env.SANDCODE_USE_OPENROUTER)) return 'openrouter'
  if (isEnvTruthy(process.env.SANDCODE_USE_OPENAI_COMPAT)) return 'openai-compat'
  if (isZaiProvider()) return 'zai'
  // Check config for non-env provider selection
  try {
    const config = getGlobalConfig()
    if (config.provider && config.provider !== 'claude') {
      return config.provider as APIProvider
    }
  } catch { /* config not initialized yet */ }
  return 'firstParty'
}

/** Check if the active provider is a user-added custom provider */
export function getCustomProviderConfig(): { id: string; name: string; baseUrl: string; apiKey: string; defaultModel: string; models?: Array<{ value: string; label: string; desc: string }>; extraHeaders?: Record<string, string> } | undefined {
  try {
    const config = getGlobalConfig()
    return config.customProviders?.find(p => p.id === config.provider)
  } catch { return undefined }
}

/**
 * Returns true if the active provider is a custom provider that
 * should route through the openai-compat adapter.
 */
export function isCustomProvider(): boolean {
  return getCustomProviderConfig() !== undefined
}

export function getAPIProviderForStatsig(): AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS {
  return getAPIProvider() as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
}

export function isFirstPartyAnthropicBaseUrl(): boolean {
  const baseUrl = process.env.ANTHROPIC_BASE_URL
  if (!baseUrl) {
    return true
  }
  try {
    const host = new URL(baseUrl).host
    const allowedHosts = ['api.anthropic.com']
    if (process.env.USER_TYPE === 'ant') {
      allowedHosts.push('api-staging.anthropic.com')
    }
    return allowedHosts.includes(host)
  } catch {
    return false
  }
}

/** Returns true if using a non-Anthropic provider (OpenAI-compat adapter) */
export function isNonAnthropicProvider(): boolean {
  const provider = getAPIProvider()
  if (OPENAI_COMPAT_PROVIDERS.includes(provider)) return true
  // Custom providers are always non-Anthropic
  if (isCustomProvider()) return true
  // Unknown provider IDs from config are non-Anthropic
  if (provider !== 'firstParty' && provider !== 'bedrock' && provider !== 'vertex' && provider !== 'foundry') {
    return true
  }
  return false
}

/**
 * For non-Anthropic providers, determine if a model likely supports a capability.
 * Returns undefined if the provider is Anthropic (fall through to existing logic).
 */
export function getNonAnthropicModelCapability(
  model: string,
  capability: 'thinking' | 'tools' | 'streaming' | 'effort',
): boolean | undefined {
  const provider = getAPIProvider()
  if (!OPENAI_COMPAT_PROVIDERS.includes(provider) && !isCustomProvider()) return undefined

  const m = model.toLowerCase()

  // Known models with reasoning/thinking support
  if (capability === 'thinking') {
    if (provider === 'openai') return m.includes('o1') || m.includes('o3') || m.includes('o4')
    if (provider === 'deepseek') return m.includes('reasoner') || m.includes('r1')
    if (provider === 'zai') return m.includes('glm-5')
    if (provider === 'openrouter') {
      // OpenRouter proxies many models — check model name patterns
      return m.includes('o1') || m.includes('o3') || m.includes('o4') || m.includes('reasoner') || m.includes('r1')
    }
    // Most other models don't have native thinking
    return false
  }

  // Tool use — most modern models support it
  if (capability === 'tools') {
    if (provider === 'openai') return true
    if (provider === 'deepseek') return m.includes('chat') || m.includes('coder')
    if (provider === 'mistral') return true
    if (provider === 'gemini') return true
    if (provider === 'zai') return true
    if (provider === 'openrouter') return true
    // For openai-compat, assume tools work unless proven otherwise
    return true
  }

  // Effort control — Anthropic-only concept
  if (capability === 'effort') return false

  // Streaming — all OpenAI-compat providers support it
  if (capability === 'streaming') return true

  return undefined
}

export function isZaiProvider(): boolean {
  // Check env var first (safe to call before config init)
  if (isEnvTruthy(process.env.SANDCODE_USE_ZAI)) {
    return true
  }
  // Config may not be initialized yet during module evaluation
  try {
    return getGlobalConfig().provider === 'zai'
  } catch {
    return false
  }
}
