import {
  CopyOutlined,
  DeleteOutlined,
  EditOutlined,
  KeyOutlined,
  PlusOutlined,
  ReloadOutlined,
  ThunderboltOutlined
} from '@ant-design/icons';
import {
  Alert,
  App as AntApp,
  Button,
  Checkbox,
  Descriptions,
  Drawer,
  Form,
  Input,
  Modal,
  Popconfirm,
  Select,
  Skeleton,
  Space,
  Switch,
  Table,
  Tag,
  Typography
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom';

import { CodeBlock } from '../components/common/CodeBlock';
import { EmptyState } from '../components/common/EmptyState';
import { PageHeader } from '../components/common/PageHeader';
import { SectionCard } from '../components/common/SectionCard';
import { StatusPill } from '../components/common/StatusPill';
import type { StatusTone } from '../components/common/StatusPill';
import { useI18n } from '../frontend/i18n/react';
import { detailHistoryLocation, detailHistoryState } from '../frontend/navigation-state';
import { api } from '../frontend/services/api';
import type {
  Domain,
  InboundMailbox,
  Webhook,
  WebhookDelivery,
  WebhookDeliveryStatus,
  WebhookEvent,
  WebhookPayload
} from '../frontend/types';

const DELIVERY_EVENTS: WebhookEvent[] = ['sent', 'bounced', 'failed', 'opened', 'clicked'];
const ALL_EVENTS: WebhookEvent[] = [...DELIVERY_EVENTS, 'received'];
const DELIVERY_STATUSES: WebhookDeliveryStatus[] = ['pending', 'processing', 'success', 'dead'];

interface WebhooksProps {
  /** When set, list/create are scoped to this domain (no global page chrome). */
  domainId?: number;
  /** When set, only receipt callbacks for this mailbox are shown. */
  mailboxId?: number;
  domains?: Domain[];
  mailboxes?: InboundMailbox[];
  onCopy?: (value: string) => void;
}

interface WebhookFormValues {
  name: string;
  url: string;
  events: WebhookEvent[];
  domainId?: number | null;
  enabled: boolean;
}

interface SecretReveal {
  webhook: Webhook;
  mode: 'created' | 'rotated';
}

export default function Webhooks({ domainId: domainIdProp, mailboxId: mailboxIdProp, domains = [], mailboxes = [], onCopy }: WebhooksProps) {
  const { message } = AntApp.useApp();
  const { t } = useI18n();
  const location = useLocation();
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const queryDomainId = Number(searchParams.get('domainId') || 0) || undefined;
  const queryMailboxId = Number(searchParams.get('mailboxId') || 0) || undefined;
  const requestedWebhookId = positiveInteger(searchParams.get('webhookId'));
  const deliveryStatus = deliveryStatusFromParam(searchParams.get('deliveryStatus'));
  const deliveryEvent = deliveryEventFromParam(searchParams.get('deliveryEvent'));
  const domainId = domainIdProp ?? queryDomainId;
  const mailboxId = mailboxIdProp ?? queryMailboxId;
  const embedded = domainIdProp != null || mailboxIdProp != null;
  const [webhooks, setWebhooks] = useState<Webhook[]>([]);
  const [recentDeliveries, setRecentDeliveries] = useState<WebhookDelivery[]>([]);
  const [detailDeliveries, setDetailDeliveries] = useState<WebhookDelivery[]>([]);
  const [detailLoading, setDetailLoading] = useState(false);
  const [detailError, setDetailError] = useState('');
  const [availableDomains, setAvailableDomains] = useState<Domain[]>(domains);
  const [availableMailboxes, setAvailableMailboxes] = useState<InboundMailbox[]>(mailboxes);
  const [loading, setLoading] = useState(true);
  const [loadError, setLoadError] = useState('');
  const [resourceError, setResourceError] = useState('');
  const [recentDeliveriesError, setRecentDeliveriesError] = useState('');
  const [actionKey, setActionKey] = useState('');
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [editing, setEditing] = useState<Webhook | null>(null);
  const [secretReveal, setSecretReveal] = useState<SecretReveal | null>(null);
  const [form] = Form.useForm<WebhookFormValues>();
  const loadRequestId = useRef(0);
  const detailRequestId = useRef(0);

  const mailboxScoped = mailboxId != null;
  const scoped = domainId != null || mailboxScoped;
  const selectableEvents: WebhookEvent[] = mailboxScoped ? ['received'] : DELIVERY_EVENTS;
  const domainMap = useMemo(() => new Map(availableDomains.map((d) => [d.id, d.domain])), [availableDomains]);
  const mailboxMap = useMemo(() => new Map(availableMailboxes.map((m) => [m.id, m.address])), [availableMailboxes]);
  const selectedWebhook = useMemo(
    () => requestedWebhookId ? webhooks.find((webhook) => webhook.id === requestedWebhookId) || null : null,
    [requestedWebhookId, webhooks]
  );

  const loadData = useCallback(async () => {
    const requestId = ++loadRequestId.current;
    setLoading(true);
    setLoadError('');
    setResourceError('');
    setRecentDeliveriesError('');
    const shouldLoadResources = !domains.length || !mailboxes.length;
    const [webhooksResult, deliveriesResult, domainsResult, mailboxesResult] = await Promise.allSettled([
      api.webhooks(mailboxScoped ? undefined : (domainId != null ? domainId : undefined), mailboxId),
      api.webhookDeliveries({ limit: 100 }),
      shouldLoadResources ? api.domains() : Promise.resolve(null),
      shouldLoadResources ? api.inboundMailboxes() : Promise.resolve(null)
    ]);
    if (requestId !== loadRequestId.current) return;

    let nextWebhooks: Webhook[] = [];
    if (webhooksResult.status === 'fulfilled') {
      nextWebhooks = (webhooksResult.value.webhooks || []).filter((webhook) => scoped || webhook.mailboxId == null);
      setWebhooks(nextWebhooks);
    } else {
      setLoadError(webhooksResult.reason instanceof Error ? webhooksResult.reason.message : t('common.error'));
    }

    if (deliveriesResult.status === 'fulfilled') {
      const webhookIds = new Set(nextWebhooks.map((w) => w.id));
      const nextDeliveries = (deliveriesResult.value.deliveries || []).filter((d) =>
        scoped ? webhookIds.has(d.webhookId) : true
      );
      setRecentDeliveries(nextDeliveries);
    } else {
      setRecentDeliveriesError(deliveriesResult.reason instanceof Error ? deliveriesResult.reason.message : t('common.error'));
    }

    const resourceFailures: string[] = [];
    if (domainsResult.status === 'fulfilled') {
      if (domainsResult.value) setAvailableDomains(domainsResult.value.domains || []);
    } else {
      resourceFailures.push(domainsResult.reason instanceof Error ? domainsResult.reason.message : t('common.error'));
    }
    if (mailboxesResult.status === 'fulfilled') {
      if (mailboxesResult.value) setAvailableMailboxes(mailboxesResult.value.mailboxes || []);
    } else {
      resourceFailures.push(mailboxesResult.reason instanceof Error ? mailboxesResult.reason.message : t('common.error'));
    }
    setResourceError(resourceFailures.join('；'));
    setLoading(false);
  }, [domainId, domains.length, mailboxId, mailboxScoped, mailboxes.length, scoped, t]);

  useEffect(() => {
    if (domains.length) setAvailableDomains(domains);
  }, [domains]);

  useEffect(() => {
    if (mailboxes.length) setAvailableMailboxes(mailboxes);
  }, [mailboxes]);

  useEffect(() => {
    void loadData();
    return () => { loadRequestId.current += 1; };
  }, [loadData]);

  const lastDeliveryByWebhook = useMemo(() => {
    const map = new Map<number, WebhookDelivery>();
    for (const delivery of recentDeliveries) {
      if (!map.has(delivery.webhookId)) map.set(delivery.webhookId, delivery);
    }
    return map;
  }, [recentDeliveries]);

  const loadDetailDeliveries = useCallback(async () => {
    const requestId = ++detailRequestId.current;
    if (!requestedWebhookId) {
      setDetailDeliveries([]);
      setDetailError('');
      setDetailLoading(false);
      return;
    }

    setDetailDeliveries([]);
    setDetailError('');
    setDetailLoading(true);
    try {
      const result = await api.webhookDeliveries({
        webhookId: requestedWebhookId,
        status: deliveryStatus === 'all' ? undefined : deliveryStatus,
        eventType: deliveryEvent === 'all' ? undefined : deliveryEvent,
        limit: 200
      });
      if (requestId === detailRequestId.current) {
        setDetailDeliveries(result.deliveries || []);
      }
    } catch (error) {
      if (requestId === detailRequestId.current) {
        setDetailError(error instanceof Error ? error.message : t('common.error'));
      }
    } finally {
      if (requestId === detailRequestId.current) setDetailLoading(false);
    }
  }, [deliveryEvent, deliveryStatus, requestedWebhookId, t]);

  useEffect(() => {
    void loadDetailDeliveries();
  }, [loadDetailDeliveries]);

  async function copyValue(value: string) {
    if (!value) return;
    if (onCopy) {
      onCopy(value);
      return;
    }
    await navigator.clipboard.writeText(value);
    message.success(t('common.copied'));
  }

  function openCreate() {
    setEditing(null);
    form.setFieldsValue({
      name: '',
      url: '',
      events: [...selectableEvents],
      domainId: mailboxScoped ? undefined : (domainId != null ? domainId : undefined),
      enabled: true
    });
    setDrawerOpen(true);
  }

  function openEdit(webhook: Webhook) {
    setEditing(webhook);
    form.setFieldsValue({
      name: webhook.name,
      url: webhook.url,
      events: webhook.events?.length ? [...webhook.events] : [...selectableEvents],
      domainId: webhook.domainId ?? undefined,
      enabled: webhook.enabled
    });
    setDrawerOpen(true);
  }

  function closeDrawer() {
    setDrawerOpen(false);
    setEditing(null);
    form.resetFields();
  }

  async function submitForm() {
    const values = await form.validateFields();
    const key = editing ? `save:${editing.id}` : 'create';
    setActionKey(key);
    try {
      const payload: WebhookPayload = {
        name: values.name.trim(),
        url: values.url.trim(),
        events: values.events,
        domainId: mailboxScoped ? null : (domainId != null ? domainId : (values.domainId ?? null)),
        mailboxId: mailboxScoped ? mailboxId : null,
        enabled: values.enabled
      };
      if (editing) {
        await api.updateWebhook(editing.id, payload);
        message.success(t('actions.webhookUpdated'));
        closeDrawer();
        await loadData();
      } else {
        const result = await api.createWebhook(payload);
        message.success(t('actions.webhookCreated'));
        closeDrawer();
        if (result.webhook?.secret) {
          setSecretReveal({ webhook: result.webhook, mode: 'created' });
        }
        await loadData();
      }
    } catch (error) {
      message.error(error instanceof Error ? error.message : t('common.error'));
    } finally {
      setActionKey('');
    }
  }

  async function toggleEnabled(webhook: Webhook, enabled: boolean) {
    setActionKey(`toggle:${webhook.id}`);
    try {
      await api.updateWebhook(webhook.id, { enabled });
      setWebhooks((current) =>
        current.map((item) => (item.id === webhook.id ? { ...item, enabled } : item))
      );
    } catch (error) {
      message.error(error instanceof Error ? error.message : t('common.error'));
    } finally {
      setActionKey('');
    }
  }

  async function deleteWebhook(webhook: Webhook) {
    setActionKey(`delete:${webhook.id}`);
    try {
      await api.deleteWebhook(webhook.id);
      message.success(t('actions.webhookDeleted'));
      if (requestedWebhookId === webhook.id) closeDeliveries();
      await loadData();
    } catch (error) {
      message.error(error instanceof Error ? error.message : t('common.error'));
    } finally {
      setActionKey('');
    }
  }

  async function rotateSecret(webhook: Webhook) {
    setActionKey(`rotate:${webhook.id}`);
    try {
      const result = await api.rotateWebhookSecret(webhook.id);
      message.success(t('actions.webhookSecretRotated'));
      if (result.webhook?.secret) {
        setSecretReveal({ webhook: result.webhook, mode: 'rotated' });
      }
      await loadData();
    } catch (error) {
      message.error(error instanceof Error ? error.message : t('common.error'));
    } finally {
      setActionKey('');
    }
  }

  async function testWebhook(webhook: Webhook) {
    setActionKey(`test:${webhook.id}`);
    try {
      await api.testWebhook(webhook.id);
      message.success(t('actions.webhookTestQueued'));
      await loadData();
      viewDeliveries(webhook);
    } catch (error) {
      message.error(error instanceof Error ? error.message : t('common.error'));
    } finally {
      setActionKey('');
    }
  }

  async function replayDelivery(delivery: WebhookDelivery) {
    setActionKey(`replay:${delivery.id}`);
    try {
      await api.replayWebhookDelivery(delivery.id);
      message.success(t('actions.webhookDeliveryReplayed'));
      await Promise.all([loadData(), loadDetailDeliveries()]);
    } catch (error) {
      message.error(error instanceof Error ? error.message : t('common.error'));
    } finally {
      setActionKey('');
    }
  }

  function viewDeliveries(webhook: Webhook) {
    const next = new URLSearchParams(searchParams);
    next.set('webhookId', String(webhook.id));
    next.delete('deliveryStatus');
    next.delete('deliveryEvent');
    setSearchParams(next, {
      state: detailHistoryLocation(`${location.pathname}${location.search}`, 1)
    });
  }

  function closeDeliveries() {
    const historyState = detailHistoryState(location.state);
    if (historyState) {
      navigate(-historyState.depth);
      return;
    }
    const next = new URLSearchParams(searchParams);
    next.delete('webhookId');
    next.delete('deliveryStatus');
    next.delete('deliveryEvent');
    setSearchParams(next, { replace: true, state: null });
  }

  function updateDeliveryFilter(key: 'deliveryStatus' | 'deliveryEvent', value: string) {
    const next = new URLSearchParams(searchParams);
    if (value === 'all') next.delete(key);
    else next.set(key, value);
    const historyState = detailHistoryState(location.state);
    if (!historyState) {
      setSearchParams(next, { replace: true });
      return;
    }
    const search = next.toString();
    navigate(
      { pathname: location.pathname, search: search ? `?${search}` : '' },
      { state: detailHistoryLocation(historyState.listPath, historyState.depth + 1) }
    );
  }

  function scopeLabel(webhook: Webhook) {
    if (webhook.mailboxId != null) {
      const address = mailboxMap.get(webhook.mailboxId);
      return address ? `${t('webhooks.scopeMailbox')} · ${address}` : t('webhooks.scopeMailbox');
    }
    if (webhook.domainId == null) return t('webhooks.scopeAccount');
    const name = domainMap.get(webhook.domainId);
    return name ? `${t('webhooks.scopeDomain')} · ${name}` : t('webhooks.scopeDomain');
  }

  function eventLabel(event: string) {
    if (event === 'sent') return t('webhooks.eventSent');
    if (event === 'bounced') return t('webhooks.eventBounced');
    if (event === 'failed') return t('webhooks.eventFailed');
    if (event === 'opened') return t('webhooks.eventOpened');
    if (event === 'clicked') return t('webhooks.eventClicked');
    if (event === 'received') return t('webhooks.eventReceived');
    return event;
  }

  function deliveryStatusLabel(status: string) {
    if (status === 'pending') return t('webhooks.statusPending');
    if (status === 'processing') return t('webhooks.statusProcessing');
    if (status === 'success') return t('webhooks.statusSuccess');
    if (status === 'dead') return t('webhooks.statusDead');
    return status;
  }

  function deliveryStatusTone(status: string): StatusTone {
    if (status === 'success') return 'success';
    if (status === 'pending') return 'info';
    if (status === 'processing') return 'warning';
    if (status === 'dead') return 'error';
    return 'neutral';
  }

  function lastDeliverySnippet(webhook: Webhook) {
    const delivery = lastDeliveryByWebhook.get(webhook.id);
    if (!delivery) return <Typography.Text type="secondary">—</Typography.Text>;
    const detail = delivery.error
      || (delivery.responseStatus != null ? `HTTP ${delivery.responseStatus}` : '')
      || deliveryStatusLabel(String(delivery.status));
    return (
      <Space size={6} wrap>
        <StatusPill tone={deliveryStatusTone(String(delivery.status))}>
          {deliveryStatusLabel(String(delivery.status))}
        </StatusPill>
        <Typography.Text type="secondary" ellipsis className="inline-code-value">
          {eventLabel(String(delivery.eventType))} · {detail}
        </Typography.Text>
      </Space>
    );
  }

  const endpointColumns: ColumnsType<Webhook> = [
    {
      title: t('webhooks.name'),
      dataIndex: 'name',
      render: (value: string, webhook) => (
        <Space direction="vertical" size={0}>
          <Typography.Text strong>{value}</Typography.Text>
          <Typography.Text type="secondary" code>
            {webhook.secretPrefix}…
          </Typography.Text>
        </Space>
      )
    },
    {
      title: t('webhooks.scope'),
      render: (_, webhook) => scopeLabel(webhook)
    },
    {
      title: t('webhooks.url'),
      dataIndex: 'url',
      ellipsis: true,
      render: (value: string) => (
        <Typography.Text code ellipsis title={value} className="inline-code-value">
          {truncateUrl(value)}
        </Typography.Text>
      )
    },
    {
      title: t('webhooks.events'),
      dataIndex: 'events',
      render: (events: WebhookEvent[]) => (
        <Space size={[4, 4]} wrap>
          {(events || []).map((event) => (
            <Tag key={event}>{eventLabel(event)}</Tag>
          ))}
        </Space>
      )
    },
    {
      title: t('webhooks.enabled'),
      dataIndex: 'enabled',
      width: 100,
      render: (enabled: boolean, webhook) => (
        <Switch
          checked={enabled}
          loading={actionKey === `toggle:${webhook.id}`}
          onChange={(checked) => void toggleEnabled(webhook, checked)}
          checkedChildren={t('webhooks.enabled')}
          unCheckedChildren={t('webhooks.disabled')}
        />
      )
    },
    {
      title: t('webhooks.lastAttemptAt'),
      render: (_, webhook) => lastDeliverySnippet(webhook)
    },
    {
      title: t('webhooks.actions'),
      fixed: 'right',
      width: 280,
      render: (_, webhook) => (
        <Space wrap size={4}>
          <Button size="small" icon={<ThunderboltOutlined />} loading={actionKey === `test:${webhook.id}`} onClick={() => void testWebhook(webhook)}>
            {t('webhooks.test')}
          </Button>
          <Button size="small" onClick={() => viewDeliveries(webhook)}>
            {t('webhooks.viewDeliveries')}
          </Button>
          <Button size="small" icon={<EditOutlined />} onClick={() => openEdit(webhook)} />
          <Popconfirm title={t('webhooks.rotateConfirm')} onConfirm={() => void rotateSecret(webhook)}>
            <Button aria-label={t('webhooks.rotateSecret')} size="small" icon={<KeyOutlined />} loading={actionKey === `rotate:${webhook.id}`} />
          </Popconfirm>
          <Popconfirm title={t('webhooks.deleteConfirm')} onConfirm={() => void deleteWebhook(webhook)}>
            <Button aria-label={t('common.delete')} size="small" danger icon={<DeleteOutlined />} loading={actionKey === `delete:${webhook.id}`} />
          </Popconfirm>
        </Space>
      )
    }
  ];

  const deliveryColumns: ColumnsType<WebhookDelivery> = [
    {
      title: t('webhooks.createdAt'),
      dataIndex: 'createdAt',
      width: 170,
      render: (value: string) => (value ? new Date(value).toLocaleString() : '—')
    },
    {
      title: t('webhooks.events'),
      dataIndex: 'eventType',
      render: (value: string) => <Tag>{eventLabel(value)}</Tag>
    },
    {
      title: t('common.status'),
      dataIndex: 'status',
      render: (value: string) => (
        <StatusPill tone={deliveryStatusTone(value)}>{deliveryStatusLabel(value)}</StatusPill>
      )
    },
    {
      title: t('webhooks.attemptCount'),
      dataIndex: 'attemptCount',
      width: 90
    },
    {
      title: t('webhooks.responseStatus'),
      dataIndex: 'responseStatus',
      width: 100,
      render: (value: number | null | undefined) => (value != null ? value : '—')
    },
    {
      title: t('webhooks.error'),
      dataIndex: 'error',
      ellipsis: true,
      render: (value: string, row) => value || row.responseBodyPreview || '—'
    },
    {
      title: t('webhooks.lastAttemptAt'),
      dataIndex: 'lastAttemptAt',
      width: 170,
      render: (value?: string | null) => (value ? new Date(value).toLocaleString() : '—')
    },
    {
      title: t('webhooks.actions'),
      fixed: 'right',
      width: 110,
      render: (_, delivery) => (
        <Button
          size="small"
          disabled={delivery.status === 'processing'}
          loading={actionKey === `replay:${delivery.id}`}
          onClick={() => void replayDelivery(delivery)}
        >
          {t('webhooks.replay')}
        </Button>
      )
    }
  ];

  const secret = secretReveal?.webhook.secret || '';
  const sampleVerifier = buildSignatureSample(secret || 'whsec_your_secret');

  return (
    <Space direction="vertical" size={20} className="full-width">
      {!embedded ? (
        <PageHeader
          title={t('webhooks.title')}
          subtitle={t('webhooks.subtitle')}
          extra={
            <Space>
              <Button icon={<ReloadOutlined />} onClick={() => void loadData()} loading={loading}>
                {t('common.refresh')}
              </Button>
              <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
                {t('webhooks.create')}
              </Button>
            </Space>
          }
        />
      ) : (
        <Space direction="vertical" size={12} className="full-width">
          <Alert type="info" showIcon message={mailboxScoped ? t('webhooks.mailboxReceiptHelp') : t('webhooks.domainOverrideHelp')} />
          <Space>
            <Button icon={<ReloadOutlined />} onClick={() => void loadData()} loading={loading}>
              {t('common.refresh')}
            </Button>
            <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
              {t('webhooks.create')}
            </Button>
          </Space>
        </Space>
      )}

      {!embedded ? (
        <Alert type="info" showIcon message={mailboxScoped ? t('webhooks.mailboxReceiptHelp') : t('webhooks.domainOverrideHelp')} />
      ) : null}

      <SectionCard
        title={t('webhooks.listTitle')}
        extra={<StatusPill tone="neutral">{webhooks.length}</StatusPill>}
      >
        {!loadError && resourceError ? <Alert type="warning" showIcon message={t('webhooks.resourcesUnavailable')} description={resourceError} style={{ marginBottom: 12 }} /> : null}
        {!loadError && recentDeliveriesError && webhooks.length ? <Alert type="warning" showIcon message={t('webhooks.recentDeliveriesUnavailable')} description={recentDeliveriesError} style={{ marginBottom: 12 }} /> : null}
        {loadError ? (
          <Alert
            type="error"
            showIcon
            message={t('webhooks.loadFailed')}
            description={loadError}
            action={<Button icon={<ReloadOutlined />} onClick={() => void loadData()}>{t('common.refresh')}</Button>}
          />
        ) : loading && !webhooks.length ? (
          <Skeleton active paragraph={{ rows: 6 }} />
        ) : webhooks.length ? (
          <Table
            rowKey="id"
            columns={endpointColumns}
            dataSource={webhooks}
            loading={loading}
            scroll={{ x: 1200 }}
            pagination={{ pageSize: 10 }}
          />
        ) : (
          <EmptyState
            description={t('webhooks.empty')}
          />
        )}
      </SectionCard>

      <Drawer
        title={editing ? t('webhooks.editTitle') : t('webhooks.createTitle')}
        width={520}
        open={drawerOpen}
        onClose={closeDrawer}
        destroyOnHidden
        footer={
          <div className="drawer-footer">
            <Button onClick={closeDrawer}>{t('common.cancel')}</Button>
            <Button type="primary" loading={actionKey === 'create' || actionKey.startsWith('save:')} onClick={() => void submitForm()}>
              {editing ? t('common.save') : t('webhooks.create')}
            </Button>
          </div>
        }
      >
        <Form form={form} layout="vertical" initialValues={{ enabled: true, events: DELIVERY_EVENTS }}>
          <Form.Item
            name="name"
            label={t('webhooks.name')}
            rules={[{ required: true, message: t('webhooks.nameRequired') }]}
          >
            <Input placeholder={t('webhooks.namePlaceholder')} />
          </Form.Item>
          <Form.Item
            name="url"
            label={t('webhooks.url')}
            extra={t('webhooks.urlHint')}
            rules={[{ required: true, message: t('webhooks.urlRequired') }]}
          >
            <Input placeholder={t('webhooks.urlPlaceholder')} />
          </Form.Item>
          <Form.Item
            name="events"
            label={t('webhooks.events')}
            rules={[{ required: true, type: 'array', min: 1, message: t('webhooks.eventsRequired') }]}
          >
            <Checkbox.Group
              options={selectableEvents.map((event) => ({
                value: event,
                label: eventLabel(event)
              }))}
              disabled={mailboxScoped}
            />
          </Form.Item>
          {!scoped ? (
            <Form.Item name="domainId" label={t('webhooks.domain')} extra={t('webhooks.domainAccount')}>
              <Select
                allowClear
                placeholder={t('webhooks.domainAccount')}
                options={availableDomains.map((domain) => ({
                  value: domain.id,
                  label: domain.domain
                }))}
              />
            </Form.Item>
          ) : null}
          <Form.Item name="enabled" label={t('webhooks.enabled')} valuePropName="checked">
            <Switch />
          </Form.Item>
        </Form>
      </Drawer>

      <Drawer
        title={selectedWebhook ? `${selectedWebhook.name} · ${t('webhooks.deliveriesTitle')}` : t('webhooks.deliveriesTitle')}
        width={760}
        open={Boolean(requestedWebhookId)}
        onClose={closeDeliveries}
      >
        {loading && !selectedWebhook ? (
          <div role="status" aria-label={t('webhooks.deliveriesTitle')}>
            <Skeleton active paragraph={{ rows: 8 }} />
          </div>
        ) : selectedWebhook ? (
          <Space direction="vertical" size={20} className="full-width">
            <Descriptions bordered column={1} size="small">
              <Descriptions.Item label={t('webhooks.url')}>
                <Typography.Text code copyable={{ onCopy: () => void copyValue(selectedWebhook.url) }} style={{ overflowWrap: 'anywhere', wordBreak: 'break-word' }}>{selectedWebhook.url}</Typography.Text>
              </Descriptions.Item>
              <Descriptions.Item label={t('webhooks.scope')}>{scopeLabel(selectedWebhook)}</Descriptions.Item>
              <Descriptions.Item label={t('webhooks.events')}>
                <Space wrap>{selectedWebhook.events.map((event) => <Tag key={event}>{eventLabel(event)}</Tag>)}</Space>
              </Descriptions.Item>
              <Descriptions.Item label={t('webhooks.secretPrefix')}><Typography.Text code>{selectedWebhook.secretPrefix}…</Typography.Text></Descriptions.Item>
              <Descriptions.Item label={t('common.status')}>
                <StatusPill tone={selectedWebhook.enabled ? 'success' : 'neutral'}>{selectedWebhook.enabled ? t('webhooks.enabled') : t('webhooks.disabled')}</StatusPill>
              </Descriptions.Item>
            </Descriptions>
            <Space wrap>
              <Select
                aria-label={t('webhooks.deliveriesFilterStatus')}
                style={{ minWidth: 160 }}
                value={deliveryStatus}
                onChange={(value) => updateDeliveryFilter('deliveryStatus', value)}
                options={[{ value: 'all', label: t('webhooks.allStatuses') }, ...DELIVERY_STATUSES.map((status) => ({ value: status, label: deliveryStatusLabel(status) }))]}
              />
              <Select
                aria-label={t('webhooks.deliveriesFilterEvent')}
                style={{ minWidth: 160 }}
                value={deliveryEvent}
                onChange={(value) => updateDeliveryFilter('deliveryEvent', value)}
                options={[{ value: 'all', label: t('webhooks.allEvents') }, ...ALL_EVENTS.map((event) => ({ value: event, label: eventLabel(event) }))]}
              />
            </Space>
            {detailError ? (
              <Alert
                type="error"
                showIcon
                message={detailError}
                action={<Button icon={<ReloadOutlined />} onClick={() => void loadDetailDeliveries()}>{t('common.refresh')}</Button>}
              />
            ) : detailLoading && !detailDeliveries.length ? (
              <div role="status" aria-label={t('webhooks.deliveriesTitle')}>
                <Skeleton active paragraph={{ rows: 6 }} />
              </div>
            ) : detailDeliveries.length ? (
              <Table rowKey="id" columns={deliveryColumns} dataSource={detailDeliveries} loading={detailLoading} scroll={{ x: 920 }} pagination={{ pageSize: 10 }} />
            ) : <EmptyState description={t('webhooks.deliveriesEmpty')} />}
            <Alert type="info" showIcon message={t('webhooks.docsSignature')} description={t('webhooks.docsEvents')} />
            <CodeBlock value={buildSignatureSample('whsec_your_secret')} onCopy={copyValue} />
          </Space>
        ) : loadError && requestedWebhookId ? (
          <Alert type="error" showIcon message={t('webhooks.loadFailed')} description={loadError} action={<Button icon={<ReloadOutlined />} onClick={() => void loadData()}>{t('common.refresh')}</Button>} />
        ) : requestedWebhookId ? <EmptyState description={t('common.notFound')} /> : null}
      </Drawer>

      <Modal
        title={
          secretReveal?.mode === 'rotated'
            ? t('webhooks.secretRotatedTitle')
            : t('webhooks.secretCreatedTitle')
        }
        open={Boolean(secretReveal)}
        closable={false}
        maskClosable={false}
        keyboard={false}
        destroyOnHidden
        footer={[
          <Button
            key="copy"
            icon={<CopyOutlined />}
            onClick={() => void copyValue(secret)}
          >
            {t('webhooks.copySecret')}
          </Button>,
          <Button key="done" type="primary" onClick={() => setSecretReveal(null)}>
            {t('common.confirm')}
          </Button>
        ]}
      >
        <Space direction="vertical" size={16} className="full-width">
          <Alert type="error" showIcon message={t('webhooks.secretCreatedWarning')} />
          <div>
            <Typography.Text type="secondary">{t('webhooks.secret')}</Typography.Text>
            <CodeBlock value={secret} onCopy={copyValue} />
          </div>
          <div>
            <Typography.Text type="secondary">{t('webhooks.docsSignature')}</Typography.Text>
            <CodeBlock value={sampleVerifier} onCopy={copyValue} />
          </div>
        </Space>
      </Modal>
    </Space>
  );
}

function truncateUrl(url: string, max = 48) {
  if (!url) return '';
  if (url.length <= max) return url;
  return `${url.slice(0, max - 1)}…`;
}

function positiveInteger(value: string | null) {
  const parsed = Number(value);
  return Number.isInteger(parsed) && parsed > 0 ? parsed : null;
}

function deliveryStatusFromParam(value: string | null): WebhookDeliveryStatus | 'all' {
  return DELIVERY_STATUSES.includes(value as WebhookDeliveryStatus)
    ? value as WebhookDeliveryStatus
    : 'all';
}

function deliveryEventFromParam(value: string | null): WebhookEvent | 'all' {
  return ALL_EVENTS.includes(value as WebhookEvent) ? value as WebhookEvent : 'all';
}

function buildSignatureSample(secret: string) {
  return `// Verify X-MailHub-Signature (Node.js)
const crypto = require('crypto');

function verify(rawBody, signatureHeader, secret = ${JSON.stringify(secret)}) {
  const parts = Object.fromEntries(
    signatureHeader.split(',').map((p) => p.trim().split('='))
  );
  const signed = \`\${parts.t}.\${rawBody}\`;
  const expected = crypto.createHmac('sha256', secret).update(signed).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(parts.v1, 'hex'), Buffer.from(expected, 'hex'));
}`;
}
