import { ReloadOutlined, SaveOutlined, WarningOutlined } from '@ant-design/icons';
import {
  Alert,
  App as AntApp,
  Button,
  Form,
  Input,
  Select,
  Skeleton,
  Space,
  Switch,
  Table,
  Typography
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { type BlockerFunction, useBeforeUnload, useBlocker } from 'react-router-dom';

import { PageHeader } from '../components/common/PageHeader';
import { SectionCard } from '../components/common/SectionCard';
import { StatusTag } from '../components/common/StatusTag';
import { useAppContext } from '../frontend/app-context';
import { getDnsCurrentValues } from '../frontend/domain-model.js';
import { useI18n } from '../frontend/i18n/react';
import { api } from '../frontend/services/api';
import type { DnsRecord, RuntimeConfig } from '../frontend/types';

export default function Settings() {
  const { message, modal } = AntApp.useApp();
  const { locale, t } = useI18n();
  const { user: me } = useAppContext();
  const [form] = Form.useForm<Partial<RuntimeConfig>>();
  const appBaseUrl = Form.useWatch('appBaseUrl', form);
  const [settings, setSettings] = useState<RuntimeConfig | null>(null);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [loadError, setLoadError] = useState('');
  const [dirty, setDirty] = useState(false);
  const leaveConfirmation = useRef<{ destroy: () => void } | null>(null);
  const leaveCopy = useMemo(() => locale.startsWith('en')
    ? {
        title: 'Discard unsaved changes?',
        content: 'You have unsaved settings. Leaving this page will discard them.',
        confirm: 'Leave page',
        cancel: 'Keep editing'
      }
    : {
        title: '放弃未保存的更改？',
        content: '当前设置尚未保存，离开此页面将丢失这些更改。',
        confirm: '离开页面',
        cancel: '继续编辑'
      }, [locale]);
  const copy = locale.startsWith('en') ? settingsCopyEn : settingsCopyZh;
  const appUrlError = publicUrlSecurityError(appBaseUrl, locale);

  const shouldBlock = useCallback<BlockerFunction>(({ currentLocation, nextLocation }) => (
    dirty && locationIdentity(currentLocation) !== locationIdentity(nextLocation)
  ), [dirty]);
  const blocker = useBlocker(shouldBlock);

  useBeforeUnload(useCallback((event) => {
    if (!dirty) return;
    event.preventDefault();
    event.returnValue = '';
  }, [dirty]), { capture: true });

  const loadSettings = useCallback(async () => {
    setLoading(true);
    setLoadError('');
    try {
      if (me?.role !== 'admin') return;
      const result = await api.adminSettings();
      setSettings(result.settings);
      form.setFieldsValue(result.settings);
      setDirty(false);
    } catch (error) {
      setLoadError(error instanceof Error ? error.message : t('common.error'));
    } finally {
      setLoading(false);
    }
  }, [form, me?.role, t]);

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

  useEffect(() => {
    if (blocker.state !== 'blocked' || leaveConfirmation.current) return;
    leaveConfirmation.current = modal.confirm({
      title: leaveCopy.title,
      content: leaveCopy.content,
      okText: leaveCopy.confirm,
      cancelText: leaveCopy.cancel,
      okButtonProps: { danger: true },
      onOk: () => {
        leaveConfirmation.current = null;
        setDirty(false);
        blocker.proceed();
      },
      onCancel: () => {
        leaveConfirmation.current = null;
        blocker.reset();
      },
      afterClose: () => {
        leaveConfirmation.current = null;
      }
    });
  }, [blocker, leaveCopy, modal]);

  useEffect(() => () => {
    leaveConfirmation.current?.destroy();
    leaveConfirmation.current = null;
  }, []);

  async function save(values: Partial<RuntimeConfig>) {
    setSaving(true);
    try {
      const result = await api.saveAdminSettings(values);
      setSettings(result.settings);
      form.setFieldsValue(result.settings);
      setDirty(false);
      message.success(t('actions.settingsSaved'));
    } catch (error) {
      message.error(error instanceof Error ? error.message : t('common.error'));
    } finally {
      setSaving(false);
    }
  }

  if (!loading && me?.role !== 'admin') {
    return (
      <Space direction="vertical" size={20} className="full-width">
        <PageHeader title={t('nav.settings')} />
        <Alert type="warning" showIcon message={t('settings.noPermission')} />
      </Space>
    );
  }

  const checkColumns: ColumnsType<DnsRecord> = [
    { title: t('settings.checkItem'), dataIndex: 'label', width: 160 },
    { title: t('dnsRecord.hostname'), dataIndex: 'host', width: 180, render: (value: string) => <Typography.Text code>{value || '—'}</Typography.Text> },
    { title: t('dnsRecord.targetValue'), dataIndex: 'value', width: 220, render: (value: string) => <Typography.Text code>{value || '—'}</Typography.Text> },
    {
      title: t('dnsRecord.currentValue'),
      width: 260,
      render: (_, record) => {
        const values: string[] = getDnsCurrentValues(record);
        return values.length ? <Space direction="vertical" size={4}>{values.map((value) => <Typography.Text key={value} code>{value}</Typography.Text>)}</Space> : <Typography.Text type="secondary">{t('dnsRecord.emptyCurrent')}</Typography.Text>;
      }
    },
    { title: t('common.status'), width: 120, render: (_, record) => <StatusTag record={record} /> }
  ];
  const checkData = settings?.systemChecks?.ptr ? [settings.systemChecks.ptr] : [];

  return (
    <Space direction="vertical" size={20} className="full-width">
      <PageHeader
        title={t('nav.settings')}
        subtitle={locale.startsWith('en') ? 'Runtime and delivery defaults for this MailHub instance.' : '配置当前 MailHub 实例的运行参数和投递默认行为。'}
        extra={
          <Button type="primary" icon={<SaveOutlined />} loading={saving} disabled={!dirty || loading} onClick={() => form.submit()} style={{ minHeight: 44 }}>
            {t('settings.save')}
          </Button>
        }
      />
      {loadError ? <Alert type="error" showIcon message={loadError} action={<Button icon={<ReloadOutlined />} onClick={() => void loadSettings()}>{t('common.refresh')}</Button>} /> : null}
      {loading ? <SectionCard><Skeleton active paragraph={{ rows: 10 }} /></SectionCard> : (
        <Form form={form} layout="vertical" onFinish={save} onValuesChange={() => setDirty(true)}>
          <Space direction="vertical" size={20} className="full-width">
            <SectionCard title={locale.startsWith('en') ? 'Instance' : '实例配置'}>
              {appUrlError ? <Alert type="error" showIcon message={copy.publicUrlInvalid} description={appUrlError} style={{ marginBottom: 20 }} /> : null}
              <div className="form-grid two">
                <Form.Item
                  name="appBaseUrl"
                  label={copy.publicUrl}
                  extra={envExtra('APP_BASE_URL')}
                  rules={[{ required: true, message: copy.publicUrlRequired }, { validator: (_, value) => publicUrlSecurityError(value, locale) ? Promise.reject(new Error(publicUrlSecurityError(value, locale))) : Promise.resolve() }]}
                >
                  <Input aria-label="APP_BASE_URL" inputMode="url" placeholder="https://mail.example.com" />
                </Form.Item>
                <Form.Item name="mailHostname" label={copy.mailHostname} extra={envExtra('MAIL_HOSTNAME')}><Input aria-label="MAIL_HOSTNAME" /></Form.Item>
                <Form.Item name="sendingIp" label={copy.sendingIp} extra={envExtra('SENDING_IP')}><Input aria-label="SENDING_IP" inputMode="decimal" /></Form.Item>
                <Form.Item name="defaultSpfMechanisms" label={copy.spfMechanisms} extra={envExtra('DEFAULT_SPF_MECHANISMS')}><Input aria-label="DEFAULT_SPF_MECHANISMS" /></Form.Item>
                <Form.Item name="dmarcPolicy" label={copy.dmarcPolicy} extra={envExtra('DMARC_POLICY')}><Select aria-label="DMARC_POLICY" options={['none', 'quarantine', 'reject'].map((value) => ({ value, label: value }))} /></Form.Item>
                <Form.Item name="dmarcRua" label={copy.dmarcReports} extra={envExtra('DMARC_RUA')}><Input aria-label="DMARC_RUA" inputMode="email" /></Form.Item>
              </div>
            </SectionCard>

            <SectionCard title={locale.startsWith('en') ? 'Message and tracking defaults' : '邮件与跟踪默认值'}>
              <div className="form-grid two">
                <Form.Item name="listUnsubscribeMailto" label={copy.unsubscribeEmail} extra={envExtra('LIST_UNSUBSCRIBE_MAILTO')}><Input aria-label="LIST_UNSUBSCRIBE_MAILTO" placeholder="unsubscribe@example.com" /></Form.Item>
                <Form.Item name="listUnsubscribeUrl" label={copy.unsubscribeUrl} extra={envExtra('LIST_UNSUBSCRIBE_URL')}><Input aria-label="LIST_UNSUBSCRIBE_URL" placeholder="https://example.com/unsubscribe/{eventId}" /></Form.Item>
                <Form.Item name="reportAbuseTo" label={copy.abuseMailbox} extra={envExtra('REPORT_ABUSE_TO')}><Input aria-label="REPORT_ABUSE_TO" placeholder="abuse@example.com" /></Form.Item>
                <Form.Item name="csaComplaintsTo" label={copy.csaMailbox} extra={envExtra('CSA_COMPLAINTS_TO')}><Input aria-label="CSA_COMPLAINTS_TO" placeholder="csa-complaints@example.com" /></Form.Item>
                <Form.Item name="bounceAddress" label={copy.bounceAddress} extra={envExtra('BOUNCE_ADDRESS')}><Input aria-label="BOUNCE_ADDRESS" placeholder="bounce@example.com" /></Form.Item>
              </div>
              <Space direction="vertical" size={16}>
                <Form.Item name="engagementTrackingEnabled" label={t('settings.engagementTracking')} valuePropName="checked" style={{ marginBottom: 0 }}><Switch /></Form.Item>
                <Form.Item name="listUnsubscribePostEnabled" label={copy.oneClickUnsubscribe} extra={envExtra('LIST_UNSUBSCRIBE_POST_ENABLED')} valuePropName="checked" style={{ marginBottom: 0 }}><Switch aria-label="LIST_UNSUBSCRIBE_POST_ENABLED" /></Form.Item>
                <Form.Item name="feedbackIdEnabled" label={copy.feedbackId} extra={envExtra('FEEDBACK_ID_ENABLED')} valuePropName="checked" style={{ marginBottom: 0 }}><Switch aria-label="FEEDBACK_ID_ENABLED" /></Form.Item>
              </Space>
            </SectionCard>

            <SectionCard
              title={t('settings.deliveryChecks')}
              extra={settings?.systemChecks?.checkedAt ? <Typography.Text type="secondary">{new Date(settings.systemChecks.checkedAt).toLocaleString()}</Typography.Text> : null}
            >
              <Table rowKey="key" columns={checkColumns} dataSource={checkData} pagination={false} scroll={{ x: 940 }} />
            </SectionCard>

            <SectionCard title={<Space><WarningOutlined style={{ color: '#D92D20' }} />{locale.startsWith('en') ? 'Danger zone' : '高风险设置'}</Space>}>
              <Alert
                type="warning"
                showIcon
                message={locale.startsWith('en') ? 'Changes here alter the sending security boundary.' : '以下设置会改变发信安全边界，请在保存前确认影响。'}
                description={settings?.usingDefaultAdminPassword ? (locale.startsWith('en') ? 'The default administrator password is still in use. Change it before exposing this instance.' : '当前仍在使用默认管理员密码，请在对外开放前完成修改。') : undefined}
                style={{ marginBottom: 20 }}
              />
              <Space direction="vertical" size={16}>
                <Form.Item name="sendRequiresVerified" label={copy.requireVerifiedDomain} extra={envExtra('SEND_REQUIRES_VERIFIED')} valuePropName="checked" style={{ marginBottom: 0 }}><Switch aria-label="SEND_REQUIRES_VERIFIED" /></Form.Item>
                <Form.Item name="bounceEnvelopeEnabled" label={copy.bounceEnvelope} extra={envExtra('BOUNCE_ENVELOPE_ENABLED')} valuePropName="checked" style={{ marginBottom: 0 }}><Switch aria-label="BOUNCE_ENVELOPE_ENABLED" /></Form.Item>
              </Space>
            </SectionCard>
          </Space>
        </Form>
      )}
    </Space>
  );
}

function locationIdentity(location: { pathname: string; search: string; hash: string }) {
  return `${location.pathname}${location.search}${location.hash}`;
}

function envExtra(name: string) {
  return <Typography.Text type="secondary" code>{name}</Typography.Text>;
}

function publicUrlSecurityError(value: unknown, locale: string) {
  if (!value) return '';
  let url: URL;
  try {
    url = new URL(String(value));
  } catch {
    return locale.startsWith('en') ? 'Enter a valid absolute URL.' : '请输入有效的完整访问地址。';
  }
  const local = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '::1';
  if (url.protocol !== 'https:' && !local) {
    return locale.startsWith('en')
      ? 'Public instances must use HTTPS so API credentials are never sent over plaintext HTTP.'
      : '公网实例必须使用 HTTPS，避免 API 密钥通过明文 HTTP 传输。';
  }
  return '';
}

const settingsCopyZh = {
  publicUrl: '公开访问地址', publicUrlInvalid: '公开访问地址不安全', publicUrlRequired: '请输入公开访问地址',
  mailHostname: '邮件服务器主机名', sendingIp: '发信公网 IP', spfMechanisms: '默认 SPF 扩展', dmarcPolicy: '默认 DMARC 策略', dmarcReports: 'DMARC 报告邮箱',
  unsubscribeEmail: '退订邮箱', unsubscribeUrl: '退订链接', abuseMailbox: '滥用举报邮箱', csaMailbox: 'CSA 投诉邮箱', bounceAddress: '退信地址',
  oneClickUnsubscribe: '启用一键退订', feedbackId: '启用 Feedback-ID', requireVerifiedDomain: '仅允许已验证域名发信', bounceEnvelope: '启用退信信封地址'
};

const settingsCopyEn: typeof settingsCopyZh = {
  publicUrl: 'Public URL', publicUrlInvalid: 'Public URL is insecure', publicUrlRequired: 'Enter the public URL',
  mailHostname: 'Mail server hostname', sendingIp: 'Public sending IP', spfMechanisms: 'Default SPF mechanisms', dmarcPolicy: 'Default DMARC policy', dmarcReports: 'DMARC report mailbox',
  unsubscribeEmail: 'Unsubscribe mailbox', unsubscribeUrl: 'Unsubscribe URL', abuseMailbox: 'Abuse mailbox', csaMailbox: 'CSA complaints mailbox', bounceAddress: 'Bounce address',
  oneClickUnsubscribe: 'Enable one-click unsubscribe', feedbackId: 'Enable Feedback-ID', requireVerifiedDomain: 'Require a verified sending domain', bounceEnvelope: 'Enable bounce envelope address'
};
