'use client';

import { useState, useEffect, useId, useCallback, type SubmitEvent } from 'react';
import { Card } from '@/components/ui/layout/Card/Card';
import { Button } from '@/components/ui/primitives/Button/Button';
import { Input } from '@/components/ui/primitives/Input/Input';
import { Label } from '@/components/ui/primitives/Label/Label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/primitives/Select/Select';
import { InlineNotice } from '@/components/ui/feedback/InlineNotice';
import { useLocale, useT } from '@/lib/i18n/react';
import type { StringBundle } from '@/lib/i18n';
import { formatDateTime } from '@/lib/format';
import { getCsrfToken } from '@/lib/csrf';
import { captureCaught } from '@/lib/observability';
import { VendorShell } from '@/components/ui/layout/VendorShell';
import { HydratedIsland } from '@/components/HydratedIsland';
import { VendorSettingsRouteNav } from '@/features/vendor-settings/VendorSettingsRouteNav';

// ─── Types ────────────────────────────────────────────────────────────────────

interface ProviderInfo {
  kind: string;
  label?: string;
  implemented: boolean;
  credentialsFields?: string[];
}

interface InvoicingSettings {
  provider: string;
  lastTestAt?: string;
  lastTestOk?: boolean;
}

type VendorInvoicingT = (key: keyof StringBundle['vendor_invoicing']) => string;

type TestResult = {
  ok: boolean;
  message: string;
  code?: string;
};

const CREDENTIAL_LABEL_KEYS: Record<string, keyof StringBundle['vendor_invoicing']> = {
  apiUser: 'cred_apiUser',
  apiPass: 'cred_apiPass',
  companyId: 'cred_companyId',
};

const TEST_ERROR_KEYS: Record<string, keyof StringBundle['vendor_invoicing']> = {
  invalid_credentials: 'test_error_invalid_credentials',
  connection_timeout: 'test_error_connection_timeout',
};

// ─── Component ────────────────────────────────────────────────────────────────

export function InvoicingSettingsForm() {
  const t = useT('vendor_invoicing');
  const tCommon = useT('common');
  const { locale } = useLocale();

  const [providers, setProviders] = useState<ProviderInfo[]>([]);
  const [providersLoading, setProvidersLoading] = useState(true);
  const [providersError, setProvidersError] = useState(false);
  const [settings, setSettings] = useState<InvoicingSettings | null>(null);
  const [selectedProvider, setSelectedProvider] = useState('self_handled');
  const [credentials, setCredentials] = useState<Record<string, string>>({});
  const [saving, setSaving] = useState(false);
  const [testing, setTesting] = useState(false);
  const [testResult, setTestResult] = useState<TestResult | null>(null);
  const [saveError, setSaveError] = useState<string | null>(null);

  const selectId = useId();
  const testRegionId = useId();

  const loadProviders = useCallback(async () => {
    setProvidersLoading(true);
    setProvidersError(false);

    try {
      const [providerResponse, settingsResponse] = await Promise.all([
        fetch('/api/vendor/invoicing/providers'),
        fetch('/api/vendor/invoicing/settings'),
      ]);
      if (!providerResponse.ok) throw new Error(`providers ${providerResponse.status}`);
      if (!settingsResponse.ok) throw new Error(`settings ${settingsResponse.status}`);
      const [providerList, currentSettings] = await Promise.all([
        providerResponse.json() as Promise<ProviderInfo[]>,
        settingsResponse.json() as Promise<InvoicingSettings>,
      ]);
      setProviders(providerList);
      setSettings(currentSettings);
      if (currentSettings?.provider) {
        setSelectedProvider(currentSettings.provider);
      }
    } catch (err) {
      captureCaught(err instanceof Error ? err : new Error(String(err)), {
        scope: 'InvoicingSettingsForm.load',
        severity: 'warning',
      });
      setProvidersError(true);
    } finally {
      setProvidersLoading(false);
    }
  }, []);

  // ─── Load providers + current settings ──────────────────────────────────────

  useEffect(() => {
    void Promise.resolve().then(() => loadProviders());
  }, [loadProviders]);

  // ─── Helpers ─────────────────────────────────────────────────────────────────

  function handleCredentialChange(field: string, value: string) {
    setCredentials((prev) => ({ ...prev, [field]: value }));
  }

  function credentialLabel(field: string, translate: VendorInvoicingT): string {
    const key = CREDENTIAL_LABEL_KEYS[field];
    return key ? translate(key) : field;
  }

  function credentialInputType(field: string): 'text' | 'password' {
    if (field === 'companyId' || field === 'apiUser') return 'text';
    if (field.includes('pass') || field === 'apiPass') return 'password';
    return 'text';
  }

  function formatTestFailure(code: string | undefined, translate: VendorInvoicingT): TestResult {
    const errorKey = code ? TEST_ERROR_KEYS[code] : undefined;
    if (errorKey) {
      return { ok: false, message: translate(errorKey) };
    }
    if (code) {
      return {
        ok: false,
        message: translate('test_error_unknown'),
        code,
      };
    }
    return { ok: false, message: translate('test_fail') };
  }

  // ─── Save handler ────────────────────────────────────────────────────────────

  async function handleSave(e: SubmitEvent<HTMLFormElement>) {
    e.preventDefault();
    setSaving(true);
    setSaveError(null);

    try {
      const body: { provider: string; credentials?: Record<string, string> } = {
        provider: selectedProvider,
      };

      if (Object.keys(credentials).length > 0) {
        body.credentials = credentials;
      }

      const res = await fetch('/api/vendor/invoicing/settings', {
        method: 'PUT',
        headers: {
          'content-type': 'application/json',
          'x-csrf-token': getCsrfToken(),
        },
        body: JSON.stringify(body),
      });

      if (!res.ok) {
        const err = (await res.json().catch((parseErr) => {
          captureCaught(parseErr instanceof Error ? parseErr : new Error(String(parseErr)), {
            scope: 'InvoicingSettingsForm.handleSave',
            severity: 'warning',
          });
          return {};
        })) as { error?: string };
        setSaveError(err?.error ?? t('error_saving'));
      } else {
        // Refresh settings to reflect saved state
        const updated = (await res.json()) as InvoicingSettings;
        setSettings(updated);
        setCredentials({});
      }
    } catch (err) {
      captureCaught(err instanceof Error ? err : new Error(String(err)), {
        scope: 'InvoicingSettingsForm.handleSave',
        severity: 'warning',
      });
      setSaveError(t('network_error'));
    } finally {
      setSaving(false);
    }
  }

  // ─── Test-connection handler ──────────────────────────────────────────────────

  async function handleTestConnection() {
    setTesting(true);
    setTestResult(null);

    try {
      const body: { kind?: string; credentials?: Record<string, string> } = {
        kind: selectedProvider,
      };

      if (Object.keys(credentials).length > 0) {
        body.credentials = credentials;
      }

      const res = await fetch('/api/vendor/invoicing/test-connection', {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
          'x-csrf-token': getCsrfToken(),
        },
        body: JSON.stringify(body),
      });

      const json = (await res.json()) as {
        ok: boolean;
        error?: string;
        code?: string;
      };

      if (json.ok) {
        setTestResult({ ok: true, message: t('test_ok') });
      } else {
        setTestResult(formatTestFailure(json.code ?? json.error, t));
      }
    } catch (err) {
      captureCaught(err instanceof Error ? err : new Error(String(err)), {
        scope: 'InvoicingSettingsForm.handleTestConnection',
        severity: 'warning',
      });
      setTestResult({ ok: false, message: t('test_fail') });
    } finally {
      setTesting(false);
    }
  }

  // ─── Derived state ────────────────────────────────────────────────────────────

  const activeProvider = providers.find((p) => p.kind === selectedProvider);
  const credentialFields = activeProvider?.credentialsFields ?? [];
  const hasCredentialFields = credentialFields.length > 0;
  const implementedProviders = providers.filter((p) => p.implemented);

  function providerLabel(kind: string): string {
    const key = `provider_${kind}` as Parameters<typeof t>[0];
    try {
      return t(key);
    } catch (err) {
      captureCaught(err instanceof Error ? err : new Error(String(err)), {
        scope: 'InvoicingSettingsForm.providerLabel',
        severity: 'warning',
      });
      return kind;
    }
  }

  // ─── Render ───────────────────────────────────────────────────────────────────

  return (
    <HydratedIsland>
      <VendorShell variant="dashboard" currentPath="/vendor/settings/invoicing">
        <div className="flex flex-col gap-6 p-4 lg:p-6">
          <VendorSettingsRouteNav activeId="invoicing" />
          <Card padding="lg">
            <form onSubmit={handleSave} className="flex flex-col gap-6">
              {/* Title */}
              <h2 className="text-xl font-bold text-[var(--text-primary)]">{t('title')}</h2>

              {/* Provider selector */}
              <div className="flex flex-col gap-2">
                <Label htmlFor={selectId}>{t('provider_label')}</Label>
                {providersError ? (
                  <div className="flex flex-col gap-2">
                    <p className="text-sm text-[var(--color-error)]">{t('providers_load_error')}</p>
                    <Button type="button" variant="secondary" onClick={() => void loadProviders()}>
                      {tCommon('retry')}
                    </Button>
                  </div>
                ) : (
                  <Select
                    value={selectedProvider}
                    onValueChange={setSelectedProvider}
                    disabled={providersLoading}
                  >
                    <SelectTrigger id={selectId} aria-label={t('provider_label')}>
                      <SelectValue
                        placeholder={providersLoading ? t('providers_loading') : undefined}
                      />
                    </SelectTrigger>
                    <SelectContent>
                      {providersLoading ? (
                        <SelectItem value={selectedProvider} disabled>
                          {t('providers_loading')}
                        </SelectItem>
                      ) : (
                        implementedProviders.map((p) => (
                          <SelectItem key={p.kind} value={p.kind}>
                            {providerLabel(p.kind)}
                          </SelectItem>
                        ))
                      )}
                    </SelectContent>
                  </Select>
                )}
                <p className="text-text-secondary text-sm">{t('provider_help')}</p>
                {selectedProvider === 'self_handled' && (
                  <InlineNotice tone="warning" description={t('self_handled_notice')} />
                )}
              </div>

              {/* Dynamic credential fields */}
              {hasCredentialFields && (
                <fieldset className="flex flex-col gap-4 border-0 p-0">
                  <legend className="mb-2 text-sm font-semibold text-[var(--text-secondary)]">
                    {t('credentials_section')}
                  </legend>
                  {credentialFields.map((field) => {
                    const label = credentialLabel(field, t);
                    const inputType = credentialInputType(field);
                    return (
                      <div key={field} className="flex flex-col gap-1">
                        <Label htmlFor={`cred-${field}`}>{label}</Label>
                        <Input
                          id={`cred-${field}`}
                          type={inputType}
                          autoComplete="off"
                          value={credentials[field] ?? ''}
                          onChange={(e) => handleCredentialChange(field, e.target.value)}
                          aria-label={label}
                          placeholder={inputType === 'password' ? '••••••••' : undefined}
                        />
                      </div>
                    );
                  })}
                </fieldset>
              )}

              {/* Last test status */}
              {settings?.lastTestAt && (
                <p className="text-sm text-[var(--text-secondary)]">
                  {t('last_test')}: {formatDateTime(settings.lastTestAt, locale)}
                  {' — '}
                  {settings.lastTestOk ? (
                    <span className="text-[var(--color-success)]">{t('test_ok')}</span>
                  ) : (
                    <span className="text-[var(--color-error)]">{t('test_fail')}</span>
                  )}
                </p>
              )}

              {/* Inline test result (aria-live) */}
              <div
                id={testRegionId}
                aria-live="polite"
                aria-atomic="true"
                className="min-h-[1.25rem] text-sm"
              >
                {testResult && (
                  <span
                    className={
                      testResult.ok ? 'text-[var(--color-success)]' : 'text-[var(--color-error)]'
                    }
                  >
                    {testResult.message}
                    {!testResult.ok && testResult.code && (
                      <span className="text-text-muted ms-2 text-xs">{testResult.code}</span>
                    )}
                  </span>
                )}
              </div>

              {/* Save error */}
              {saveError && (
                <p role="alert" className="text-sm text-[var(--color-error)]">
                  {saveError}
                </p>
              )}

              {/* Action buttons */}
              <div className="flex flex-wrap gap-3">
                <Button type="submit" disabled={saving || providersLoading || providersError}>
                  {saving ? t('saving') : t('save')}
                </Button>

                {hasCredentialFields && (
                  <Button
                    type="button"
                    variant="secondary"
                    onClick={handleTestConnection}
                    disabled={testing}
                    aria-controls={testRegionId}
                  >
                    {testing ? t('testing') : t('test_connection')}
                  </Button>
                )}
              </div>
            </form>
          </Card>
        </div>
      </VendorShell>
    </HydratedIsland>
  );
}
