export type ProviderId = 'xai' | 'openai' | 'anthropic' | 'google' | 'opencode-go'

export type ProviderApiKeys = Partial<Record<ProviderId, string>>

export const AI_CREDENTIALS_KEY = 'ai.credentials'

export const PROVIDER_KEY_LABELS: Record<
  ProviderId,
  { label: string; hint: string; docsUrl?: string }
> = {
  'opencode-go': {
    label: 'OpenCode Go',
    hint: '從 opencode.ai/auth 訂閱 Go 方案後取得',
    docsUrl: 'https://opencode.ai/docs/go/',
  },
  xai: { label: 'Grok (xAI)', hint: 'xAI Console API key' },
  openai: { label: 'OpenAI', hint: 'platform.openai.com API key' },
  anthropic: { label: 'Anthropic', hint: 'console.anthropic.com API key' },
  google: { label: 'Google Gemini', hint: 'Google AI Studio API key' },
}

export const PROVIDER_ORDER: ProviderId[] = [
  'opencode-go',
  'xai',
  'openai',
  'anthropic',
  'google',
]

export const PROVIDER_OPTIONS = [
  {
    value: 'opencode-go' as const,
    label: 'OpenCode Go',
    models: [
      'deepseek-v4-flash',
      'deepseek-v4-pro',
      'glm-5.1',
      'kimi-k2.7-code',
      'kimi-k2.5',
      'qwen3.7-max',
    ],
  },
  { value: 'xai' as const, label: 'Grok (xAI)', models: ['grok-3', 'grok-3-fast', 'grok-2-1212'] },
  { value: 'openai' as const, label: 'OpenAI', models: ['gpt-4o', 'gpt-4o-mini'] },
  {
    value: 'anthropic' as const,
    label: 'Anthropic',
    models: ['claude-sonnet-4-20250514', 'claude-3-5-haiku-20241022'],
  },
  { value: 'google' as const, label: 'Google', models: ['gemini-2.0-flash', 'gemini-1.5-pro'] },
] as const

export type AccountAiCredentials = {
  provider: ProviderId
  model: string
  research_provider?: ProviderId
  research_model?: string
  api_keys: ProviderApiKeys
}

export const DEFAULT_AI_CREDENTIALS: AccountAiCredentials = {
  provider: 'opencode-go',
  model: 'deepseek-v4-pro',
  research_provider: 'opencode-go',
  research_model: 'deepseek-v4-flash',
  api_keys: {},
}

export function maskApiKey(key: string | undefined | null): string | null {
  if (!key) return null
  if (key.length <= 4) return '••••'
  return `••••${key.slice(-4)}`
}

export function isMaskedKey(value: string): boolean {
  return value.startsWith('••••')
}

export function getApiKeyStatus(keys: ProviderApiKeys): Record<ProviderId, boolean> {
  return PROVIDER_ORDER.reduce(
    (acc, id) => {
      acc[id] = !!keys[id]?.trim()
      return acc
    },
    {} as Record<ProviderId, boolean>,
  )
}

export function mergeProviderApiKeys(
  existing: ProviderApiKeys,
  incoming: ProviderApiKeys,
): ProviderApiKeys {
  const merged = { ...existing }
  for (const [provider, value] of Object.entries(incoming) as [ProviderId, string][]) {
    const trimmed = value?.trim()
    if (!trimmed || isMaskedKey(trimmed)) continue
    merged[provider] = trimmed
  }
  return merged
}

export function getMaskedProviderApiKeys(keys: ProviderApiKeys): ProviderApiKeys {
  return PROVIDER_ORDER.reduce((acc, id) => {
    const masked = maskApiKey(keys[id])
    if (masked) acc[id] = masked
    return acc
  }, {} as ProviderApiKeys)
}

export function parseAccountAiCredentials(raw: Record<string, unknown> | undefined): AccountAiCredentials {
  if (!raw || typeof raw !== 'object') return { ...DEFAULT_AI_CREDENTIALS, api_keys: {} }
  const apiKeys =
    raw.api_keys && typeof raw.api_keys === 'object'
      ? (raw.api_keys as ProviderApiKeys)
      : {}
  const provider = (raw.provider as ProviderId) || DEFAULT_AI_CREDENTIALS.provider
  const researchProvider = (raw.research_provider as ProviderId) || provider
  return {
    provider,
    model: typeof raw.model === 'string' ? raw.model : DEFAULT_AI_CREDENTIALS.model,
    research_provider: researchProvider,
    research_model:
      typeof raw.research_model === 'string'
        ? raw.research_model
        : DEFAULT_AI_CREDENTIALS.research_model,
    api_keys: apiKeys,
  }
}

export function buildAccountAiCredentialsPayload(
  current: AccountAiCredentials,
  keyInputs: ProviderApiKeys,
): AccountAiCredentials {
  return {
    provider: current.provider,
    model: current.model,
    research_provider: current.research_provider,
    research_model: current.research_model,
    api_keys: mergeProviderApiKeys(current.api_keys, keyInputs),
  }
}

export function memberAiSettingsPath(userId: string) {
  return `/api/v1/settings/user/${encodeURIComponent(userId)}/${encodeURIComponent(AI_CREDENTIALS_KEY)}`
}