import { useEffect, useState, type FormEvent } from 'react';
import { useTranslation } from 'react-i18next';
import { extractApiError } from '@/api/client';
import { useC2Config, useDeleteC2Config, useTestC2Config, useUpdateC2Config } from '@/hooks/useC2';
import { ConfirmDialog } from './ConfirmDialog';
import { FormField, TextInput } from './FormField';
import { useToast } from '@/hooks/useToast';

interface C2ConfigCardProps {
  engagementId: number;
}

export function C2ConfigCard({ engagementId }: C2ConfigCardProps): JSX.Element {
  const { t } = useTranslation();
  const { push } = useToast();

  const configQuery = useC2Config(engagementId);
  const updateMutation = useUpdateC2Config(engagementId);
  const deleteMutation = useDeleteC2Config(engagementId);
  const testMutation = useTestC2Config(engagementId);

  const config = configQuery.data;
  const is503 = configQuery.error
    ? (configQuery.error as { response?: { status?: number } })?.response?.status === 503
    : false;

  const [url, setUrl] = useState('');
  const [token, setToken] = useState('');
  const [verifyTls, setVerifyTls] = useState(false);
  const [replaceToken, setReplaceToken] = useState(false);
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
  const [testResult, setTestResult] = useState<{ ok: boolean; message: string } | null>(null);

  // Sync URL and verifyTls from loaded config (but not token — write-only at API level)
  useEffect(() => {
    if (config) {
      setUrl(config.url);
      setVerifyTls(config.verify_tls);
    }
  }, [config]);

  const disabled = is503 || configQuery.isLoading;

  const onSave = async (e: FormEvent) => {
    e.preventDefault();
    if (is503) return;
    setTestResult(null);

    const input: { url: string; verify_tls: boolean; api_token?: string } = {
      url: url.trim(),
      verify_tls: verifyTls,
    };
    // Send token only if: no existing config, OR user explicitly chose to replace
    if (!config?.has_token || replaceToken) {
      if (token.trim()) input.api_token = token.trim();
    }

    try {
      await updateMutation.mutateAsync(input);
      push(t('c2.config.toast.saved'), 'success');
      setToken('');
      setReplaceToken(false);
    } catch (err) {
      push(extractApiError(err, t('c2.config.error.save')), 'error');
    }
  };

  const onDelete = async () => {
    setShowDeleteConfirm(false);
    setTestResult(null);
    try {
      await deleteMutation.mutateAsync();
      push(t('c2.config.toast.deleted'), 'success');
      setUrl('');
      setToken('');
      setVerifyTls(false);
      setReplaceToken(false);
    } catch (err) {
      push(extractApiError(err, t('c2.config.error.delete')), 'error');
    }
  };

  const onTest = async () => {
    setTestResult(null);
    try {
      const result = await testMutation.mutateAsync();
      setTestResult({
        ok: result.ok,
        message: result.ok ? t('c2.config.connected') : (result.error ?? t('c2.config.connectionFailed')),
      });
    } catch (err) {
      setTestResult({ ok: false, message: extractApiError(err, t('c2.config.connectionFailed')) });
    }
  };

  const submitting = updateMutation.isPending || deleteMutation.isPending;

  return (
    <div
      data-testid="c2-config-card"
      className="card-product flex flex-col gap-md"
    >
      <h2 className="text-[20px] font-medium text-ink">{t('c2.config.title')}</h2>

      {is503 && (
        <div
          role="alert"
          className="rounded-none px-xl py-md bg-fog border border-hairline text-[14px] text-charcoal"
        >
          {t('c2.config.disabled')}
        </div>
      )}

      {configQuery.isLoading ? (
        <p className="text-[14px] text-graphite">{t('c2.config.loading')}</p>
      ) : (
        <form onSubmit={onSave} noValidate className="flex flex-col gap-md">
          <FormField
            label={t('c2.config.field.url')}
            htmlFor="c2-url"
            hint={t('c2.config.field.urlHint')}
          >
            <TextInput
              id="c2-url"
              data-testid="c2-url-input"
              type="url"
              name="url"
              placeholder="https://mythic.lab:7443"
              value={url}
              onChange={(e) => setUrl(e.target.value)}
              disabled={disabled}
            />
          </FormField>

          <FormField label={t('c2.config.field.token')} htmlFor="c2-token">
            {config?.has_token && !replaceToken ? (
              <div className="flex items-center gap-md">
                <TextInput
                  id="c2-token"
                  data-testid="c2-token-input"
                  type="password"
                  name="api_token"
                  placeholder="••••••••"
                  value=""
                  readOnly
                  disabled={disabled}
                />
                <button
                  type="button"
                  className="btn-text-link text-[14px] whitespace-nowrap"
                  onClick={() => setReplaceToken(true)}
                  disabled={disabled}
                >
                  {t('c2.config.btn.replaceToken')}
                </button>
              </div>
            ) : (
              <TextInput
                id="c2-token"
                data-testid="c2-token-input"
                type="password"
                name="api_token"
                placeholder={config?.has_token ? t('c2.config.field.tokenHint') : t('c2.config.field.token')}
                value={token}
                onChange={(e) => setToken(e.target.value)}
                disabled={disabled}
              />
            )}
          </FormField>

          <div className="flex flex-col gap-xs">
            <div className="flex items-center gap-sm">
              <input
                id="c2-verify-tls"
                data-testid="c2-verify-tls"
                type="checkbox"
                checked={verifyTls}
                onChange={(e) => setVerifyTls(e.target.checked)}
                disabled={disabled}
                className="h-4 w-4 accent-primary"
              />
              <label htmlFor="c2-verify-tls" className="text-[14px] text-ink">
                {t('c2.config.field.verifyTls')}
              </label>
            </div>
            <p className="text-[12px] text-graphite">
              {t('c2.config.field.verifyTlsHint')}
            </p>
          </div>

          <div className="flex items-center gap-md flex-wrap">
            <button
              type="submit"
              data-testid="c2-save-btn"
              className="btn-primary"
              disabled={disabled || submitting}
            >
              {updateMutation.isPending ? t('c2.config.btn.saving') : t('c2.config.btn.save')}
            </button>

            <button
              type="button"
              data-testid="c2-test-btn"
              className="btn-outline"
              onClick={onTest}
              disabled={disabled || testMutation.isPending || !config}
            >
              {testMutation.isPending ? t('c2.config.btn.testing') : t('c2.config.btn.test')}
            </button>

            {testResult !== null && (
              <span
                className={`text-[14px] ${testResult.ok ? 'text-success' : 'text-bloom-deep'}`}
              >
                {testResult.message}
              </span>
            )}

            {config?.has_token && (
              <button
                type="button"
                data-testid="c2-delete-btn"
                className="btn-text-link text-bloom-deep ml-auto"
                onClick={() => setShowDeleteConfirm(true)}
                disabled={disabled || submitting}
              >
                {t('c2.config.btn.delete')}
              </button>
            )}
          </div>
        </form>
      )}

      {showDeleteConfirm && (
        <ConfirmDialog
          title={t('c2.config.deleteConfirm.title')}
          description={t('c2.config.deleteConfirm.desc')}
          confirmLabel={t('c2.config.deleteConfirm.confirm')}
          cancelLabel={t('c2.config.deleteConfirm.cancel')}
          destructive
          onConfirm={onDelete}
          onCancel={() => setShowDeleteConfirm(false)}
        />
      )}
    </div>
  );
}
