import { useEffect, useState } from 'react';
import { Eye, EyeOff } from 'lucide-react';
import { Link, useNavigate, useParams } from 'react-router-dom';
import { Button, FormField, Input, Select, SectionHeader, Toggle, useToast } from '@cameleer/design-system';
import { PageLoader } from '../../components/PageLoader';
import {
  useOutboundConnection,
  useCreateOutboundConnection,
  useUpdateOutboundConnection,
  useTestOutboundConnection,
  type OutboundConnectionDto,
  type OutboundConnectionRequest,
  type OutboundConnectionTestResult,
  type OutboundMethod,
  type OutboundAuthKind,
  type TrustMode,
} from '../../api/queries/admin/outboundConnections';
import { useEnvironments } from '../../api/queries/admin/environments';
import sectionStyles from '../../styles/section-card.module.css';

// ── Form state ──────────────────────────────────────────────────────────

interface FormState {
  name: string;
  description: string;
  url: string;
  method: OutboundMethod;
  headers: Array<{ key: string; value: string }>;
  defaultBodyTmpl: string;
  tlsTrustMode: TrustMode;
  tlsCaPemPaths: string[];
  hmacSecret: string; // empty = keep existing (edit) / no secret (create)
  authKind: OutboundAuthKind;
  bearerToken: string;
  basicUsername: string;
  basicPassword: string;
  allowAllEnvs: boolean;
  allowedEnvIds: string[];
}

function initialForm(existing?: OutboundConnectionDto): FormState {
  return {
    name: existing?.name ?? '',
    description: existing?.description ?? '',
    url: existing?.url ?? 'https://',
    method: existing?.method ?? 'POST',
    headers: existing
      ? Object.entries(existing.defaultHeaders).map(([key, value]) => ({ key, value }))
      : [],
    defaultBodyTmpl: existing?.defaultBodyTmpl ?? '',
    tlsTrustMode: existing?.tlsTrustMode ?? 'SYSTEM_DEFAULT',
    tlsCaPemPaths: existing?.tlsCaPemPaths ?? [],
    hmacSecret: '',
    authKind: existing?.authKind ?? 'NONE',
    bearerToken: '',
    basicUsername: '',
    basicPassword: '',
    allowAllEnvs: !existing || existing.allowedEnvironmentIds.length === 0,
    allowedEnvIds: existing?.allowedEnvironmentIds ?? [],
  };
}

function toRequest(f: FormState): OutboundConnectionRequest {
  const defaultHeaders = Object.fromEntries(
    f.headers.filter((h) => h.key.trim()).map((h) => [h.key.trim(), h.value]),
  );
  const allowedEnvironmentIds = f.allowAllEnvs ? [] : f.allowedEnvIds;
  const auth =
    f.authKind === 'NONE'
      ? {}
      : f.authKind === 'BEARER'
        ? { tokenCiphertext: f.bearerToken }
        : { username: f.basicUsername, passwordCiphertext: f.basicPassword };
  return {
    name: f.name,
    description: f.description || null,
    url: f.url,
    method: f.method,
    defaultHeaders,
    defaultBodyTmpl: f.defaultBodyTmpl || null,
    tlsTrustMode: f.tlsTrustMode,
    tlsCaPemPaths: f.tlsCaPemPaths,
    hmacSecret: f.hmacSecret ? f.hmacSecret : null,
    auth,
    allowedEnvironmentIds,
  };
}

// ── Select option arrays ───────────────────────────────────────────────

const METHOD_OPTIONS: Array<{ value: OutboundMethod; label: string }> = [
  { value: 'POST', label: 'POST' },
  { value: 'PUT', label: 'PUT' },
  { value: 'PATCH', label: 'PATCH' },
];

const TRUST_OPTIONS: Array<{ value: TrustMode; label: string }> = [
  { value: 'SYSTEM_DEFAULT', label: 'System default (recommended)' },
  { value: 'TRUST_PATHS', label: 'Trust additional CA PEMs' },
  { value: 'TRUST_ALL', label: 'Trust all (INSECURE)' },
];

const AUTH_OPTIONS: Array<{ value: OutboundAuthKind; label: string }> = [
  { value: 'NONE', label: 'None' },
  { value: 'BEARER', label: 'Bearer token' },
  { value: 'BASIC', label: 'Basic' },
];

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

export default function OutboundConnectionEditor() {
  const { id } = useParams<{ id: string }>();
  const isNew = !id;
  const navigate = useNavigate();
  const { toast } = useToast();

  const existingQ = useOutboundConnection(isNew ? undefined : id);
  const envQ = useEnvironments();
  const createMut = useCreateOutboundConnection();
  // Hooks must be called unconditionally; pass placeholder id when unknown.
  const updateMut = useUpdateOutboundConnection(id ?? 'placeholder');
  const testMut = useTestOutboundConnection();

  const [form, setForm] = useState<FormState>(() => initialForm());
  const [initialized, setInitialized] = useState(isNew);
  const [testResult, setTestResult] = useState<OutboundConnectionTestResult | null>(null);
  const [showSecret, setShowSecret] = useState(false);

  useEffect(() => {
    if (!initialized && existingQ.data) {
      setForm(initialForm(existingQ.data));
      setInitialized(true);
    }
  }, [existingQ.data, initialized]);

  if (!isNew && existingQ.isLoading) return <PageLoader />;

  const isSaving = createMut.isPending || updateMut.isPending;

  const onSave = () => {
    const payload = toRequest(form);
    if (isNew) {
      createMut.mutate(payload, {
        onSuccess: () => {
          toast({ title: 'Created', description: form.name, variant: 'success' });
          navigate('/admin/outbound-connections');
        },
        onError: (e) => toast({ title: 'Create failed', description: String(e), variant: 'error' }),
      });
    } else {
      updateMut.mutate(payload, {
        onSuccess: () => toast({ title: 'Updated', description: form.name, variant: 'success' }),
        onError: (e) => toast({ title: 'Update failed', description: String(e), variant: 'error' }),
      });
    }
  };

  const onTest = () => {
    if (!id) return;
    testMut.mutate(id, {
      onSuccess: (r) => setTestResult(r),
      onError: (e) =>
        setTestResult({
          status: 0,
          latencyMs: 0,
          responseSnippet: null,
          tlsProtocol: null,
          tlsCipherSuite: null,
          peerCertificateSubject: null,
          peerCertificateExpiresAtEpochMs: null,
          error: String(e),
        }),
    });
  };

  const envs = envQ.data ?? [];

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
        <SectionHeader>
          {isNew ? 'New Outbound Connection' : `Edit: ${existingQ.data?.name ?? ''}`}
        </SectionHeader>
        <Link to="/admin/outbound-connections">
          <Button variant="secondary" size="sm">Back</Button>
        </Link>
      </div>

      <section className={sectionStyles.section} style={{ display: 'grid', gap: 16 }}>

        {/* Name */}
        <FormField label="Name" htmlFor="oc-name">
          <Input
            id="oc-name"
            value={form.name}
            onChange={(e) => setForm({ ...form, name: e.target.value })}
            placeholder="slack-ops"
          />
        </FormField>

        {/* Description */}
        <FormField label="Description" htmlFor="oc-description">
          <textarea
            id="oc-description"
            value={form.description}
            onChange={(e) => setForm({ ...form, description: e.target.value })}
            rows={2}
            style={{ width: '100%', boxSizing: 'border-box' }}
            placeholder="Optional description"
          />
        </FormField>

        {/* URL */}
        <FormField label="URL" htmlFor="oc-url">
          <Input
            id="oc-url"
            value={form.url}
            onChange={(e) => setForm({ ...form, url: e.target.value })}
            placeholder="https://hooks.slack.com/services/..."
          />
        </FormField>

        {/* Method */}
        <FormField label="Method" htmlFor="oc-method">
          <Select
            options={METHOD_OPTIONS}
            value={form.method}
            onChange={(e) => setForm({ ...form, method: e.target.value as OutboundMethod })}
          />
        </FormField>

        {/* Default headers */}
        <div>
          <div style={{ marginBottom: 4, fontWeight: 500, fontSize: '0.875rem' }}>Default headers</div>
          {form.headers.map((h, i) => (
            <div key={i} style={{ display: 'flex', gap: 8, marginTop: 4 }}>
              <Input
                value={h.key}
                onChange={(e) => {
                  const next = [...form.headers];
                  next[i] = { ...next[i], key: e.target.value };
                  setForm({ ...form, headers: next });
                }}
                placeholder="Header"
              />
              <Input
                value={h.value}
                onChange={(e) => {
                  const next = [...form.headers];
                  next[i] = { ...next[i], value: e.target.value };
                  setForm({ ...form, headers: next });
                }}
                placeholder="Value"
              />
              <Button
                variant="secondary"
                size="sm"
                onClick={() => setForm({ ...form, headers: form.headers.filter((_, idx) => idx !== i) })}
              >
                Remove
              </Button>
            </div>
          ))}
          <Button
            variant="secondary"
            size="sm"
            onClick={() => setForm({ ...form, headers: [...form.headers, { key: '', value: '' }] })}
            style={{ marginTop: 6 }}
          >
            Add header
          </Button>
        </div>

        {/* Default body template */}
        <FormField label="Default body template" htmlFor="oc-body">
          <textarea
            id="oc-body"
            value={form.defaultBodyTmpl}
            onChange={(e) => setForm({ ...form, defaultBodyTmpl: e.target.value })}
            rows={4}
            style={{ width: '100%', boxSizing: 'border-box', fontFamily: 'monospace', fontSize: '0.8125rem' }}
            placeholder={'{"text": "{{message}}"}'}
          />
        </FormField>

        {/* TLS trust mode */}
        <FormField label="TLS trust mode" htmlFor="oc-tls">
          <Select
            options={TRUST_OPTIONS}
            value={form.tlsTrustMode}
            onChange={(e) => setForm({ ...form, tlsTrustMode: e.target.value as TrustMode })}
          />
        </FormField>

        {form.tlsTrustMode === 'TRUST_ALL' && (
          <div style={{ background: 'var(--amber-bg, #fef3c7)', color: 'var(--amber, #92400e)', padding: '8px 12px', borderRadius: 4, fontSize: '0.875rem' }}>
            TLS certificate validation is DISABLED. Do not use TRUST_ALL in production.
          </div>
        )}

        {form.tlsTrustMode === 'TRUST_PATHS' && (
          <div>
            <div style={{ marginBottom: 4, fontWeight: 500, fontSize: '0.875rem' }}>CA PEM paths</div>
            {form.tlsCaPemPaths.map((p, i) => (
              <div key={i} style={{ display: 'flex', gap: 8, marginTop: 4 }}>
                <Input
                  value={p}
                  onChange={(e) => {
                    const next = [...form.tlsCaPemPaths];
                    next[i] = e.target.value;
                    setForm({ ...form, tlsCaPemPaths: next });
                  }}
                  placeholder="/etc/ssl/certs/my-ca.pem"
                />
                <Button
                  variant="secondary"
                  size="sm"
                  onClick={() =>
                    setForm({ ...form, tlsCaPemPaths: form.tlsCaPemPaths.filter((_, idx) => idx !== i) })
                  }
                >
                  Remove
                </Button>
              </div>
            ))}
            <Button
              variant="secondary"
              size="sm"
              onClick={() => setForm({ ...form, tlsCaPemPaths: [...form.tlsCaPemPaths, ''] })}
              style={{ marginTop: 6 }}
            >
              Add path
            </Button>
          </div>
        )}

        {/* HMAC secret */}
        <FormField
          label="HMAC secret"
          htmlFor="oc-hmac"
          hint={existingQ.data?.hmacSecretSet ? 'Leave blank to keep existing secret' : undefined}
        >
          <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
            <Input
              id="oc-hmac"
              type={showSecret ? 'text' : 'password'}
              value={form.hmacSecret}
              onChange={(e) => setForm({ ...form, hmacSecret: e.target.value })}
              placeholder={
                existingQ.data?.hmacSecretSet
                  ? '<secret set — leave blank to keep>'
                  : 'Optional signing secret'
              }
            />
            <Button variant="ghost" size="sm" onClick={() => setShowSecret((s) => !s)}>
              {showSecret ? <EyeOff size={14} /> : <Eye size={14} />}
            </Button>
          </div>
        </FormField>

        {/* Auth kind */}
        <FormField label="Auth" htmlFor="oc-auth">
          <Select
            options={AUTH_OPTIONS}
            value={form.authKind}
            onChange={(e) => setForm({ ...form, authKind: e.target.value as OutboundAuthKind })}
          />
        </FormField>

        {form.authKind === 'BEARER' && (
          <FormField label="Bearer token" htmlFor="oc-bearer">
            <Input
              id="oc-bearer"
              value={form.bearerToken}
              onChange={(e) => setForm({ ...form, bearerToken: e.target.value })}
              placeholder="Token stored encrypted at rest"
            />
          </FormField>
        )}

        {form.authKind === 'BASIC' && (
          <>
            <FormField label="Basic username" htmlFor="oc-basic-user">
              <Input
                id="oc-basic-user"
                value={form.basicUsername}
                onChange={(e) => setForm({ ...form, basicUsername: e.target.value })}
              />
            </FormField>
            <FormField label="Basic password" htmlFor="oc-basic-pass">
              <Input
                id="oc-basic-pass"
                type="password"
                value={form.basicPassword}
                onChange={(e) => setForm({ ...form, basicPassword: e.target.value })}
              />
            </FormField>
          </>
        )}

        {/* Allowed environments */}
        <div>
          <Toggle
            checked={form.allowAllEnvs}
            onChange={(e) => setForm({ ...form, allowAllEnvs: (e.target as HTMLInputElement).checked })}
            label="Allow in all environments"
          />
          {!form.allowAllEnvs && (
            <div style={{ display: 'grid', gap: 4, marginTop: 8, marginLeft: 4 }}>
              {envs.map((env) => (
                <label key={env.id} style={{ display: 'flex', gap: 8, alignItems: 'center', cursor: 'pointer', fontSize: '0.875rem' }}>
                  <input
                    type="checkbox"
                    checked={form.allowedEnvIds.includes(env.id)}
                    onChange={(e) => {
                      const next = e.target.checked
                        ? [...form.allowedEnvIds, env.id]
                        : form.allowedEnvIds.filter((x) => x !== env.id);
                      setForm({ ...form, allowedEnvIds: next });
                    }}
                  />
                  {env.displayName}
                </label>
              ))}
              {envs.length === 0 && (
                <span style={{ color: 'var(--text-muted, #6b7280)', fontSize: '0.875rem' }}>No environments found</span>
              )}
            </div>
          )}
        </div>

        {/* Actions */}
        <div style={{ display: 'flex', gap: 8, marginTop: 8 }}>
          <Button variant="primary" onClick={onSave} loading={isSaving} disabled={isSaving}>
            {isNew ? 'Create' : 'Save'}
          </Button>
          {!isNew && (
            <Button variant="secondary" onClick={onTest} loading={testMut.isPending} disabled={testMut.isPending}>
              {testMut.isPending ? 'Testing...' : 'Test'}
            </Button>
          )}
        </div>

        {/* Test result */}
        {testResult && (
          <section className={sectionStyles.section}>
            <SectionHeader>Test result</SectionHeader>
            {testResult.error ? (
              <div style={{ color: 'var(--error, #b91c1c)', fontSize: '0.875rem' }}>
                Error: {testResult.error}
              </div>
            ) : (
              <dl style={{ display: 'grid', gridTemplateColumns: 'max-content 1fr', gap: '4px 16px', fontSize: '0.875rem', margin: 0 }}>
                <dt>Status</dt><dd style={{ margin: 0 }}>{testResult.status}</dd>
                <dt>Latency</dt><dd style={{ margin: 0 }}>{testResult.latencyMs} ms</dd>
                <dt>TLS protocol</dt><dd style={{ margin: 0 }}>{testResult.tlsProtocol ?? '—'}</dd>
                {testResult.responseSnippet && (
                  <>
                    <dt>Response</dt>
                    <dd style={{ margin: 0 }}><code>{testResult.responseSnippet}</code></dd>
                  </>
                )}
              </dl>
            )}
          </section>
        )}
      </section>
    </div>
  );
}
