import { useMemo, useState } from 'react';
import { Text } from 'react-native';

import type { Id } from '@spoon/backend/convex/_generated/dataModel.js';

import { Button } from '~/components/ui/button';
import { Field } from '~/components/ui/field';
import { FormSection } from '~/components/ui/form-section';
import { SheetSelect } from '~/components/ui/sheet-select';
import { SwitchRow } from '~/components/ui/switch-row';
import { Textarea } from '~/components/ui/textarea';

type Provider =
  | 'openai'
  | 'anthropic'
  | 'google'
  | 'openrouter'
  | 'requesty'
  | 'litellm'
  | 'cloudflare_ai_gateway'
  | 'custom_openai_compatible'
  | 'opencode_openai_login';
type AuthType = 'api_key' | 'opencode_auth_json' | 'none';
type ReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';

type ExistingProfile = {
  _id: Id<'aiProviderProfiles'>;
  authType: AuthType;
  baseUrl?: string;
  defaultModel: string;
  enabled: boolean;
  modelOptions?: string[];
  name: string;
  provider: Provider;
  reasoningEffort: ReasoningEffort;
};

const providerDefaults: Record<
  Provider,
  { authType: AuthType; model: string; name: string }
> = {
  anthropic: {
    authType: 'api_key',
    model: 'claude-sonnet-4-5',
    name: 'Anthropic',
  },
  cloudflare_ai_gateway: {
    authType: 'api_key',
    model: 'gpt-5.1-codex',
    name: 'Cloudflare AI Gateway',
  },
  custom_openai_compatible: {
    authType: 'api_key',
    model: 'gpt-5.1-codex',
    name: 'Custom compatible',
  },
  google: { authType: 'api_key', model: 'gemini-2.5-pro', name: 'Google' },
  litellm: { authType: 'api_key', model: 'gpt-5.1-codex', name: 'LiteLLM' },
  opencode_openai_login: {
    authType: 'opencode_auth_json',
    model: 'gpt-5.1-codex',
    name: 'OpenCode provider',
  },
  openai: { authType: 'api_key', model: 'gpt-5.1-codex', name: 'OpenAI' },
  openrouter: {
    authType: 'api_key',
    model: 'openai/gpt-5.1-codex',
    name: 'OpenRouter',
  },
  requesty: {
    authType: 'api_key',
    model: 'openai/gpt-5.1-codex',
    name: 'Requesty',
  },
};

const parseModelOptions = (text: string) =>
  text
    .split(/\r?\n|,/)
    .map((model) => model.trim())
    .filter(Boolean);

export const AiProviderProfileForm = ({
  existing,
  onSubmit,
  saving,
}: {
  existing?: ExistingProfile;
  onSubmit: (values: {
    authType: AuthType;
    baseUrl?: string;
    defaultModel: string;
    enabled: boolean;
    modelOptions: string[];
    name: string;
    provider: Provider;
    reasoningEffort: ReasoningEffort;
    secret?: string;
  }) => Promise<void>;
  saving: boolean;
}) => {
  const [name, setName] = useState(existing?.name ?? 'OpenCode provider');
  const [provider, setProvider] = useState<Provider>(
    existing?.provider ?? 'opencode_openai_login',
  );
  const [authType, setAuthType] = useState<AuthType>(
    existing?.authType ?? 'opencode_auth_json',
  );
  const [secret, setSecret] = useState('');
  const [baseUrl, setBaseUrl] = useState(existing?.baseUrl ?? '');
  const [modelOptions, setModelOptions] = useState(
    (existing?.modelOptions?.length
      ? existing.modelOptions
      : [existing?.defaultModel ?? 'gpt-5.1-codex']
    ).join('\n'),
  );
  const models = useMemo(() => parseModelOptions(modelOptions), [modelOptions]);
  const [defaultModel, setDefaultModel] = useState(
    existing?.defaultModel ?? 'gpt-5.1-codex',
  );
  const [reasoningEffort, setReasoningEffort] = useState<ReasoningEffort>(
    existing?.reasoningEffort ?? 'medium',
  );
  const [enabled, setEnabled] = useState(existing?.enabled ?? true);

  const changeProvider = (nextProvider: Provider) => {
    const defaults = providerDefaults[nextProvider];
    setProvider(nextProvider);
    setName(defaults.name);
    setAuthType(defaults.authType);
    setDefaultModel(defaults.model);
    setModelOptions(defaults.model);
  };

  const submit = () =>
    void onSubmit({
      authType,
      baseUrl: baseUrl || undefined,
      defaultModel: models.includes(defaultModel)
        ? defaultModel
        : (models[0] ?? defaultModel),
      enabled,
      modelOptions: models,
      name,
      provider,
      reasoningEffort,
      secret: secret || undefined,
    });

  return (
    <FormSection title={existing ? 'Edit provider' : 'New provider'}>
      <Field label='Name' value={name} onChangeText={setName} />
      <SheetSelect
        label='Provider'
        options={[
          { label: 'Codex ChatGPT login', value: 'opencode_openai_login' },
          { label: 'OpenAI', value: 'openai' },
          { label: 'Anthropic', value: 'anthropic' },
          { label: 'Google', value: 'google' },
          { label: 'OpenRouter', value: 'openrouter' },
          { label: 'Requesty', value: 'requesty' },
          { label: 'LiteLLM', value: 'litellm' },
          { label: 'Cloudflare AI Gateway', value: 'cloudflare_ai_gateway' },
          {
            label: 'Custom OpenAI compatible',
            value: 'custom_openai_compatible',
          },
        ]}
        value={provider}
        onChange={changeProvider}
      />
      <SheetSelect
        label='Auth type'
        options={[
          { label: 'API key', value: 'api_key' },
          { label: 'Codex auth JSON', value: 'opencode_auth_json' },
          { label: 'None', value: 'none' },
        ]}
        value={authType}
        onChange={setAuthType}
      />
      {authType === 'opencode_auth_json' ? (
        <Text className='text-muted-foreground text-sm leading-5'>
          Copy auth.json from your Codex auth folder, for example
          ~/.codex/auth.json, and paste it here. Spoon writes it into isolated
          agent workspaces for Codex CLI runs.
        </Text>
      ) : null}
      {authType !== 'none' ? (
        <Field
          label={authType === 'api_key' ? 'API key' : 'Auth JSON'}
          multiline={authType === 'opencode_auth_json'}
          secureTextEntry={authType === 'api_key'}
          value={secret}
          onChangeText={setSecret}
        />
      ) : null}
      <Field label='Base URL' value={baseUrl} onChangeText={setBaseUrl} />
      <Textarea
        label='Model options'
        value={modelOptions}
        onChangeText={setModelOptions}
      />
      <SheetSelect
        disabled={!models.length}
        label='Default model'
        options={
          models.length
            ? models.map((model) => ({ label: model, value: model }))
            : [{ label: 'Add model options first', value: '' }]
        }
        value={models.includes(defaultModel) ? defaultModel : (models[0] ?? '')}
        onChange={setDefaultModel}
      />
      <SheetSelect
        label='Reasoning effort'
        options={[
          { label: 'None', value: 'none' },
          { label: 'Minimal', value: 'minimal' },
          { label: 'Low', value: 'low' },
          { label: 'Medium', value: 'medium' },
          { label: 'High', value: 'high' },
          { label: 'XHigh', value: 'xhigh' },
        ]}
        value={reasoningEffort}
        onChange={setReasoningEffort}
      />
      <SwitchRow label='Enabled' value={enabled} onValueChange={setEnabled} />
      <Button disabled={saving || !models.length} onPress={submit}>
        {saving ? 'Saving...' : 'Save provider'}
      </Button>
    </FormSection>
  );
};
