import { useEffect, useState, type FormEvent } from 'react';
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 { 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('C2 configuration saved', 'success');
      setToken('');
      setReplaceToken(false);
    } catch (err) {
      push(extractApiError(err, 'Could not save C2 configuration'), 'error');
    }
  };

  const onDelete = async () => {
    setShowDeleteConfirm(false);
    setTestResult(null);
    try {
      await deleteMutation.mutateAsync();
      push('C2 configuration removed', 'success');
      setUrl('');
      setToken('');
      setVerifyTls(false);
      setReplaceToken(false);
    } catch (err) {
      push(extractApiError(err, 'Could not remove C2 configuration'), 'error');
    }
  };

  const onTest = async () => {
    setTestResult(null);
    try {
      const result = await testMutation.mutateAsync();
      setTestResult({
        ok: result.ok,
        message: result.ok ? 'Connected' : (result.error ?? 'Connection failed'),
      });
    } catch (err) {
      setTestResult({ ok: false, message: extractApiError(err, 'Test failed') });
    }
  };

  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">C2 configuration</h2>

      {is503 && (
        <div
          role="alert"
          className="rounded-none px-xl py-md bg-fog border border-hairline text-[14px] text-charcoal"
        >
          C2 features are disabled (server has no encryption key configured).
        </div>
      )}

      {configQuery.isLoading ? (
        <p className="text-[14px] text-graphite">Loading…</p>
      ) : (
        <form onSubmit={onSave} noValidate className="flex flex-col gap-md">
          <FormField
            label="URL"
            htmlFor="c2-url"
            hint="HTTPS required (e.g. https://mythic.lab:7443)"
          >
            <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="API 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}
                >
                  Replace token
                </button>
              </div>
            ) : (
              <TextInput
                id="c2-token"
                data-testid="c2-token-input"
                type="password"
                name="api_token"
                placeholder={config?.has_token ? 'Enter new token' : 'API 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">
                Verify TLS certificate
              </label>
            </div>
            <p className="text-[12px] text-graphite">
              Uncheck only for lab Mythic with self-signed certificates. Disabling
              verification exposes the API token to MITM.
            </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 ? 'Saving…' : 'Save'}
            </button>

            <button
              type="button"
              data-testid="c2-test-btn"
              className="btn-outline"
              onClick={onTest}
              disabled={disabled || testMutation.isPending || !config}
            >
              {testMutation.isPending ? 'Testing…' : 'Test connection'}
            </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}
              >
                Delete configuration
              </button>
            )}
          </div>
        </form>
      )}

      {showDeleteConfirm && (
        <ConfirmDialog
          title="Delete C2 configuration"
          description="This will remove the C2 configuration for this engagement. The API token will be permanently deleted."
          confirmLabel="Delete"
          cancelLabel="Cancel"
          destructive
          onConfirm={onDelete}
          onCancel={() => setShowDeleteConfirm(false)}
        />
      )}
    </div>
  );
}
