import { CheckOutlined, CloudOutlined, CodeOutlined, MailOutlined, SendOutlined } from '@ant-design/icons';
import {
  Alert,
  Button,
  Checkbox,
  Collapse,
  Descriptions,
  Drawer,
  Form,
  Input,
  Radio,
  Select,
  Space,
  Steps,
  Typography
} from 'antd';
import { useEffect, useMemo, useState } from 'react';

import { StatusPill } from '../common/StatusPill';
import { useI18n } from '../../frontend/i18n/react';
import type { AddDomainPayload, DnsCredential, RuntimeConfig, SmtpRelay } from '../../frontend/types';

interface AddDomainDrawerProps {
  open: boolean;
  loading?: boolean;
  config: RuntimeConfig | null;
  dnsCredentials: DnsCredential[];
  smtpRelays: SmtpRelay[];
  onClose: () => void;
  onSubmit: (values: AddDomainPayload) => Promise<void>;
}

interface DomainWizardValues extends AddDomainPayload {
  purpose: 'sending' | 'sending-receiving';
  dnsMode: 'automatic' | 'manual';
}

export function AddDomainDrawer({
  open,
  loading,
  config,
  dnsCredentials,
  smtpRelays,
  onClose,
  onSubmit
}: AddDomainDrawerProps) {
  const { locale } = useI18n();
  const copy = locale.startsWith('en') ? enCopy : zhCopy;
  const [form] = Form.useForm<DomainWizardValues>();
  const [current, setCurrent] = useState(0);
  const values = Form.useWatch([], form);
  const dnsMode = Form.useWatch('dnsMode', form);
  const steps = useMemo(() => [copy.domainAndPurpose, copy.dnsAndDelivery, copy.reviewAndCreate], [copy]);

  useEffect(() => {
    if (!open) return;
    form.resetFields();
    form.setFieldsValue({
      purpose: 'sending',
      dnsMode: dnsCredentials.length ? 'automatic' : 'manual',
      dnsCredentialId: dnsCredentials[0]?.id,
      smtpRelayId: undefined,
      senderHost: config?.mailHostname || '',
      sendingIp: config?.sendingIp || '',
      selector: defaultSelector(),
      dmarcPolicy: config?.dmarcPolicy || 'none',
      spfExtra: config?.defaultSpfMechanisms || '',
      immediateCheck: true
    });
    setCurrent(0);
  }, [config, dnsCredentials, form, open]);

  async function next() {
    try {
      await form.validateFields(stepFields(current));
    } catch {
      return;
    }
    if (current === 1 && dnsMode === 'automatic' && !form.getFieldValue('dnsCredentialId')) {
      form.setFields([{ name: 'dnsCredentialId', errors: [copy.selectDnsCredential] }]);
      return;
    }
    setCurrent((value) => Math.min(value + 1, steps.length - 1));
  }

  async function submit() {
    let result: DomainWizardValues;
    try {
      result = await form.validateFields();
    } catch {
      return;
    }
    const payload: AddDomainPayload = {
      domain: result.domain.trim().toLowerCase(),
      senderHost: result.senderHost?.trim(),
      sendingIp: result.sendingIp?.trim(),
      dnsCredentialId: result.dnsMode === 'automatic' ? result.dnsCredentialId : undefined,
      smtpRelayId: result.smtpRelayId || null,
      selector: result.selector?.trim(),
      dmarcPolicy: result.dmarcPolicy,
      spfExtra: result.spfExtra?.trim(),
      immediateCheck: result.immediateCheck
    };
    try {
      await onSubmit(payload);
    } catch {
      return;
    }
    form.resetFields();
    setCurrent(0);
  }

  return (
    <Drawer
      title={copy.title}
      width="min(640px, 100vw)"
      open={open}
      onClose={onClose}
      destroyOnHidden
      maskClosable={!loading}
      className="add-domain-drawer"
      styles={{ header: { padding: '16px 24px' }, body: { padding: '20px 24px 28px' }, footer: { padding: '12px 24px' } }}
      footer={
        <div className="drawer-footer">
          <Button style={{ minHeight: 44 }} disabled={loading} onClick={onClose}>{copy.cancel}</Button>
          <Space size={8}>
            <Button style={{ minHeight: 44 }} disabled={current === 0 || loading} onClick={() => setCurrent((value) => value - 1)}>{copy.previous}</Button>
            {current < steps.length - 1 ? (
              <Button type="primary" style={{ minHeight: 44 }} onClick={() => void next()}>{copy.next}</Button>
            ) : (
              <Button type="primary" style={{ minHeight: 44 }} icon={<CheckOutlined />} loading={loading} onClick={() => void submit()}>{copy.createAndVerify}</Button>
            )}
          </Space>
        </div>
      }
    >
      <Space direction="vertical" size={24} className="full-width">
        <Steps current={current} items={steps.map((title) => ({ title }))} responsive aria-label={copy.progress} />
        <Form form={form} layout="vertical" requiredMark="optional" preserve>
          <section hidden={current !== 0} aria-label={copy.domainAndPurpose}>
            <Form.Item
              name="domain"
              label={copy.domain}
              rules={[
                { required: true, message: copy.domainRequired },
                { pattern: /^(?!-)(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/, message: copy.domainInvalid }
              ]}
              extra={copy.domainHint}
            >
              <Input placeholder="example.com" autoComplete="off" style={{ minHeight: 44 }} />
            </Form.Item>
            <Form.Item name="purpose" label={copy.purpose} rules={[{ required: true }]}>
              <Radio.Group style={{ width: '100%' }}>
                <Space direction="vertical" size={12} className="full-width">
                  <Radio value="sending"><Space><SendOutlined /><span><Typography.Text strong>{copy.sendingOnly}</Typography.Text><br /><Typography.Text type="secondary">{copy.sendingOnlyHint}</Typography.Text></span></Space></Radio>
                  <Radio value="sending-receiving"><Space><MailOutlined /><span><Typography.Text strong>{copy.sendAndReceive}</Typography.Text><br /><Typography.Text type="secondary">{copy.sendAndReceiveHint}</Typography.Text></span></Space></Radio>
                </Space>
              </Radio.Group>
            </Form.Item>
            {values?.purpose === 'sending-receiving' ? <Alert type="info" showIcon message={copy.receiveFollowUp} /> : null}
          </section>

          <section hidden={current !== 1} aria-label={copy.dnsAndDelivery}>
            <Form.Item name="dnsMode" label={copy.dnsConfiguration} rules={[{ required: true }]}>
              <Radio.Group optionType="button" buttonStyle="solid" style={{ minHeight: 44 }}>
                <Radio.Button value="automatic" disabled={!dnsCredentials.length}><CloudOutlined /> {copy.automatic}</Radio.Button>
                <Radio.Button value="manual"><CodeOutlined /> {copy.manual}</Radio.Button>
              </Radio.Group>
            </Form.Item>
            {dnsMode === 'automatic' ? (
              <Form.Item name="dnsCredentialId" label={copy.dnsCredential} rules={[{ required: true, message: copy.selectDnsCredential }]} extra={copy.autoDnsHint}>
                <Select
                  placeholder={copy.selectDnsCredential}
                  style={{ minHeight: 44 }}
                  options={dnsCredentials.map((credential) => ({ value: credential.id, label: `${credential.name} · ${providerLabel(credential.provider)}` }))}
                />
              </Form.Item>
            ) : (
              <Alert type="info" showIcon message={copy.manualDnsTitle} description={copy.manualDnsHint} />
            )}

            <Form.Item name="smtpRelayId" label={copy.relay} extra={copy.relayHint} style={{ marginTop: 20 }}>
              <Select
                allowClear
                placeholder={copy.defaultDelivery}
                style={{ minHeight: 44 }}
                options={smtpRelays.map((relay) => ({ value: relay.id, label: relayLabel(relay, copy.defaultLabel) }))}
              />
            </Form.Item>

            <Collapse
              ghost
              items={[{
                key: 'advanced',
                label: copy.advanced,
                forceRender: true,
                children: (
                  <>
                    <Form.Item name="senderHost" label={copy.senderHost} rules={[{ required: true, message: copy.senderHostRequired }]}><Input placeholder="mail.example.com" autoComplete="off" style={{ minHeight: 44 }} /></Form.Item>
                    <Form.Item name="sendingIp" label={copy.sendingIp} rules={[{ required: true, message: copy.sendingIpRequired }]}><Input placeholder="203.0.113.10" autoComplete="off" style={{ minHeight: 44 }} /></Form.Item>
                    <Form.Item name="selector" label="DKIM selector" rules={[{ required: true, message: copy.selectorRequired }]}><Input placeholder="mh202607" autoComplete="off" style={{ minHeight: 44 }} /></Form.Item>
                    <Form.Item name="dmarcPolicy" label="DMARC"><Select style={{ minHeight: 44 }} options={['none', 'quarantine', 'reject'].map((value) => ({ value, label: value }))} /></Form.Item>
                    <Form.Item name="spfExtra" label={copy.spfExtra}><Input.TextArea rows={3} placeholder="include:spf.example.com" /></Form.Item>
                  </>
                )
              }]}
            />
          </section>

          <section hidden={current !== 2} aria-label={copy.reviewAndCreate}>
            <Alert type="info" showIcon message={copy.reviewHint} style={{ marginBottom: 20 }} />
            <Descriptions bordered size="small" column={1}>
              <Descriptions.Item label={copy.domain}>{values?.domain || '-'}</Descriptions.Item>
              <Descriptions.Item label={copy.purpose}>{values?.purpose === 'sending-receiving' ? copy.sendAndReceive : copy.sendingOnly}</Descriptions.Item>
              <Descriptions.Item label={copy.dnsConfiguration}>
                <StatusPill tone={values?.dnsMode === 'automatic' ? 'info' : 'neutral'}>{values?.dnsMode === 'automatic' ? copy.automatic : copy.manual}</StatusPill>
              </Descriptions.Item>
              <Descriptions.Item label={copy.dnsCredential}>{values?.dnsMode === 'automatic' ? dnsCredentials.find((item) => item.id === values?.dnsCredentialId)?.name || '-' : copy.notApplicable}</Descriptions.Item>
              <Descriptions.Item label={copy.relay}>{smtpRelays.find((item) => item.id === values?.smtpRelayId)?.name || copy.defaultDelivery}</Descriptions.Item>
              <Descriptions.Item label="DKIM selector">{values?.selector || '-'}</Descriptions.Item>
              <Descriptions.Item label="DMARC">{values?.dmarcPolicy || 'none'}</Descriptions.Item>
            </Descriptions>
            <Form.Item name="immediateCheck" valuePropName="checked" style={{ marginTop: 20 }}>
              <Checkbox>{copy.verifyImmediately}</Checkbox>
            </Form.Item>
          </section>
        </Form>
      </Space>
    </Drawer>
  );
}

function stepFields(step: number): Array<keyof DomainWizardValues> {
  if (step === 0) return ['domain', 'purpose'];
  if (step === 1) return ['dnsMode', 'dnsCredentialId', 'smtpRelayId', 'senderHost', 'sendingIp', 'selector', 'dmarcPolicy', 'spfExtra'];
  return [];
}

function defaultSelector() {
  const date = new Date();
  return `mh${date.getUTCFullYear()}${String(date.getUTCMonth() + 1).padStart(2, '0')}`;
}

function providerLabel(provider: string) {
  return ({ cloudflare: 'Cloudflare', aliyun: 'Aliyun DNS', dnspod: 'Tencent DNSPod' } as Record<string, string>)[provider] || provider;
}

function relayLabel(relay: SmtpRelay, defaultLabel: string) {
  return `${relay.name}${relay.isDefault ? ` · ${defaultLabel}` : ''} · ${relay.host}:${relay.port}`;
}

const zhCopy = {
  title: '添加发信域名', progress: '添加域名进度', domainAndPurpose: '域名与用途', dnsAndDelivery: 'DNS 与投递', reviewAndCreate: '检查并创建', cancel: '取消', previous: '上一步', next: '下一步', createAndVerify: '创建并验证',
  domain: '域名', domainRequired: '请输入域名', domainInvalid: '请输入有效的根域名', domainHint: '请输入用于发件地址的根域名，例如 example.com。', purpose: '用途', sendingOnly: '仅发送邮件', sendingOnlyHint: '配置 SPF、DKIM、DMARC 和发信主机。', sendAndReceive: '发送并接收邮件', sendAndReceiveHint: '创建后继续配置邮箱与收信路由。', receiveFollowUp: '域名创建后，可在“收信配置”页签中创建邮箱和路由。',
  dnsConfiguration: 'DNS 配置方式', automatic: '自动配置', manual: '手动配置', dnsCredential: 'DNS 凭据', selectDnsCredential: '请选择 DNS 凭据', autoDnsHint: '创建后将使用该凭据写入所需记录；你仍可先检查摘要。', manualDnsTitle: '手动配置 DNS', manualDnsHint: '创建后会展示每条记录的主机名、类型和值，便于复制到当前 DNS 服务商。', relay: '发送中继', relayHint: '留空时按系统默认解析顺序投递。', defaultDelivery: '使用系统默认投递', defaultLabel: '默认', advanced: '高级选项', senderHost: '发信主机', senderHostRequired: '请输入发信主机', sendingIp: '发信 IP', sendingIpRequired: '请输入发信 IP', selectorRequired: '请输入 DKIM selector', spfExtra: 'SPF 扩展机制',
  reviewHint: '创建操作不会隐藏任何现有能力；DNS 自动写入和验证结果可在域名详情中继续处理。', notApplicable: '不适用', verifyImmediately: '创建后立即检查 DNS 生效状态'
};

const enCopy: typeof zhCopy = {
  title: 'Add sending domain', progress: 'Add domain progress', domainAndPurpose: 'Domain and purpose', dnsAndDelivery: 'DNS and delivery', reviewAndCreate: 'Review and create', cancel: 'Cancel', previous: 'Previous', next: 'Next', createAndVerify: 'Create and verify',
  domain: 'Domain', domainRequired: 'Enter a domain', domainInvalid: 'Enter a valid root domain', domainHint: 'Use the root domain for your From addresses, for example example.com.', purpose: 'Purpose', sendingOnly: 'Send email', sendingOnlyHint: 'Configure SPF, DKIM, DMARC, and the sending host.', sendAndReceive: 'Send and receive email', sendAndReceiveHint: 'Continue with mailbox and inbound routing after creation.', receiveFollowUp: 'After creation, configure mailboxes and routes from the Receiving tab.',
  dnsConfiguration: 'DNS configuration', automatic: 'Automatic', manual: 'Manual', dnsCredential: 'DNS credential', selectDnsCredential: 'Select a DNS credential', autoDnsHint: 'The credential can apply required records after creation; review them first if needed.', manualDnsTitle: 'Manual DNS configuration', manualDnsHint: 'The domain details will show each host, type, and value to copy into your DNS provider.', relay: 'Sending relay', relayHint: 'Leave empty to use the system delivery resolution order.', defaultDelivery: 'Use system delivery', defaultLabel: 'Default', advanced: 'Advanced options', senderHost: 'Sending host', senderHostRequired: 'Enter a sending host', sendingIp: 'Sending IP', sendingIpRequired: 'Enter a sending IP', selectorRequired: 'Enter a DKIM selector', spfExtra: 'Additional SPF mechanisms',
  reviewHint: 'Creation keeps all existing capabilities available. Continue DNS application and verification from domain details.', notApplicable: 'Not applicable', verifyImmediately: 'Check DNS status immediately after creation'
};
