'use client';

/**
 * LlmProviderManager — admin CRUD for LLM provider credentials.
 */

import { useState } from 'react';
import { useT } from '@/lib/i18n/react';
import { HydratedIsland } from '@/components/HydratedIsland';
import { PageHeader } from '@/components/ui/layout/PageHeader';
import { Button } from '@/components/ui/primitives/Button';
import { Input } from '@/components/ui/primitives/Input';
import { FormField } from '@/components/ui/primitives/FormField';
import { Badge } from '@/components/ui/primitives/Badge';
import { PageShellSkeleton } from '@/components/ui/feedback/Skeleton';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { Row } from '@/components/ui/layout/Row';
import { Stack } from '@/components/ui/layout/Stack';
import {
  AlertDialog,
  AlertDialogContent,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogAction,
  AlertDialogCancel,
} from '@/components/ui/overlays/AlertDialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/primitives/Select';
import { useToast } from '@/components/ui/overlays/Toast';
import { interpolate } from '@/lib/i18n/interpolate';
import { QueryBoundary } from '@platform-modules/ui-primitives';
import {
  useProviders,
  useCreateProvider,
  useUpdateProvider,
  useDeleteProvider,
  useRefreshProviderModels,
  useTestProvider,
} from './internals/useAdminSupport';

type ProviderType = 'google' | 'openai-compat' | 'mock';

interface LlmProviderView {
  id: string;
  slug: string;
  name: string;
  type: ProviderType;
  baseUrl: string | null;
  isActive?: boolean;
}

interface ProviderFormState {
  slug: string;
  name: string;
  type: ProviderType;
  base_url: string;
  api_key: string;
}

const SLUG_PATTERN = /^[a-z0-9-]+$/;

function emptyForm(): ProviderFormState {
  return { slug: '', name: '', type: 'google', base_url: '', api_key: '' };
}

function RefreshModelsButton({ id, type }: { id: string; type: string }) {
  const t = useT('admin_support');
  const { toast } = useToast();
  const refresh = useRefreshProviderModels(id);
  const refreshPending = refresh.isPending;
  if (type === 'mock') {
    return (
      <Button variant="ghost" size="sm" disabled title={t('provider_refresh_builtin')}>
        {t('provider_refresh_builtin')}
      </Button>
    );
  }
  return (
    <Button
      variant="ghost"
      size="sm"
      disabled={refreshPending}
      onClick={() =>
        refresh.mutate(undefined, {
          onSuccess: (data) =>
            toast({
              title: interpolate(t('provider_refresh_success'), { count: data.models.length }),
              tone: 'success',
            }),
          onError: (e) =>
            toast({
              title: interpolate(t('provider_refresh_error'), {
                message: e instanceof Error ? e.message : String(e),
              }),
              tone: 'danger',
            }),
        })
      }
    >
      {refreshPending ? `${t('providers_refresh')}…` : t('providers_refresh')}
    </Button>
  );
}

function TestProviderButton({ id }: { id: string }) {
  const t = useT('admin_support');
  const { toast } = useToast();
  const testProvider = useTestProvider(id);
  return (
    <Button
      variant="ghost"
      size="sm"
      disabled={testProvider.isPending}
      onClick={() =>
        testProvider.mutate(undefined, {
          onSuccess: ({ data }) =>
            toast({
              title: data.ok
                ? interpolate(t('providers_test_success'), { response: data.response ?? '' })
                : interpolate(t('providers_test_failure'), { error: data.error ?? '' }),
              tone: data.ok ? 'success' : 'danger',
            }),
          onError: (error) =>
            toast({
              title: interpolate(t('providers_test_failure'), {
                error: error instanceof Error ? error.message : String(error),
              }),
              tone: 'danger',
            }),
        })
      }
    >
      {testProvider.isPending ? `${t('providers_test')}…` : t('providers_test')}
    </Button>
  );
}

function LlmProviderManagerInner() {
  const t = useT('admin_support');

  const providersQuery = useProviders();
  const create = useCreateProvider();

  const [editingId, setEditingId] = useState<string | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState<ProviderFormState>(emptyForm);
  const [formError, setFormError] = useState<string | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<{
    id: string;
    name: string;
    inUse: boolean;
  } | null>(null);
  const [deleteLoading, setDeleteLoading] = useState(false);

  const update = useUpdateProvider(editingId ?? '');
  const del = useDeleteProvider(deleteTarget?.id ?? '');

  function openCreate() {
    setEditingId(null);
    setForm(emptyForm());
    setFormError(null);
    setShowForm(true);
  }

  function openEdit(provider: LlmProviderView) {
    setEditingId(provider.id);
    setForm({
      slug: provider.slug,
      name: provider.name,
      type: provider.type,
      base_url: provider.baseUrl ?? '',
      api_key: '',
    });
    setFormError(null);
    setShowForm(true);
  }

  async function handleDeleteClick(provider: LlmProviderView) {
    setDeleteLoading(true);
    try {
      const [providerRes, definitionsRes] = await Promise.all([
        fetch(`/api/admin/support/providers/${provider.id}`),
        fetch('/api/admin/support/definitions'),
      ]);
      const providerJson = (await providerRes.json()) as Record<string, unknown>;
      const definitionsJson = (await definitionsRes.json()) as Record<string, unknown>;

      let inUse = false;
      if (definitionsJson.ok && Array.isArray(definitionsJson.definitions)) {
        for (const def of definitionsJson.definitions as Array<{
          llmChain?: { chain?: Array<{ llmProviderId?: string }> };
        }>) {
          const chain = def.llmChain?.chain ?? [];
          if (chain.some((entry) => entry.llmProviderId === provider.id)) {
            inUse = true;
            break;
          }
        }
      }

      const name = (providerJson.provider as LlmProviderView | undefined)?.name ?? provider.name;
      setDeleteTarget({ id: provider.id, name, inUse });
    } finally {
      setDeleteLoading(false);
    }
  }

  async function handleSubmit(e: React.SyntheticEvent<HTMLFormElement>) {
    e.preventDefault();
    setFormError(null);

    if (!form.name.trim()) {
      setFormError(t('providers_error_name_required'));
      return;
    }
    if (!editingId && !SLUG_PATTERN.test(form.slug)) {
      setFormError(t('providers_error_slug_invalid'));
      return;
    }
    if (form.type === 'openai-compat' && !form.base_url.trim()) {
      setFormError(t('providers_error_base_url_required'));
      return;
    }
    if (!editingId && !form.api_key.trim()) {
      setFormError(t('providers_error_api_key_required'));
      return;
    }

    try {
      if (editingId) {
        const payload: Record<string, unknown> = {
          name: form.name.trim(),
          type: form.type,
          base_url: form.type === 'openai-compat' ? form.base_url.trim() : null,
        };
        if (form.api_key.trim()) payload.api_key = form.api_key.trim();
        await update.mutateAsync(payload);
      } else {
        await create.mutateAsync({
          slug: form.slug.trim(),
          name: form.name.trim(),
          type: form.type,
          base_url: form.type === 'openai-compat' ? form.base_url.trim() : null,
          api_key: form.api_key.trim(),
        });
      }
      setShowForm(false);
      setEditingId(null);
      setForm(emptyForm());
    } catch (err) {
      setFormError(err instanceof Error ? err.message : String(err));
    }
  }

  if (showForm) {
    const isPending = create.isPending || update.isPending;
    return (
      <form onSubmit={handleSubmit} noValidate>
        <Stack gap="4">
          <Row gap="3" align="center">
            <Button
              type="button"
              variant="ghost"
              size="sm"
              onClick={() => {
                setShowForm(false);
                setEditingId(null);
                setForm(emptyForm());
              }}
            >
              {t('providers_back')}
            </Button>
            <PageHeader title={editingId ? t('providers_edit') : t('providers_add')} />
          </Row>

          {formError && <InlineNotice tone="danger" title={formError} />}

          <FormField label={t('providers_slug')} htmlFor="lpm-slug">
            <Input
              id="lpm-slug"
              dir="ltr"
              value={form.slug}
              disabled={!!editingId}
              onChange={(e) => setForm((f) => ({ ...f, slug: e.target.value }))}
              pattern="[a-z0-9-]+"
              required
            />
          </FormField>

          <FormField label={t('providers_name')} htmlFor="lpm-name">
            <Input
              id="lpm-name"
              value={form.name}
              onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}
              required
            />
          </FormField>

          <FormField label={t('providers_type')} htmlFor="lpm-type">
            <Select
              value={form.type}
              onValueChange={(v) => setForm((f) => ({ ...f, type: v as ProviderType }))}
            >
              <SelectTrigger id="lpm-type" className="w-full">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="google">{t('providers_type_google')}</SelectItem>
                <SelectItem value="openai-compat">{t('providers_type_openai')}</SelectItem>
                <SelectItem value="mock">{t('providers_type_mock_option')}</SelectItem>
              </SelectContent>
            </Select>
          </FormField>

          {form.type === 'openai-compat' && (
            <FormField label={t('providers_base_url')} htmlFor="lpm-base-url">
              <Input
                id="lpm-base-url"
                dir="ltr"
                value={form.base_url}
                onChange={(e) => setForm((f) => ({ ...f, base_url: e.target.value }))}
                required
              />
            </FormField>
          )}

          <FormField label={t('providers_api_key')} htmlFor="lpm-api-key">
            <Input
              id="lpm-api-key"
              type="password"
              dir="ltr"
              value={form.api_key}
              onChange={(e) => setForm((f) => ({ ...f, api_key: e.target.value }))}
              placeholder={t('providers_api_key_placeholder')}
              required={!editingId}
            />
            {editingId && (
              <p className="text-text-muted mt-1 text-xs">{t('providers_api_key_edit_help')}</p>
            )}
          </FormField>

          <Row justify="end" gap="2">
            <Button
              type="button"
              variant="ghost"
              size="sm"
              onClick={() => {
                setShowForm(false);
                setEditingId(null);
                setForm(emptyForm());
              }}
            >
              {t('providers_cancel')}
            </Button>
            <Button type="submit" variant="primary" size="sm" disabled={isPending}>
              {isPending ? `${t('providers_save')}…` : t('providers_save')}
            </Button>
          </Row>
        </Stack>
      </form>
    );
  }

  return (
    <QueryBoundary
      query={providersQuery}
      skeleton={<PageShellSkeleton />}
      errorFallback={() => <InlineNotice tone="danger" title={t('providers_load_error')} />}
    >
      {(resolved) => {
        const providers = (resolved.providers as LlmProviderView[] | undefined) ?? [];
        return (
          <Stack gap="4">
            <Row gap="3" align="center" className="flex-wrap">
              <PageHeader title={t('providers_title')} />
              <Button variant="primary" size="sm" onClick={openCreate}>
                {t('providers_add')}
              </Button>
            </Row>

            <div className="border-border-default overflow-hidden rounded-lg border">
              <table className="w-full text-sm">
                <thead className="bg-surface-raised text-text-muted text-xs uppercase">
                  <tr>
                    <th className="px-4 py-2 text-start font-medium">{t('providers_name')}</th>
                    <th className="px-4 py-2 text-start font-medium">{t('providers_type')}</th>
                    <th className="px-4 py-2 text-start font-medium">{t('providers_base_url')}</th>
                    <th className="px-4 py-2 text-start font-medium">{t('providers_status')}</th>
                    <th className="px-4 py-2 text-end font-medium" />
                  </tr>
                </thead>
                <tbody className="divide-border-default divide-y">
                  {providers.length === 0 ? (
                    <tr>
                      <td colSpan={5} className="text-text-muted px-4 py-8 text-center text-sm">
                        {t('providers_empty')}
                      </td>
                    </tr>
                  ) : (
                    providers.map((provider) => (
                      <tr key={provider.id} className="bg-surface-default">
                        <td className="px-4 py-3 font-medium">{provider.name}</td>
                        <td className="px-4 py-3">
                          <Badge
                            tone={
                              provider.type === 'mock'
                                ? 'warning'
                                : provider.type === 'google'
                                  ? 'neutral'
                                  : 'info'
                            }
                            size="sm"
                          >
                            {provider.type === 'google'
                              ? t('providers_type_google')
                              : provider.type === 'mock'
                                ? t('providers_type_mock')
                                : t('providers_type_openai')}
                          </Badge>
                        </td>
                        <td className="text-text-muted max-w-48 truncate px-4 py-3 font-mono text-xs">
                          {provider.type === 'openai-compat' && provider.baseUrl
                            ? provider.baseUrl
                            : '—'}
                        </td>
                        <td className="px-4 py-3">
                          <Badge
                            tone={provider.isActive !== false ? 'success' : 'neutral'}
                            size="sm"
                          >
                            {provider.isActive !== false
                              ? t('providers_active')
                              : t('providers_inactive')}
                          </Badge>
                        </td>
                        <td className="px-4 py-3">
                          <Row justify="end" gap="2">
                            <RefreshModelsButton id={provider.id} type={provider.type} />
                            <TestProviderButton id={provider.id} />
                            <Button variant="ghost" size="sm" onClick={() => openEdit(provider)}>
                              {t('providers_edit')}
                            </Button>
                            <Button
                              variant="ghost"
                              size="sm"
                              className="text-danger-500"
                              disabled={deleteLoading}
                              onClick={() => void handleDeleteClick(provider)}
                            >
                              {t('providers_delete')}
                            </Button>
                          </Row>
                        </td>
                      </tr>
                    ))
                  )}
                </tbody>
              </table>
            </div>

            <AlertDialog
              open={!!deleteTarget}
              onOpenChange={(open) => !open && setDeleteTarget(null)}
            >
              <AlertDialogContent>
                <AlertDialogTitle>{t('providers_delete_confirm')}</AlertDialogTitle>
                <AlertDialogDescription>
                  {deleteTarget?.inUse ? (
                    <span className="text-feedback-warning">{t('providers_in_use_warning')}</span>
                  ) : (
                    t('providers_delete_body').replace('{name}', deleteTarget?.name ?? '')
                  )}
                </AlertDialogDescription>
                <AlertDialogCancel>{t('providers_cancel')}</AlertDialogCancel>
                <AlertDialogAction
                  disabled={deleteTarget?.inUse}
                  onClick={async () => {
                    await del.mutateAsync();
                    setDeleteTarget(null);
                  }}
                >
                  {t('providers_delete')}
                </AlertDialogAction>
              </AlertDialogContent>
            </AlertDialog>
          </Stack>
        );
      }}
    </QueryBoundary>
  );
}

export function LlmProviderManager() {
  return (
    <HydratedIsland>
      <LlmProviderManagerInner />
    </HydratedIsland>
  );
}
