import type { ProviderState } from '#cli/compat/providers'
import {
  getBuiltinProvider,
  getProviderAdapter,
  getProviderDisplayName,
  isCustomProviderId,
  isLegacyCustomProviderId,
  resolveBuiltinProviderBaseUrl,
  usesCcMock,
} from '#cli/compat/providers'
import { OAUTH_DUMMY_KEY } from './auth'
import { NEXT_API_OAUTH_PROVIDER_ID } from './next-api-oauth'

type ProviderRuntimeEnvResolution = Readonly<{
  config?: Readonly<{
    apiKey: string
    baseUrl: string
  }>
  updates: Record<string, string | undefined>
}>

type ProviderRuntimeConfig = Readonly<{
  apiKey?: unknown
  baseUrl?: unknown
}>

type ProviderRuntimeState = Readonly<
  Pick<ProviderState, 'connections' | 'customProviders' | 'custom'>
>

function normalizeText(value: unknown): string {
  return String(value ?? '').trim()
}

function resolveCustomAdapter(
  value: unknown,
): 'openai' | 'openai-responses' | 'gemini' | 'anthropic' {
  const adapter = normalizeText(value)
  if (
    adapter === 'gemini'
    || adapter === 'anthropic'
    || adapter === 'openai-responses'
  ) {
    return adapter
  }
  return 'openai'
}

export function resolveProviderRuntimeEnv(input: Readonly<{
  config?: ProviderRuntimeConfig | null
  env?: Record<string, string | undefined> | null
  legacyCustomProviderName: string
  providerId: string
  providerState?: ProviderRuntimeState | null
}>): ProviderRuntimeEnvResolution | undefined {
  const providerId = normalizeText(input.providerId)
  if (!providerId)
    return undefined

  const env = input.env ?? {}
  const config = input.config ?? {}
  const providerState = input.providerState ?? {}

  if (providerId === NEXT_API_OAUTH_PROVIDER_ID) {
    const conn = providerState?.connections?.[NEXT_API_OAUTH_PROVIDER_ID] ?? {}
    const baseUrl
      = normalizeText(conn.baseUrl ?? config.baseUrl)
        || normalizeText(env.DIMCODE_OPENAI_BASE_URL ?? env.OPENAI_BASE_URL)
    const apiKey
      = normalizeText(conn.apiKey ?? config.apiKey)
        || normalizeText(env.OPENAI_API_KEY)
        || OAUTH_DUMMY_KEY
    const providerName = getProviderDisplayName(
      getBuiltinProvider(NEXT_API_OAUTH_PROVIDER_ID) ?? {
        id: NEXT_API_OAUTH_PROVIDER_ID,
      },
    )

    return {
      config: {
        baseUrl,
        apiKey,
      },
      updates: {
        DIMCODE_PROVIDER_ADAPTER: 'openai',
        DIMCODE_PROVIDER_ID: NEXT_API_OAUTH_PROVIDER_ID,
        DIMCODE_PROVIDER_NAME: providerName,
        DIMCODE_OPENAI_BASE_URL: baseUrl || undefined,
        OPENAI_BASE_URL: baseUrl || undefined,
        OPENAI_API_KEY: apiKey,
        DIMCODE_CCMOCK: undefined,
      },
    }
  }

  const isCustomProvider = isCustomProviderId(providerId)
  const isLegacyCustomProvider = isLegacyCustomProviderId(providerId)
  const builtin
    = !isCustomProvider && !isLegacyCustomProvider
      ? getBuiltinProvider(providerId)
      : undefined
  const customProviders = providerState.customProviders ?? []
  const custom = isCustomProvider
    ? customProviders.find(entry => normalizeText(entry.id) === providerId)
    : undefined
  const adapter = isCustomProvider
    ? resolveCustomAdapter(custom?.adapter)
    : isLegacyCustomProvider
      ? 'openai'
      : getProviderAdapter(builtin)
  const providerName = isCustomProvider
    ? normalizeText(custom?.name) || input.legacyCustomProviderName
    : isLegacyCustomProvider
      ? input.legacyCustomProviderName
      : getProviderDisplayName(builtin ?? { id: providerId })
  const baseUrl = isCustomProvider
    ? normalizeText(custom?.baseUrl)
    : isLegacyCustomProvider
      ? normalizeText(providerState?.custom?.baseUrl)
      : normalizeText(
          resolveBuiltinProviderBaseUrl(
            builtin,
            providerState?.connections?.[providerId]?.baseUrl,
          ),
        )
  const apiKey = isCustomProvider
    ? normalizeText(custom?.apiKey)
    : isLegacyCustomProvider
      ? normalizeText(providerState?.custom?.apiKey)
      : normalizeText(providerState?.connections?.[providerId]?.apiKey)
  const ccmockEnabled = usesCcMock(builtin)
  const updates: Record<string, string | undefined> = {
    DIMCODE_PROVIDER_ADAPTER: adapter,
    DIMCODE_PROVIDER_ID: providerId,
    DIMCODE_PROVIDER_NAME: providerName,
    DIMCODE_CCMOCK: ccmockEnabled ? '1' : undefined,
  }

  if (adapter === 'gemini') {
    updates.DIMCODE_GEMINI_BASE_URL = baseUrl || undefined
    updates.GOOGLE_API_KEY = apiKey || undefined
  }
  else if (adapter === 'anthropic') {
    updates.DIMCODE_ANTHROPIC_BASE_URL = baseUrl || undefined
    updates.ANTHROPIC_API_KEY = apiKey || undefined
  }
  else {
    updates.DIMCODE_OPENAI_BASE_URL = baseUrl || undefined
    updates.OPENAI_API_KEY = apiKey || undefined
  }

  return { updates }
}
