'use client';

import { Badge } from '@tale/ui/badge';
import { Button } from '@tale/ui/button';
import { IconButton } from '@tale/ui/icon-button';
import { HStack, Stack } from '@tale/ui/layout';
import { Text } from '@tale/ui/text';
import { Loader2, Pencil, Save } from 'lucide-react';

import { CollapsibleGuide } from '@/app/components/ui/data-display/collapsible-guide';
import { Input } from '@/app/components/ui/forms/input';
import { Select } from '@/app/components/ui/forms/select';
import { Textarea } from '@/app/components/ui/forms/textarea';
import { useT } from '@/lib/i18n/client';
import { startCase } from '@/lib/utils/string';

import type { Integration } from '../../hooks/use-integration-manage';
import { SENSITIVE_KEYS, maskValue } from '../../hooks/use-integration-manage';
import { SlackSetupGuide } from './slack-setup-guide';
import { TestResultFeedback } from './test-result-feedback';

interface IntegrationCredentialsFormProps {
  integration: Integration;
  isSql: boolean;
  busy: boolean;
  isSavingOAuth2: boolean;
  selectedAuthMethod: string;
  supportedMethods: string[];
  hasMultipleAuthMethods: boolean;
  hasOAuth2Config: boolean;
  hasOAuth2Credentials: boolean;
  oauth2Fields: {
    authorizationUrl: string;
    tokenUrl: string;
    clientId: string;
    clientSecret: string;
    signingSecret: string;
    scopes: string;
  };
  oauth2FieldsComplete: boolean;
  isEditingOAuth2: boolean;
  credentials: Record<string, string>;
  displayBindings: string[];
  editableConfigFields: Array<{
    key: string;
    type: 'string' | 'number';
    defaultValue: string | number;
  }>;
  configValues: Record<string, string>;
  sqlConfig: Record<string, string>;
  testResult: { success: boolean; message: string } | null;
  onAuthMethodChange: (method: string) => void;
  onCredentialChange: (key: string, value: string) => void;
  onConfigValueChange: (key: string, value: string) => void;
  onSqlConfigChange: (key: string, value: string) => void;
  onOAuth2FieldChange: (
    field: keyof IntegrationCredentialsFormProps['oauth2Fields'],
    value: string,
  ) => void;
  onEditOAuth2: (editing: boolean) => void;
  onSaveOAuth2: () => void;
  onDismissTestResult: () => void;
}

export function IntegrationCredentialsForm({
  integration,
  isSql,
  busy,
  isSavingOAuth2,
  selectedAuthMethod,
  supportedMethods,
  hasMultipleAuthMethods,
  hasOAuth2Config,
  hasOAuth2Credentials,
  oauth2Fields,
  oauth2FieldsComplete,
  isEditingOAuth2,
  credentials,
  displayBindings,
  editableConfigFields,
  configValues,
  sqlConfig,
  testResult,
  onAuthMethodChange,
  onCredentialChange,
  onConfigValueChange,
  onSqlConfigChange,
  onOAuth2FieldChange,
  onEditOAuth2,
  onSaveOAuth2,
  onDismissTestResult,
}: IntegrationCredentialsFormProps) {
  const { t } = useT('settings');
  const { t: tCommon } = useT('common');
  const isSlack = integration.name === 'slack';

  return (
    <>
      {isSql && (
        <SqlConnectionSection
          integration={integration}
          sqlConfig={sqlConfig}
          busy={busy}
          onSqlConfigChange={onSqlConfigChange}
        />
      )}

      {typeof integration.setupGuide === 'string' && (
        <CollapsibleGuide
          label={t('integrations.manageDialog.setupGuide')}
          content={integration.setupGuide}
        />
      )}

      <Stack gap={3}>
        <HStack className="items-start justify-between">
          <Text variant="label">
            {t('integrations.manageDialog.authentication')}
          </Text>
          {selectedAuthMethod === 'oauth2' &&
            hasOAuth2Config &&
            hasOAuth2Credentials &&
            !isEditingOAuth2 && (
              <IconButton
                variant="secondary"
                icon={Pencil}
                iconSize={3}
                aria-label={t('integrations.manageDialog.updateCredentials')}
                onClick={() => onEditOAuth2(true)}
                disabled={busy}
              />
            )}
        </HStack>

        {hasMultipleAuthMethods && (
          <Select
            id="manage-auth-method"
            label={t('integrations.manageDialog.authenticationMethod')}
            options={supportedMethods.map((m) => ({
              value: m,
              label: t(`integrations.authMethods.${m}`),
            }))}
            value={selectedAuthMethod}
            onValueChange={onAuthMethodChange}
            disabled={busy}
          />
        )}

        {isSql && selectedAuthMethod === 'basic_auth' && (
          <>
            <Input
              id="manage-sql-username"
              label={t('integrations.manageDialog.username')}
              placeholder={integration.basicAuth?.username ?? ''}
              value={credentials['username'] ?? ''}
              onChange={(e) => onCredentialChange('username', e.target.value)}
              disabled={busy}
            />
            <Input
              id="manage-sql-password"
              label={t('integrations.manageDialog.password')}
              type="password"
              placeholder="••••••••"
              value={credentials['password'] ?? ''}
              onChange={(e) => onCredentialChange('password', e.target.value)}
              disabled={busy}
            />
          </>
        )}

        {isSlack &&
          selectedAuthMethod === 'oauth2' &&
          hasOAuth2Config &&
          !(hasOAuth2Credentials && !isEditingOAuth2) &&
          integration.organizationId && (
            <SlackSetupGuide organizationId={integration.organizationId} />
          )}

        {selectedAuthMethod === 'oauth2' &&
          hasOAuth2Config &&
          (hasOAuth2Credentials && !isEditingOAuth2 ? (
            <OAuth2CredentialsSummary
              integration={integration}
              isSlack={isSlack}
            />
          ) : (
            <OAuth2CredentialsEditor
              oauth2Fields={oauth2Fields}
              oauth2FieldsComplete={oauth2FieldsComplete}
              isEditingOAuth2={isEditingOAuth2}
              busy={busy}
              isSavingOAuth2={isSavingOAuth2}
              isSlack={isSlack}
              onFieldChange={onOAuth2FieldChange}
              onSave={onSaveOAuth2}
              onCancelEdit={() => onEditOAuth2(false)}
            />
          ))}

        {selectedAuthMethod === 'oauth2' && !hasOAuth2Config && (
          <>
            <Input
              id="manage-oauth2-access-token"
              label={t('integrations.manageDialog.accessToken')}
              type="password"
              placeholder="••••••••"
              value={credentials['accessToken'] ?? ''}
              onChange={(e) =>
                onCredentialChange('accessToken', e.target.value)
              }
              disabled={busy}
            />
            <Input
              id="manage-oauth2-refresh-token"
              label={t('integrations.manageDialog.refreshToken')}
              type="password"
              placeholder={t('integrations.manageDialog.optional')}
              value={credentials['refreshToken'] ?? ''}
              onChange={(e) =>
                onCredentialChange('refreshToken', e.target.value)
              }
              disabled={busy}
            />
          </>
        )}

        {displayBindings.map((binding) => {
          const isSensitive = SENSITIVE_KEYS.has(binding);
          return (
            <Input
              key={binding}
              id={`manage-credential-${binding}`}
              label={startCase(binding)}
              type={isSensitive ? 'password' : 'text'}
              placeholder={isSensitive ? '••••••••' : ''}
              value={credentials[binding] ?? ''}
              onChange={(e) => onCredentialChange(binding, e.target.value)}
              disabled={busy}
            />
          );
        })}

        {editableConfigFields.length > 0 && (
          <>
            <Text variant="label">
              {t('integrations.manageDialog.configuration')}
            </Text>
            {editableConfigFields.map((field) => (
              <Input
                key={field.key}
                id={`manage-config-${field.key}`}
                label={startCase(field.key)}
                type={field.type === 'number' ? 'number' : 'text'}
                placeholder={String(field.defaultValue)}
                value={configValues[field.key] ?? ''}
                onChange={(e) => onConfigValueChange(field.key, e.target.value)}
                disabled={busy}
              />
            ))}
          </>
        )}

        {testResult && (
          <TestResultFeedback
            result={testResult}
            onDismiss={onDismissTestResult}
            closeLabel={tCommon('aria.close')}
          />
        )}
      </Stack>
    </>
  );
}

function SqlConnectionSection({
  integration,
  sqlConfig,
  busy,
  onSqlConfigChange,
}: {
  integration: Integration;
  sqlConfig: Record<string, string>;
  busy: boolean;
  onSqlConfigChange: (key: string, value: string) => void;
}) {
  const { t } = useT('settings');

  return (
    <Stack gap={3}>
      <HStack gap={2} className="items-center">
        <Text variant="label">
          {t('integrations.manageDialog.databaseConnection')}
        </Text>
        {integration.sqlConnectionConfig?.engine && (
          <Badge variant="outline" className="ml-auto text-xs">
            {integration.sqlConnectionConfig.engine}
          </Badge>
        )}
      </HStack>
      <Input
        id="manage-sql-server"
        label={t('integrations.manageDialog.server')}
        placeholder={integration.sqlConnectionConfig?.server ?? '192.168.1.100'}
        value={sqlConfig['server'] ?? ''}
        onChange={(e) => onSqlConfigChange('server', e.target.value)}
        disabled={busy}
      />
      <HStack gap={3}>
        <Input
          id="manage-sql-port"
          label={t('integrations.manageDialog.port')}
          type="number"
          placeholder={String(integration.sqlConnectionConfig?.port ?? 1433)}
          value={sqlConfig['port'] ?? ''}
          onChange={(e) => onSqlConfigChange('port', e.target.value)}
          disabled={busy}
        />
        <Input
          id="manage-sql-database"
          label={t('integrations.manageDialog.database')}
          placeholder={integration.sqlConnectionConfig?.database ?? ''}
          value={sqlConfig['database'] ?? ''}
          onChange={(e) => onSqlConfigChange('database', e.target.value)}
          disabled={busy}
        />
      </HStack>
    </Stack>
  );
}

function OAuth2CredentialsSummary({
  integration,
  isSlack,
}: {
  integration: Integration;
  isSlack: boolean;
}) {
  const { t } = useT('settings');

  return (
    <Stack gap={2}>
      <HStack gap={2} className="text-muted-foreground items-center text-sm">
        <Text as="span" variant="body-sm" className="w-20 shrink-0">
          {t('integrations.manageDialog.clientId')}
        </Text>
        <Text as="span" variant="code" truncate>
          {maskValue(integration.oauth2Config?.clientId ?? '')}
        </Text>
      </HStack>
      <HStack gap={2} className="text-muted-foreground items-center text-sm">
        <Text as="span" variant="body-sm" className="w-20 shrink-0">
          {t('integrations.manageDialog.clientSecret')}
        </Text>
        <Text as="span" variant="code">
          {'\u00d7'.repeat(8)}
        </Text>
      </HStack>
      {isSlack && integration.oauth2Config?.signingSecretEncrypted && (
        <HStack gap={2} className="text-muted-foreground items-center text-sm">
          <Text as="span" variant="body-sm" className="w-20 shrink-0">
            {t('integrations.manageDialog.signingSecret')}
          </Text>
          <Text as="span" variant="code">
            {'\u00d7'.repeat(8)}
          </Text>
        </HStack>
      )}
      {integration.oauth2Config?.scopes &&
        integration.oauth2Config.scopes.length > 0 && (
          <HStack gap={2} className="text-muted-foreground items-start text-sm">
            <Text as="span" variant="body-sm" className="w-20 shrink-0">
              {t('integrations.manageDialog.scopes')}
            </Text>
            <Text as="span" variant="code" className="break-all">
              {integration.oauth2Config.scopes.join(', ')}
            </Text>
          </HStack>
        )}
    </Stack>
  );
}

function OAuth2CredentialsEditor({
  oauth2Fields,
  oauth2FieldsComplete,
  isEditingOAuth2,
  busy,
  isSavingOAuth2,
  isSlack,
  onFieldChange,
  onSave,
  onCancelEdit,
}: {
  oauth2Fields: {
    authorizationUrl: string;
    tokenUrl: string;
    clientId: string;
    clientSecret: string;
    signingSecret: string;
    scopes: string;
  };
  oauth2FieldsComplete: boolean;
  isEditingOAuth2: boolean;
  busy: boolean;
  isSavingOAuth2: boolean;
  isSlack: boolean;
  onFieldChange: (field: keyof typeof oauth2Fields, value: string) => void;
  onSave: () => void;
  onCancelEdit: () => void;
}) {
  const { t } = useT('settings');
  const { t: tCommon } = useT('common');

  return (
    <>
      <Input
        id="manage-oauth2-client-id"
        label={t('integrations.manageDialog.clientId')}
        value={oauth2Fields.clientId}
        onChange={(e) => onFieldChange('clientId', e.target.value)}
        disabled={busy}
      />
      <Input
        id="manage-oauth2-client-secret"
        label={t('integrations.manageDialog.clientSecret')}
        type="password"
        placeholder="••••••••"
        value={oauth2Fields.clientSecret}
        onChange={(e) => onFieldChange('clientSecret', e.target.value)}
        disabled={busy}
      />
      {isSlack && (
        <Input
          id="manage-oauth2-signing-secret"
          label={t('integrations.manageDialog.signingSecret')}
          type="password"
          placeholder="••••••••"
          description={t('integrations.manageDialog.signingSecretHelp')}
          value={oauth2Fields.signingSecret}
          onChange={(e) => onFieldChange('signingSecret', e.target.value)}
          disabled={busy}
        />
      )}
      <Textarea
        id="manage-oauth2-scopes"
        label={t('integrations.manageDialog.scopes')}
        placeholder="channels:read, channels:history"
        rows={3}
        value={oauth2Fields.scopes}
        onChange={(e) => onFieldChange('scopes', e.target.value)}
        disabled={busy}
      />
      <Button
        onClick={onSave}
        disabled={busy || !oauth2FieldsComplete}
        className="w-full"
      >
        {isSavingOAuth2 ? (
          <>
            <Loader2 className="mr-2 size-4 animate-spin" />
            {t('integrations.manageDialog.savingCredentials')}
          </>
        ) : (
          <>
            <Save className="mr-2 size-4" />
            {t('integrations.manageDialog.saveCredentials')}
          </>
        )}
      </Button>
      {isEditingOAuth2 && (
        <Button
          variant="secondary"
          size="sm"
          onClick={onCancelEdit}
          disabled={busy}
          className="w-full"
        >
          {tCommon('actions.cancel')}
        </Button>
      )}
    </>
  );
}
