import { useCallback, useEffect, useState } from 'react';
import {
  Button,
  Card,
  Checkbox,
  Descriptions,
  Drawer,
  Form,
  Input,
  Modal,
  Popconfirm,
  Select,
  Space,
  Table,
  Tabs,
  Tag,
  Typography,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { request, type Paginated } from '../lib/api';
import { fmtTime } from '../lib/constants';
import { useAdminListColumns } from '../lib/useAdminListColumns';

const MOCK_KEYS = ['MOCK_SMS', 'MOCK_WECHAT', 'MOCK_PAY'] as const;

type PhoneRow = {
  id: string;
  phone: string;
  note: string | null;
  createdByHqId: string | null;
  createdAt: string;
  updatedAt: string;
};

type AccountType = 'user' | 'store_account' | 'partner' | 'store' | 'order';

type LinkedPayload = {
  phone: PhoneRow;
  users: Array<{ id: string; userNo: string; phone: string | null; nickname: string | null; isTest: boolean; status: number }>;
  storeAccounts: Array<{ id: string; phone: string; name: string; isTest: boolean; status: string }>;
  partners: Array<{ id: string; phone: string; name: string; companyName: string | null; isTest: boolean; status: string }>;
  stores: Array<{ id: string; name: string; phone: string; isTest: boolean; status: string }>;
};

const ACCOUNT_TYPE_OPTIONS: { value: AccountType; label: string }[] = [
  { value: 'user', label: 'C 端用户' },
  { value: 'store_account', label: '门店账号' },
  { value: 'partner', label: '合伙人' },
  { value: 'store', label: '门店' },
  { value: 'order', label: '订单' },
];

export default function TestWhitelistPage() {
  const [mockSms, setMockSms] = useState(false);
  const [mockWechat, setMockWechat] = useState(false);
  const [mockPay, setMockPay] = useState(false);
  const [mockLoading, setMockLoading] = useState(true);
  const [mockSaving, setMockSaving] = useState(false);

  const [phoneForm] = Form.useForm();
  const [phones, setPhones] = useState<Paginated<PhoneRow> | null>(null);
  const [phonesLoading, setPhonesLoading] = useState(false);
  const [phonePage, setPhonePage] = useState(1);
  const [phonePageSize, setPhonePageSize] = useState(20);
  const [phoneFilters, setPhoneFilters] = useState<{ phone?: string }>({});
  const [addOpen, setAddOpen] = useState(false);
  const [addForm] = Form.useForm();
  const [editOpen, setEditOpen] = useState(false);
  const [editRow, setEditRow] = useState<PhoneRow | null>(null);
  const [editForm] = Form.useForm();
  const [migrating, setMigrating] = useState(false);

  const [accountType, setAccountType] = useState<AccountType>('user');
  const [accountPhone, setAccountPhone] = useState('');
  const [accounts, setAccounts] = useState<Paginated<Record<string, unknown>> | null>(null);
  const [accountsLoading, setAccountsLoading] = useState(false);
  const [accountPage, setAccountPage] = useState(1);
  const [accountPageSize, setAccountPageSize] = useState(20);

  const [linkedOpen, setLinkedOpen] = useState(false);
  const [linkedLoading, setLinkedLoading] = useState(false);
  const [linked, setLinked] = useState<LinkedPayload | null>(null);

  async function loadMockFlags() {
    setMockLoading(true);
    try {
      const cfg = await request<{ mockSms: boolean; mockWechat: boolean; mockPay: boolean }>(
        '/admin/test-whitelist/mock-flags',
      );
      setMockSms(!!cfg.mockSms);
      setMockWechat(!!cfg.mockWechat);
      setMockPay(!!cfg.mockPay);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '加载 Mock 配置失败');
    } finally {
      setMockLoading(false);
    }
  }

  async function saveMockFlags(next: { MOCK_SMS?: boolean; MOCK_WECHAT?: boolean; MOCK_PAY?: boolean }) {
    const body: { mockSms?: boolean; mockWechat?: boolean; mockPay?: boolean } = {};
    if (next.MOCK_SMS !== undefined) body.mockSms = next.MOCK_SMS;
    if (next.MOCK_WECHAT !== undefined) body.mockWechat = next.MOCK_WECHAT;
    if (next.MOCK_PAY !== undefined) body.mockPay = next.MOCK_PAY;
    setMockSaving(true);
    try {
      const cfg = await request<{ mockSms: boolean; mockWechat: boolean; mockPay: boolean }>(
        '/admin/test-whitelist/mock-flags',
        {
          method: 'PUT',
          body: JSON.stringify(body),
        },
      );
      setMockSms(!!cfg.mockSms);
      setMockWechat(!!cfg.mockWechat);
      setMockPay(!!cfg.mockPay);
      message.success('已保存');
    } catch (e) {
      message.error(e instanceof Error ? e.message : '保存失败');
      await loadMockFlags();
    } finally {
      setMockSaving(false);
    }
  }

  const loadPhones = useCallback(async () => {
    setPhonesLoading(true);
    try {
      const qs = new URLSearchParams({
        page: String(phonePage),
        pageSize: String(phonePageSize),
      });
      if (phoneFilters.phone) qs.set('phone', phoneFilters.phone);
      const res = await request<Paginated<PhoneRow>>(`/admin/test-whitelist/phones?${qs}`);
      setPhones(res);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '加载手机号名单失败');
    } finally {
      setPhonesLoading(false);
    }
  }, [phonePage, phonePageSize, phoneFilters]);

  const loadAccounts = useCallback(async () => {
    setAccountsLoading(true);
    try {
      const qs = new URLSearchParams({
        type: accountType,
        page: String(accountPage),
        pageSize: String(accountPageSize),
      });
      if (accountPhone.trim()) qs.set('phone', accountPhone.trim());
      const res = await request<Paginated<Record<string, unknown>>>(
        `/admin/test-whitelist/accounts?${qs}`,
      );
      setAccounts(res);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '加载测试账号失败');
    } finally {
      setAccountsLoading(false);
    }
  }, [accountType, accountPage, accountPageSize, accountPhone]);

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

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

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

  async function onAddPhone() {
    const v = await addForm.validateFields();
    try {
      await request('/admin/test-whitelist/phones', {
        method: 'POST',
        body: JSON.stringify({ phone: v.phone, note: v.note || undefined }),
      });
      message.success('已添加');
      setAddOpen(false);
      addForm.resetFields();
      setPhonePage(1);
      void loadPhones();
      void loadAccounts();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '添加失败');
    }
  }

  async function onEditPhone() {
    if (!editRow) return;
    const v = await editForm.validateFields();
    try {
      await request(`/admin/test-whitelist/phones/${editRow.id}`, {
        method: 'PATCH',
        body: JSON.stringify({ note: v.note ?? null }),
      });
      message.success('已更新');
      setEditOpen(false);
      setEditRow(null);
      void loadPhones();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '更新失败');
    }
  }

  async function onDeletePhone(id: string) {
    try {
      await request(`/admin/test-whitelist/phones/${id}`, { method: 'DELETE' });
      message.success('已删除');
      void loadPhones();
      void loadAccounts();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '删除失败');
    }
  }

  async function onMigrate() {
    setMigrating(true);
    try {
      const res = await request<{ importedCandidates: number; added: number }>(
        '/admin/test-whitelist/migrate-visibility',
        { method: 'POST' },
      );
      message.success(
        `导入完成：候选 ${res.importedCandidates} 个，新增 ${res.added} 个`,
      );
      void loadPhones();
      void loadAccounts();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '导入失败');
    } finally {
      setMigrating(false);
    }
  }

  async function openLinked(row: PhoneRow) {
    setLinkedOpen(true);
    setLinkedLoading(true);
    setLinked(null);
    try {
      const res = await request<LinkedPayload>(`/admin/test-whitelist/phones/${row.id}/linked`);
      setLinked(res);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '加载关联失败');
      setLinkedOpen(false);
    } finally {
      setLinkedLoading(false);
    }
  }

  const phoneColumns: ColumnsType<PhoneRow> = [
    { title: '手机号', dataIndex: 'phone', width: 140 },
    {
      title: '备注',
      dataIndex: 'note',
      render: (v) => v || '—',
    },
    {
      title: '创建时间',
      dataIndex: 'createdAt',
      width: 170,
      render: fmtTime,
    },
    {
      title: '操作',
      width: 220,
      render: (_, row) => (
        <Space size={0}>
          <Button type="link" size="small" onClick={() => void openLinked(row)}>
            关联账号
          </Button>
          <Button
            type="link"
            size="small"
            onClick={() => {
              setEditRow(row);
              editForm.setFieldsValue({ note: row.note ?? '' });
              setEditOpen(true);
            }}
          >
            编辑备注
          </Button>
          <Popconfirm
            title="确认移出白名单？"
            description="将同步清除该手机号关联账号的测试标记"
            okText="确认"
            cancelText="取消"
            okButtonProps={{ danger: true }}
            onConfirm={() => void onDeletePhone(row.id)}
          >
            <Button type="link" size="small" danger>
              删除
            </Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  function accountColumns(): ColumnsType<Record<string, unknown>> {
    if (accountType === 'user') {
      return [
        { title: '用户编号', dataIndex: 'userNo', width: 120 },
        { title: '昵称', dataIndex: 'nickname', width: 100, render: (v) => (v as string) || '—' },
        { title: '手机', dataIndex: 'phone', width: 120 },
        {
          title: '标记',
          dataIndex: 'isTest',
          width: 80,
          render: (v) => (v ? <Tag color="orange">测试</Tag> : '—'),
        },
        { title: '注册', dataIndex: 'createdAt', width: 170, render: (v) => fmtTime(v as string) },
      ];
    }
    if (accountType === 'store_account') {
      return [
        { title: '姓名', dataIndex: 'name', width: 100 },
        { title: '手机', dataIndex: 'phone', width: 120 },
        { title: '状态', dataIndex: 'status', width: 90 },
        {
          title: '标记',
          dataIndex: 'isTest',
          width: 80,
          render: (v) => (v ? <Tag color="orange">测试</Tag> : '—'),
        },
        { title: '创建', dataIndex: 'createdAt', width: 170, render: (v) => fmtTime(v as string) },
      ];
    }
    if (accountType === 'partner') {
      return [
        { title: '姓名', dataIndex: 'name', width: 100 },
        { title: '公司', dataIndex: 'companyName', render: (v) => (v as string) || '—' },
        { title: '手机', dataIndex: 'phone', width: 120 },
        {
          title: '标记',
          dataIndex: 'isTest',
          width: 80,
          render: (v) => (v ? <Tag color="orange">测试</Tag> : '—'),
        },
        { title: '创建', dataIndex: 'createdAt', width: 170, render: (v) => fmtTime(v as string) },
      ];
    }
    if (accountType === 'store') {
      return [
        { title: '门店名', dataIndex: 'name', width: 160 },
        { title: '城市', dataIndex: 'cityName', width: 90 },
        { title: '电话', dataIndex: 'phone', width: 120 },
        { title: '状态', dataIndex: 'status', width: 90 },
        {
          title: '标记',
          dataIndex: 'isTest',
          width: 80,
          render: (v) => (v ? <Tag color="orange">测试</Tag> : '—'),
        },
        { title: '创建', dataIndex: 'createdAt', width: 170, render: (v) => fmtTime(v as string) },
      ];
    }
    return [
      { title: '订单号', dataIndex: 'orderNo', width: 180 },
      { title: '状态', dataIndex: 'status', width: 110 },
      {
        title: '实付',
        dataIndex: 'payAmount',
        width: 90,
        render: (v) => `¥${v}`,
      },
      { title: '收货手机', dataIndex: 'receiverPhone', width: 120 },
      {
        title: '用户手机',
        width: 120,
        render: (_, row) =>
          (row.user as { phone?: string | null } | undefined)?.phone || '—',
      },
      {
        title: '标记',
        dataIndex: 'isTest',
        width: 80,
        render: (v) => (v ? <Tag color="orange">测试</Tag> : '—'),
      },
      { title: '下单', dataIndex: 'createdAt', width: 170, render: (v) => fmtTime(v as string) },
    ];
  }

  const { columns, settingsButton, settingsModal } = useAdminListColumns('test-whitelist', phoneColumns, {
    page: phonePage,
    pageSize: phonePageSize,
  });

  return (
    <div>
      {settingsModal}
      <Typography.Title level={4} style={{ marginTop: 0 }}>
        白名单管理
      </Typography.Title>
      {settingsButton}

      <Card size="small" loading={mockLoading} style={{ marginBottom: 16 }}>
        <Typography.Text type="secondary" style={{ display: 'block', marginBottom: 12 }}>
          Mock 开关（与系统设置同源，勾选 = 不做真实验证）
        </Typography.Text>
        <Space wrap>
          <Checkbox
            checked={mockSms}
            disabled={mockSaving}
            onChange={(e) => void saveMockFlags({ MOCK_SMS: e.target.checked })}
          >
            短信不做真实验证
          </Checkbox>
          <Checkbox
            checked={mockWechat}
            disabled={mockSaving}
            onChange={(e) => void saveMockFlags({ MOCK_WECHAT: e.target.checked })}
          >
            微信不做真实验证
          </Checkbox>
          <Checkbox
            checked={mockPay}
            disabled={mockSaving}
            onChange={(e) => void saveMockFlags({ MOCK_PAY: e.target.checked })}
          >
            支付不做真实验证
          </Checkbox>
        </Space>
        <Typography.Text type="secondary" style={{ display: 'block', marginTop: 8, fontSize: 12 }}>
          配置键：{MOCK_KEYS.join(' / ')}
        </Typography.Text>
      </Card>

      <Tabs
        items={[
          {
            key: 'phones',
            label: '手机号名单',
            children: (
              <>
                <Space style={{ marginBottom: 16, width: '100%', justifyContent: 'space-between' }} wrap>
                  <Form
                    form={phoneForm}
                    layout="inline"
                    onFinish={(v) => {
                      setPhoneFilters({ phone: v.phone || undefined });
                      setPhonePage(1);
                    }}
                  >
                    <Form.Item name="phone" label="手机号">
                      <Input allowClear placeholder="模糊搜索" />
                    </Form.Item>
                    <Form.Item>
                      <Button type="primary" htmlType="submit">
                        查询
                      </Button>
                    </Form.Item>
                  </Form>
                  <Space>
                    <Button
                      onClick={() => {
                        Modal.confirm({
                          title: '从可见性白名单导入',
                          content: '将商品/门店旧可见性手机号合并入全局名单（幂等），并同步测试标记。',
                          okText: '开始导入',
                          cancelText: '取消',
                          onOk: () => onMigrate(),
                        });
                      }}
                      loading={migrating}
                    >
                      从可见性白名单导入
                    </Button>
                    <Button type="primary" onClick={() => setAddOpen(true)}>
                      添加手机号
                    </Button>
                  </Space>
                </Space>
                <Table
                  rowKey="id"
                  loading={phonesLoading}
                  columns={columns}
                  dataSource={phones?.items ?? []}
                  pagination={{
                    current: phonePage,
                    pageSize: phonePageSize,
                    total: phones?.total ?? 0,
                    showSizeChanger: true,
                    onChange: (p, ps) => {
                      setPhonePage(p);
                      setPhonePageSize(ps);
                    },
                  }}
                />
              </>
            ),
          },
          {
            key: 'accounts',
            label: '测试账号记录',
            children: (
              <>
                <Space style={{ marginBottom: 16 }} wrap>
                  <Select
                    style={{ width: 140 }}
                    value={accountType}
                    options={ACCOUNT_TYPE_OPTIONS}
                    onChange={(v: AccountType) => {
                      setAccountType(v);
                      setAccountPage(1);
                    }}
                  />
                  <Input
                    allowClear
                    placeholder="按手机号筛选"
                    style={{ width: 160 }}
                    value={accountPhone}
                    onChange={(e) => setAccountPhone(e.target.value)}
                    onPressEnter={() => {
                      setAccountPage(1);
                      void loadAccounts();
                    }}
                  />
                  <Button
                    type="primary"
                    onClick={() => {
                      if (accountPage !== 1) setAccountPage(1);
                      else void loadAccounts();
                    }}
                  >
                    查询
                  </Button>
                </Space>
                <Table
                  rowKey="id"
                  loading={accountsLoading}
                  columns={accountColumns()}
                  dataSource={accounts?.items ?? []}
                  scroll={{ x: 900 }}
                  pagination={{
                    current: accountPage,
                    pageSize: accountPageSize,
                    total: accounts?.total ?? 0,
                    showSizeChanger: true,
                    onChange: (p, ps) => {
                      setAccountPage(p);
                      setAccountPageSize(ps);
                    },
                  }}
                />
              </>
            ),
          },
        ]}
      />

      <Modal
        title="添加白名单手机号"
        open={addOpen}
        onCancel={() => setAddOpen(false)}
        onOk={() => void onAddPhone()}
        destroyOnClose
      >
        <Form form={addForm} layout="vertical">
          <Form.Item
            name="phone"
            label="手机号"
            rules={[
              { required: true, message: '请输入手机号' },
              { pattern: /^1\d{10}$/, message: '请输入 11 位手机号' },
            ]}
          >
            <Input placeholder="1xxxxxxxxxx" maxLength={11} />
          </Form.Item>
          <Form.Item name="note" label="备注">
            <Input.TextArea rows={2} maxLength={256} showCount />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={`编辑备注 · ${editRow?.phone ?? ''}`}
        open={editOpen}
        onCancel={() => {
          setEditOpen(false);
          setEditRow(null);
        }}
        onOk={() => void onEditPhone()}
        destroyOnClose
      >
        <Form form={editForm} layout="vertical">
          <Form.Item name="note" label="备注">
            <Input.TextArea rows={2} maxLength={256} showCount />
          </Form.Item>
        </Form>
      </Modal>

      <Drawer
        title={linked ? `关联账号 · ${linked.phone.phone}` : '关联账号'}
        open={linkedOpen}
        onClose={() => setLinkedOpen(false)}
        width={560}
        destroyOnClose
      >
        {linkedLoading ? (
          <Typography.Text type="secondary">加载中…</Typography.Text>
        ) : linked ? (
          <Space direction="vertical" size={16} style={{ width: '100%' }}>
            <Descriptions size="small" column={1} bordered>
              <Descriptions.Item label="手机号">{linked.phone.phone}</Descriptions.Item>
              <Descriptions.Item label="备注">{linked.phone.note || '—'}</Descriptions.Item>
            </Descriptions>
            <div>
              <Typography.Title level={5}>C 端用户（{linked.users.length}）</Typography.Title>
              <Table
                size="small"
                rowKey="id"
                pagination={false}
                dataSource={linked.users}
                columns={[
                  { title: '编号', dataIndex: 'userNo' },
                  { title: '昵称', dataIndex: 'nickname', render: (v) => v || '—' },
                  {
                    title: '测试',
                    dataIndex: 'isTest',
                    width: 70,
                    render: (v) => (v ? <Tag color="orange">测试</Tag> : '—'),
                  },
                ]}
              />
            </div>
            <div>
              <Typography.Title level={5}>门店账号（{linked.storeAccounts.length}）</Typography.Title>
              <Table
                size="small"
                rowKey="id"
                pagination={false}
                dataSource={linked.storeAccounts}
                columns={[
                  { title: '姓名', dataIndex: 'name' },
                  { title: '状态', dataIndex: 'status', width: 90 },
                  {
                    title: '测试',
                    dataIndex: 'isTest',
                    width: 70,
                    render: (v) => (v ? <Tag color="orange">测试</Tag> : '—'),
                  },
                ]}
              />
            </div>
            <div>
              <Typography.Title level={5}>合伙人（{linked.partners.length}）</Typography.Title>
              <Table
                size="small"
                rowKey="id"
                pagination={false}
                dataSource={linked.partners}
                columns={[
                  { title: '姓名', dataIndex: 'name' },
                  { title: '公司', dataIndex: 'companyName', render: (v) => v || '—' },
                  {
                    title: '测试',
                    dataIndex: 'isTest',
                    width: 70,
                    render: (v) => (v ? <Tag color="orange">测试</Tag> : '—'),
                  },
                ]}
              />
            </div>
            <div>
              <Typography.Title level={5}>门店（{linked.stores.length}）</Typography.Title>
              <Table
                size="small"
                rowKey="id"
                pagination={false}
                dataSource={linked.stores}
                columns={[
                  { title: '名称', dataIndex: 'name' },
                  { title: '状态', dataIndex: 'status', width: 90 },
                  {
                    title: '测试',
                    dataIndex: 'isTest',
                    width: 70,
                    render: (v) => (v ? <Tag color="orange">测试</Tag> : '—'),
                  },
                ]}
              />
            </div>
          </Space>
        ) : null}
      </Drawer>
    </div>
  );
}
