import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Link, useSearchParams } from 'react-router-dom';
import {
  Alert,
  Button,
  Checkbox,
  Collapse,
  Descriptions,
  Drawer,
  Form,
  Input,
  InputNumber,
  Modal,
  Radio,
  Select,
  Space,
  Table,
  Tag,
  Typography,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import { request, type AdminOrderItem, type AdminOrderRow, type HqProfile, type Paginated } from '../lib/api';
import {
  ADMIN_OPTIONS_PAGE_SIZE,
  DELIVERY_PROVIDER_LABELS,
  ORDER_STATUS_COLORS,
  ORDER_STATUS_LABELS,
  ORDER_STATUS_OPERATOR_LABELS,
  fmtTime,
} from '../lib/constants';
import { FULFILLMENT_HOLD_REASON_LABELS } from '@dukang/shared-types';
import ProxyOrderModal from '../components/ProxyOrderModal';
import OrderTrackDrawer from '../components/OrderTrackDrawer';

type ShipDefaults = {
  provider: string;
  providerLabel: string;
  fromName: string;
  fromMobile: string;
  fromAddress: string;
  fromAddressDetail: string;
  fromLng: number;
  fromLat: number;
  weight: number;
  payMode: string;
};

type CityOption = { id: string; name: string; code: string };

type WarehouseOption = {
  id: string;
  name: string;
  cityId?: string;
  cityName?: string;
  status?: string;
  contactName: string;
  contactPhone: string;
  address: string;
  lng?: number | null;
  lat?: number | null;
};

type OrderRedeemRecord = {
  id: string;
  redeemNo: string;
  amount: number;
  settleAmount: number;
  /** 本单权益券在该核销单中的分摊额 */
  couponAmount?: number;
  role?: 'PRIMARY' | 'SECONDARY';
  createdAt: string;
  store?: { id: string; name: string; cityName?: string | null } | null;
};

type OrderRedeemSummary = {
  couponNo: string;
  totalAmount: number;
  usedAmount: number;
  balance: number;
  status: string;
  redeemCount: number;
  redeemRecordSum: number;
};

type OrderDetail = AdminOrderRow & {
  receiverAddress?: string;
  receiverProvince?: string;
  receiverCity?: string;
  receiverDistrict?: string;
  clientIp?: string | null;
  ipProvince?: string | null;
  ipCity?: string | null;
  ipDistrict?: string | null;
  gpsProvince?: string | null;
  gpsCity?: string | null;
  gpsDistrict?: string | null;
  gpsLatitude?: number | null;
  gpsLongitude?: number | null;
  gpsAddress?: string | null;
  productAmount?: number;
  freightAmount?: number;
  benefitAmount?: number;
  paidAt?: string | null;
  payExpireAt?: string | null;
  productImage?: string;
  listUnitPrice?: number;
  items?: AdminOrderItem[];
  payment?: Record<string, unknown> | null;
  statusLogs?: Array<{
    fromStatus: string | null;
    toStatus: string;
    operator?: string | null;
    remark?: string | null;
    createdAt: string;
  }>;
  benefitCoupons?: Array<Record<string, unknown>>;
  redeemSummary?: OrderRedeemSummary | null;
  redeemRecords?: OrderRedeemRecord[];
  fulfillmentWarehouse?: {
    id: string;
    name: string;
    contactName?: string;
    contactPhone?: string;
    address?: string;
    lng?: number | null;
    lat?: number | null;
  } | null;
};

type ShipMode = 'WAREHOUSE' | 'EXPRESS';

function orderProductRows(detail: OrderDetail): AdminOrderItem[] {
  if (detail.items?.length) return detail.items;
  if (!detail.productName) return [];
  return [{
    productName: detail.productName,
    productSpec: detail.productSpec ?? '',
    productImage: detail.productImage ?? '',
    unitPrice: Number(detail.listUnitPrice ?? 0),
    quantity: detail.quantity ?? 1,
  }];
}

function canShip(row: { status: string; delivery?: { trackingNo?: string | null } | null }) {
  return ['PENDING_SHIP', 'OUT_WAREHOUSE'].includes(row.status) && !row.delivery?.trackingNo;
}

function warehouseToDefaults(wh: WarehouseOption, base?: ShipDefaults | null): ShipDefaults {
  return {
    provider: 'XFX',
    providerLabel: '小飞侠',
    fromName: wh.contactName || base?.fromName || '杜康仓库',
    fromMobile: wh.contactPhone || base?.fromMobile || '13800000000',
    fromAddress: wh.address || base?.fromAddress || '',
    fromAddressDetail: wh.name || base?.fromAddressDetail || '',
    fromLng: wh.lng != null ? Number(wh.lng) : (base?.fromLng ?? 113.665),
    fromLat: wh.lat != null ? Number(wh.lat) : (base?.fromLat ?? 34.757),
    weight: base?.weight ?? 2,
    payMode: base?.payMode ?? '1',
  };
}

export default function OrdersPage() {
  const [searchParams] = useSearchParams();
  const initialOrderNo = searchParams.get('orderNo')?.trim() || '';
  const [form] = Form.useForm();
  const [shipForm] = Form.useForm();
  const [logisticsForm] = Form.useForm();
  const [profile, setProfile] = useState<HqProfile | null>(null);
  const [data, setData] = useState<Paginated<AdminOrderRow> | null>(null);
  const [loading, setLoading] = useState(false);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);
  const [detail, setDetail] = useState<OrderDetail | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const deepLinkOpenedRef = useRef(false);
  const [redeemDetail, setRedeemDetail] = useState<Record<string, unknown> | null>(null);
  const [redeemDrawerOpen, setRedeemDrawerOpen] = useState(false);
  const [redeemDetailLoading, setRedeemDetailLoading] = useState(false);
  const [selectedRowKeys, setSelectedRowKeys] = useState<string[]>([]);
  const [batchDeleteOpen, setBatchDeleteOpen] = useState(false);
  const [batchDeleting, setBatchDeleting] = useState(false);
  const [deletingId, setDeletingId] = useState<string | null>(null);
  const [shipDefaults, setShipDefaults] = useState<ShipDefaults | null>(null);
  const [shipping, setShipping] = useState(false);
  const [logisticsShipping, setLogisticsShipping] = useState(false);
  const [cities, setCities] = useState<CityOption[]>([]);
  const [shipModalOpen, setShipModalOpen] = useState(false);
  const [shipTarget, setShipTarget] = useState<OrderDetail | null>(null);
  const [shipMode, setShipMode] = useState<ShipMode>('EXPRESS');
  const [warehouses, setWarehouses] = useState<WarehouseOption[]>([]);
  const [proxyOpen, setProxyOpen] = useState(false);
  const [trackOpen, setTrackOpen] = useState(false);
  const canDeleteOrders = (profile?.permissionKeys ?? []).includes('orders_delete');
  const canProxyOrder = (profile?.permissionKeys ?? []).includes('orders');

  const selectedOrders = useMemo(
    () => (data?.items ?? []).filter((row) => selectedRowKeys.includes(row.id)),
    [data?.items, selectedRowKeys],
  );

  useEffect(() => {
    request<HqProfile>('/admin/auth/me').then(setProfile).catch(() => {});
  }, []);

  useEffect(() => {
    if (initialOrderNo) {
      form.setFieldsValue({ orderNo: initialOrderNo });
    }
  }, [form, initialOrderNo]);

  useEffect(() => {
    if (!initialOrderNo || deepLinkOpenedRef.current || loading) return;
    const first = data?.items?.[0];
    if (first && String(first.orderNo) === initialOrderNo) {
      deepLinkOpenedRef.current = true;
      void openDetail(first.id);
    }
  }, [data, initialOrderNo, loading]);

  async function openRedeemDetail(redeemId: string) {
    setRedeemDetailLoading(true);
    setRedeemDrawerOpen(true);
    try {
      const res = await request<Record<string, unknown>>(`/admin/redeem-records/${redeemId}`);
      setRedeemDetail(res);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '加载核销详情失败');
      setRedeemDrawerOpen(false);
    } finally {
      setRedeemDetailLoading(false);
    }
  }

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const values = form.getFieldsValue();
      const qs = new URLSearchParams({ page: String(page), pageSize: String(pageSize) });
      if (values.orderNo) qs.set('orderNo', values.orderNo);
      if (values.status) qs.set('status', values.status);
      if (values.orderType) qs.set('orderType', values.orderType);
      if (values.cityId) qs.set('cityId', values.cityId);
      if (values.receiverPhone) qs.set('receiverPhone', values.receiverPhone);
      if (values.fulfillmentHold) qs.set('fulfillmentHold', 'true');
      if (values.excludeTest) qs.set('excludeTest', 'true');
      const res = await request<Paginated<AdminOrderRow>>(`/admin/orders?${qs}`);
      setData(res);
    } finally {
      setLoading(false);
    }
  }, [form, page, pageSize]);

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

  useEffect(() => {
    void request<ShipDefaults>('/admin/orders/ship-defaults').then(setShipDefaults).catch(() => {});
    void request<Paginated<CityOption>>(`/admin/cities?pageSize=${ADMIN_OPTIONS_PAGE_SIZE}`)
      .then((res) => setCities(res.items ?? []))
      .catch(() => {});
  }, []);

  function applyShipDefaults(defaults: ShipDefaults, warehouseId?: string | null) {
    shipForm.setFieldsValue({
      warehouseId: warehouseId || undefined,
      provider: defaults.provider,
      weight: defaults.weight,
      payMode: defaults.payMode,
      fromName: defaults.fromName,
      fromMobile: defaults.fromMobile,
      fromAddress: defaults.fromAddress,
      fromAddressDetail: defaults.fromAddressDetail,
      fromLng: defaults.fromLng,
      fromLat: defaults.fromLat,
    });
  }

  async function loadWarehouses() {
    const res = await request<Paginated<WarehouseOption>>(
      `/admin/city-warehouses?pageSize=${ADMIN_OPTIONS_PAGE_SIZE}&status=ACTIVE`,
    ).catch(() => null);
    const rows = (res?.items ?? []).filter((w) => !w.status || w.status === 'ACTIVE');
    setWarehouses(rows);
    return rows;
  }

  async function openDetail(id: string) {
    const res = await request<OrderDetail>(`/admin/orders/${id}`);
    setDetail(res);
    setDrawerOpen(true);
  }

  async function openShipModal(id: string) {
    const res = await request<OrderDetail>(`/admin/orders/${id}`);
    setShipTarget(res);
    setDetail(res);
    logisticsForm.setFieldsValue({
      logisticsCompany: '',
      trackingNo: '',
      manualQueryUrl: '',
    });
    const rows = await loadWarehouses();
    const preferredWarehouseId = res.fulfillmentWarehouseId || res.fulfillmentWarehouse?.id;
    const preferred =
      rows.find((w) => w.id === preferredWarehouseId) ||
      rows.find((w) => w.cityId === (res.city?.id || res.cityId)) ||
      rows[0];
    const defaults = preferred
      ? warehouseToDefaults(preferred, shipDefaults)
      : (shipDefaults ?? await request<ShipDefaults>('/admin/orders/ship-defaults').catch(() => null));
    if (defaults) {
      setShipDefaults(defaults);
      applyShipDefaults(defaults, preferred?.id);
    } else {
      shipForm.setFieldsValue({ warehouseId: preferred?.id, provider: 'XFX' });
    }
    setShipMode(preferred ? 'WAREHOUSE' : 'EXPRESS');
    setShipModalOpen(true);
  }

  async function onWarehouseChange(warehouseId: string) {
    const wh = warehouses.find((w) => w.id === warehouseId);
    if (!wh) return;
    applyShipDefaults(warehouseToDefaults(wh, shipDefaults), warehouseId);
  }

  async function submitShip() {
    if (!shipTarget) return;
    const values = await shipForm.validateFields();
    setShipping(true);
    try {
      const res = await request<OrderDetail>(`/admin/orders/${shipTarget.id}/ship`, {
        method: 'POST',
        body: JSON.stringify({
          provider: values.provider || 'XFX',
          warehouseId: values.warehouseId,
          weight: values.weight,
          payMode: values.payMode,
          remark: values.remark,
          fromName: values.fromName,
          fromMobile: values.fromMobile,
          fromAddress: values.fromAddress,
          fromAddressDetail: values.fromAddressDetail,
          fromLng: values.fromLng,
          fromLat: values.fromLat,
        }),
      });
      message.success('选仓发货成功');
      setShipTarget(res);
      setDetail(res);
      setShipModalOpen(false);
      void load();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '发货失败');
    } finally {
      setShipping(false);
    }
  }

  async function submitLogisticsShip() {
    if (!shipTarget) return;
    const values = await logisticsForm.validateFields(['logisticsCompany', 'trackingNo', 'manualQueryUrl']);
    const logisticsCompany = String(values.logisticsCompany ?? '').trim();
    const trackingNo = String(values.trackingNo ?? '').trim();
    if (!logisticsCompany || !trackingNo) {
      message.error('请填写快递公司与运单号');
      return;
    }
    setLogisticsShipping(true);
    try {
      const res = await request<OrderDetail>(`/admin/orders/${shipTarget.id}/logistics-ship`, {
        method: 'POST',
        body: JSON.stringify({
          logisticsCompany,
          trackingNo,
          manualQueryUrl: String(values.manualQueryUrl ?? '').trim() || undefined,
        }),
      });
      message.success('快递单已录入');
      setShipTarget(res);
      setDetail(res);
      setShipModalOpen(false);
      void load();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '填单失败');
    } finally {
      setLogisticsShipping(false);
    }
  }

  async function confirmBatchDelete() {
    if (!selectedRowKeys.length) return;
    setBatchDeleting(true);
    try {
      const res = await request<{ deleted: number; message: string }>('/admin/orders/batch-delete', {
        method: 'POST',
        body: JSON.stringify({ ids: selectedRowKeys }),
      });
      message.success(res.message || `已删除 ${res.deleted} 笔订单`);
      setBatchDeleteOpen(false);
      setSelectedRowKeys([]);
      if (detail && selectedRowKeys.includes(detail.id)) {
        setDrawerOpen(false);
        setDetail(null);
      }
      void load();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '批量删除失败');
    } finally {
      setBatchDeleting(false);
    }
  }

  function askDeleteOrder(id: string, orderNo?: string) {
    Modal.confirm({
      title: '确认删除订单？',
      content: (
        <div>
          <p>将永久删除订单{orderNo ? ` ${orderNo}` : ''} 及其配送、权益券、核销、发票等关联数据。</p>
          <p style={{ color: 'var(--ant-color-error)', marginBottom: 0 }}>此操作不可恢复，请确认不是真实线上订单。</p>
        </div>
      ),
      okText: '确认删除',
      okType: 'danger',
      cancelText: '取消',
      onOk: () => deleteOrder(id),
    });
  }

  async function deleteOrder(id: string) {
    setDeletingId(id);
    try {
      const res = await request<{ deleted: number; message: string }>(`/admin/orders/${id}`, {
        method: 'DELETE',
      });
      message.success(res.message || '订单已删除');
      if (detail?.id === id) {
        setDrawerOpen(false);
        setDetail(null);
      }
      setSelectedRowKeys((prev) => prev.filter((k) => k !== id));
      void load();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '删除失败');
      throw e;
    } finally {
      setDeletingId(null);
    }
  }

  const columns: ColumnsType<AdminOrderRow> = [
    {
      title: '订单号',
      dataIndex: 'orderNo',
      width: 200,
      render: (v, row) => (
        <Space size={4}>
          <span>{v}</span>
          {row.isTest ? <Tag color="orange">测试</Tag> : null}
        </Space>
      ),
    },
    {
      title: '城市',
      width: 90,
      render: (_, row) => row.city?.name || '—',
    },
    {
      title: '商品',
      width: 180,
      ellipsis: true,
      render: (_, row) => {
        const name = row.productName || '—';
        const qty = row.quantity != null ? ` ×${row.quantity}` : '';
        return (
          <span title={row.productSpec ? `${name}（${row.productSpec}）` : name}>
            {name}{qty}
          </span>
        );
      },
    },
    {
      title: '状态',
      dataIndex: 'status',
      width: 140,
      render: (s, row) => (
        <Space size={4} wrap>
          <Tag color={ORDER_STATUS_COLORS[s] || 'default'}>{ORDER_STATUS_LABELS[s] || s}</Tag>
          {row.fulfillmentHold ? <Tag color="orange">大单待确认</Tag> : null}
          {row.orderType === 'PROXY' || row.isProxyOrder ? (
            <Tag color="purple" title={row.proxyPartnerName || undefined}>
              代下单
            </Tag>
          ) : null}
        </Space>
      ),
    },
    {
      title: '配送',
      dataIndex: 'deliveryType',
      width: 90,
      render: (v) =>
        v === 'ON_SITE_PICKUP' ? '现场提货' : v === 'LOCAL' ? '同城' : '跨城',
    },
    { title: '实付', dataIndex: 'payAmount', width: 90, render: (v) => `¥${v}` },
    { title: '收货人', dataIndex: 'receiverName', width: 90 },
    { title: '手机', dataIndex: 'receiverPhone', width: 120 },
    {
      title: '用户',
      dataIndex: ['user', 'userNo'],
      width: 110,
      render: (_, row) => row.user?.userNo || '—',
    },
    {
      title: '快递',
      width: 100,
      render: (_, row) => row.delivery?.trackingNo || row.delivery?.provider || '—',
    },
    {
      title: '下单时间',
      dataIndex: 'createdAt',
      width: 170,
      render: (v) => new Date(v).toLocaleString('zh-CN'),
    },
    {
      title: '操作',
      width: 180,
      fixed: 'right',
      render: (_, row) => (
        <Space size={0}>
          <Button type="link" size="small" onClick={() => openDetail(row.id)}>
            详情
          </Button>
          {canShip(row) && (
            <Button type="link" size="small" onClick={() => void openShipModal(row.id)}>
              配送
            </Button>
          )}
          {canDeleteOrders && (
            <Button
              type="link"
              size="small"
              danger
              loading={deletingId === row.id}
              onClick={() => askDeleteOrder(row.id, row.orderNo)}
            >
              删除
            </Button>
          )}
        </Space>
      ),
    },
  ];

  return (
    <div>
      <Space style={{ marginBottom: 16, width: '100%', justifyContent: 'space-between' }}>
        <Typography.Title level={4} style={{ margin: 0 }}>订单监控</Typography.Title>
        <Space>
          <Button onClick={() => window.open('/orders/big-screen', 'dukang-big-screen')}>大屏</Button>
          {canProxyOrder ? (
            <Button type="primary" onClick={() => setProxyOpen(true)}>
              代下单
            </Button>
          ) : null}
          {canDeleteOrders ? (
            <Button
              danger
              disabled={!selectedRowKeys.length}
              onClick={() => setBatchDeleteOpen(true)}
            >
              批量删除{selectedRowKeys.length ? ` (${selectedRowKeys.length})` : ''}
            </Button>
          ) : null}
        </Space>
      </Space>

      {!canDeleteOrders && profile ? (
        <Alert
          type="info"
          showIcon
          style={{ marginBottom: 16 }}
          message="当前账号无「删除订单」权限"
          description={
            <span>
              非超管账号需在 <Link to="/hq-permissions">权限分配</Link> 中勾选危险操作「删除订单」。
            </span>
          }
        />
      ) : null}

      <Form form={form} layout="inline" style={{ marginBottom: 16 }} onFinish={() => { setPage(1); void load(); }}>
        <Form.Item name="orderNo" label="订单号">
          <Input placeholder="DK..." allowClear />
        </Form.Item>
        <Form.Item name="status" label="状态">
          <Select allowClear style={{ width: 120 }} options={Object.entries(ORDER_STATUS_LABELS).map(([value, label]) => ({ value, label }))} />
        </Form.Item>
        <Form.Item name="orderType" label="类型">
          <Select
            allowClear
            style={{ width: 120 }}
            placeholder="全部"
            options={[
              { value: 'NORMAL', label: '普通订单' },
              { value: 'PROXY', label: '代下单' },
            ]}
          />
        </Form.Item>
        <Form.Item name="cityId" label="城市">
          <Select
            allowClear
            showSearch
            optionFilterProp="label"
            style={{ width: 140 }}
            placeholder="全部"
            options={cities.map((c) => ({ value: c.id, label: c.name }))}
          />
        </Form.Item>
        <Form.Item name="receiverPhone" label="收货手机">
          <Input allowClear />
        </Form.Item>
        <Form.Item name="fulfillmentHold" label="大单拦截" valuePropName="checked">
          <Select
            allowClear
            style={{ width: 140 }}
            placeholder="全部"
            options={[{ value: true, label: '仅待确认大单' }]}
          />
        </Form.Item>
        <Form.Item name="excludeTest" valuePropName="checked">
          <Checkbox>过滤测试账号</Checkbox>
        </Form.Item>
        <Form.Item>
          <Space>
            <Button type="primary" htmlType="submit">查询</Button>
            <Button onClick={() => { form.resetFields(); setPage(1); void load(); }}>重置</Button>
          </Space>
        </Form.Item>
      </Form>

      <Table
        rowKey="id"
        loading={loading}
        columns={columns}
        dataSource={data?.items ?? []}
        scroll={{ x: 1500 }}
        rowSelection={canDeleteOrders ? {
          selectedRowKeys,
          onChange: (keys) => setSelectedRowKeys(keys as string[]),
        } : undefined}
        pagination={{
          current: page,
          pageSize,
          total: data?.total ?? 0,
          showSizeChanger: true,
          onChange: (p, ps) => {
            setPage(p);
            setPageSize(ps);
          },
        }}
      />

      <Drawer
        title="订单详情"
        width={720}
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        extra={detail && (
          <Space>
            {canShip(detail) && (
              <Button type="primary" onClick={() => void openShipModal(detail.id)}>
                配送发货
              </Button>
            )}
            {canDeleteOrders && (
              <Button
                danger
                loading={deletingId === detail.id}
                onClick={() => askDeleteOrder(detail.id, detail.orderNo)}
              >
                删除订单
              </Button>
            )}
            <Typography.Text type="secondary">调试改状态</Typography.Text>
            <Select
              value={detail.status}
              style={{ width: 120 }}
              options={Object.entries(ORDER_STATUS_LABELS).map(([value, label]) => ({ value, label }))}
              onChange={async (status) => {
                await request(`/admin/orders/${detail.id}/status`, {
                  method: 'PUT',
                  body: JSON.stringify({ status }),
                });
                message.success('状态已更新（调试）');
                const res = await request<OrderDetail>(`/admin/orders/${detail.id}`);
                setDetail(res);
                void load();
              }}
            />
          </Space>
        )}
      >
        {detail && (
          <>
            <Descriptions column={1} bordered size="small" title="基本信息">
              <Descriptions.Item label="订单号">{detail.orderNo}</Descriptions.Item>
              <Descriptions.Item label="开城城市">
                {detail.city?.name || '—'}
                {detail.city?.code ? `（${detail.city.code}）` : ''}
              </Descriptions.Item>
              <Descriptions.Item label="履约仓">
                {detail.fulfillmentWarehouse?.name || '未分配'}
              </Descriptions.Item>
              <Descriptions.Item label="状态">
                <Space>
                  <Tag color={ORDER_STATUS_COLORS[detail.status] || 'default'}>
                    {ORDER_STATUS_LABELS[detail.status] || detail.status}
                  </Tag>
                  {detail.fulfillmentHold ? (
                    <Tag color="orange">
                      {FULFILLMENT_HOLD_REASON_LABELS[detail.fulfillmentHoldReason || ''] ||
                        '大单待确认'}
                    </Tag>
                  ) : null}
                  {detail.orderType === 'PROXY' || detail.isProxyOrder ? (
                    <Tag color="purple">代下单</Tag>
                  ) : null}
                </Space>
              </Descriptions.Item>
              {detail.orderType === 'PROXY' || detail.isProxyOrder || detail.proxyPartnerName ? (
                <Descriptions.Item label="代下单人">
                  {[detail.proxyPartnerName, detail.proxyPartnerPhone].filter(Boolean).join(' / ') || '—'}
                </Descriptions.Item>
              ) : null}
              <Descriptions.Item label="用户">{detail.user?.userNo} / {detail.user?.nickname}</Descriptions.Item>
              <Descriptions.Item label="商品额">¥{detail.productAmount}</Descriptions.Item>
              <Descriptions.Item label="实付">¥{detail.payAmount}</Descriptions.Item>
              <Descriptions.Item label="好客权益">¥{detail.benefitAmount}</Descriptions.Item>
              <Descriptions.Item label="下单时间">{new Date(detail.createdAt).toLocaleString('zh-CN')}</Descriptions.Item>
            </Descriptions>

            <Typography.Title level={5} style={{ marginTop: 16, marginBottom: 8 }}>商品</Typography.Title>
            <Table
              size="small"
              rowKey={(_, i) => String(i)}
              pagination={false}
              dataSource={orderProductRows(detail)}
              locale={{ emptyText: '无商品信息' }}
              columns={[
                {
                  title: '商品',
                  dataIndex: 'productName',
                  render: (name: string, row) => (
                    <Space>
                      {row.productImage ? (
                        <img
                          src={row.productImage}
                          alt=""
                          style={{ width: 40, height: 40, objectFit: 'cover', borderRadius: 4 }}
                        />
                      ) : null}
                      <span>
                        {name || '—'}
                        {row.productSpec ? (
                          <Typography.Text type="secondary" style={{ display: 'block', fontSize: 12 }}>
                            {row.productSpec}
                          </Typography.Text>
                        ) : null}
                      </span>
                    </Space>
                  ),
                },
                {
                  title: '单价',
                  dataIndex: 'unitPrice',
                  width: 90,
                  render: (v: number) => `¥${v}`,
                },
                {
                  title: '数量',
                  dataIndex: 'quantity',
                  width: 70,
                },
              ]}
            />

            <Descriptions column={1} bordered size="small" title="收货信息" style={{ marginTop: 16 }}>
              <Descriptions.Item label="收货人">{detail.receiverName} {detail.receiverPhone}</Descriptions.Item>
              <Descriptions.Item label="地址">{detail.receiverAddress}</Descriptions.Item>
            </Descriptions>

            <Typography.Title level={5} style={{ marginTop: 16, marginBottom: 8 }}>
              权益核销
            </Typography.Title>
            {detail.redeemSummary ? (
              <>
                <Descriptions column={2} bordered size="small" style={{ marginBottom: 12 }}>
                  <Descriptions.Item label="权益券号">{detail.redeemSummary.couponNo}</Descriptions.Item>
                  <Descriptions.Item label="券状态">{detail.redeemSummary.status}</Descriptions.Item>
                  <Descriptions.Item label="权益总额">
                    ¥{Number(detail.redeemSummary.totalAmount).toFixed(2)}
                  </Descriptions.Item>
                  <Descriptions.Item label="已核销">
                    <Typography.Text type="danger" strong>
                      ¥{Number(detail.redeemSummary.usedAmount).toFixed(2)}
                    </Typography.Text>
                    <Typography.Text type="secondary" style={{ marginLeft: 8 }}>
                      （{detail.redeemSummary.redeemCount} 笔核销单）
                    </Typography.Text>
                  </Descriptions.Item>
                  <Descriptions.Item label="剩余余额">
                    ¥{Number(detail.redeemSummary.balance).toFixed(2)}
                  </Descriptions.Item>
                  <Descriptions.Item label="核销单合计额">
                    ¥{Number(detail.redeemSummary.redeemRecordSum).toFixed(2)}
                    <Typography.Text type="secondary" style={{ marginLeft: 8 }}>
                      （本券分摊合计）
                    </Typography.Text>
                  </Descriptions.Item>
                </Descriptions>
                <Table
                  size="small"
                  rowKey="id"
                  pagination={false}
                  locale={{ emptyText: '暂无关联核销单' }}
                  dataSource={detail.redeemRecords ?? []}
                  columns={[
                    { title: '核销号', dataIndex: 'redeemNo', width: 160, ellipsis: true },
                    {
                      title: '角色',
                      dataIndex: 'role',
                      width: 70,
                      render: (v: string | undefined) =>
                        v === 'SECONDARY' ? <Tag color="orange">次券</Tag> : <Tag color="blue">主券</Tag>,
                    },
                    {
                      title: '门店',
                      dataIndex: ['store', 'name'],
                      ellipsis: true,
                      render: (v: string | undefined, row) =>
                        v ? `${v}${row.store?.cityName ? `（${row.store.cityName}）` : ''}` : '—',
                    },
                    {
                      title: '本券分摊',
                      dataIndex: 'couponAmount',
                      width: 95,
                      render: (v: number | undefined, row) =>
                        `¥${Number(v ?? row.amount).toFixed(2)}`,
                    },
                    {
                      title: '核销总额',
                      dataIndex: 'amount',
                      width: 90,
                      render: (v: number) => `¥${Number(v).toFixed(2)}`,
                    },
                    {
                      title: '结算额',
                      dataIndex: 'settleAmount',
                      width: 90,
                      render: (v: number) => `¥${Number(v).toFixed(2)}`,
                    },
                    {
                      title: '时间',
                      dataIndex: 'createdAt',
                      width: 150,
                      render: (v: string) => fmtTime(v),
                    },
                    {
                      title: '操作',
                      width: 70,
                      render: (_, row) => (
                        <Button type="link" size="small" onClick={() => void openRedeemDetail(row.id)}>
                          详情
                        </Button>
                      ),
                    },
                  ]}
                />
              </>
            ) : (
              <Typography.Text type="secondary">该订单尚未生成权益券，无核销记录</Typography.Text>
            )}

            <Descriptions column={1} bordered size="small" title="位置快照（方案C）" style={{ marginTop: 16 }}>
              <Descriptions.Item label="clientIp">{detail.clientIp || '—'}</Descriptions.Item>
              <Descriptions.Item label="IP解析">{[detail.ipProvince, detail.ipCity, detail.ipDistrict].filter(Boolean).join(' / ') || '—'}</Descriptions.Item>
              <Descriptions.Item label="GPS">{[detail.gpsProvince, detail.gpsCity, detail.gpsDistrict].filter(Boolean).join(' / ') || '—'}</Descriptions.Item>
              <Descriptions.Item label="坐标">
                {detail.gpsLatitude != null ? `${detail.gpsLatitude}, ${detail.gpsLongitude}` : '—'}
              </Descriptions.Item>
            </Descriptions>

            {detail.delivery && (
              <Descriptions
                column={1}
                bordered
                size="small"
                title={
                  <Space>
                    <span>配送</span>
                    <Button type="link" size="small" style={{ padding: 0 }} onClick={() => setTrackOpen(true)}>
                      查看路由
                    </Button>
                  </Space>
                }
                style={{ marginTop: 16 }}
              >
                <Descriptions.Item label="快递公司">
                  {detail.delivery.logisticsCompany ||
                    DELIVERY_PROVIDER_LABELS[detail.delivery.provider] ||
                    detail.delivery.provider}
                </Descriptions.Item>
                <Descriptions.Item label="运单号">{detail.delivery.trackingNo || '—'}</Descriptions.Item>
                <Descriptions.Item label="三方单号">{detail.delivery.providerOrderNo || '—'}</Descriptions.Item>
                {detail.delivery.manualQueryUrl && (
                  <Descriptions.Item label="查询链接">
                    <a href={detail.delivery.manualQueryUrl} target="_blank" rel="noreferrer">
                      打开物流查询
                    </a>
                  </Descriptions.Item>
                )}
              </Descriptions>
            )}

            {detail.statusLogs && detail.statusLogs.length > 0 && (
              <>
                <Typography.Title level={5} style={{ marginTop: 16 }}>状态流转</Typography.Title>
                <Table
                  size="small"
                  rowKey={(_, i) => String(i)}
                  pagination={false}
                  dataSource={detail.statusLogs}
                  columns={[
                    {
                      title: '从',
                      dataIndex: 'fromStatus',
                      width: 100,
                      render: (v) => (v ? ORDER_STATUS_LABELS[v] || v : '—'),
                    },
                    {
                      title: '到',
                      dataIndex: 'toStatus',
                      width: 100,
                      render: (v) => ORDER_STATUS_LABELS[v] || v,
                    },
                    {
                      title: '操作人',
                      dataIndex: 'operator',
                      width: 120,
                      render: (v) => ORDER_STATUS_OPERATOR_LABELS[v] || v || '—',
                    },
                    {
                      title: '备注',
                      dataIndex: 'remark',
                      ellipsis: true,
                      render: (v) => v || '—',
                    },
                    {
                      title: '时间',
                      dataIndex: 'createdAt',
                      width: 170,
                      render: (v) => new Date(v).toLocaleString('zh-CN'),
                    },
                  ]}
                />
              </>
            )}
          </>
        )}
      </Drawer>

      <Drawer
        title="核销单详情"
        width={520}
        open={redeemDrawerOpen}
        onClose={() => {
          setRedeemDrawerOpen(false);
          setRedeemDetail(null);
        }}
        destroyOnClose
      >
        {redeemDetailLoading ? (
          <Typography.Text type="secondary">加载中…</Typography.Text>
        ) : redeemDetail ? (
          <Descriptions column={1} bordered size="small">
            <Descriptions.Item label="核销号">{String(redeemDetail.redeemNo ?? '—')}</Descriptions.Item>
            <Descriptions.Item label="核销额">
              ¥{Number(redeemDetail.amount ?? 0).toFixed(2)}
            </Descriptions.Item>
            <Descriptions.Item label="结算额">
              ¥{Number(redeemDetail.settleAmount ?? 0).toFixed(2)}
            </Descriptions.Item>
            <Descriptions.Item label="时间">{fmtTime(String(redeemDetail.createdAt ?? ''))}</Descriptions.Item>
            <Descriptions.Item label="用户">
              {String((redeemDetail.user as { userNo?: string } | undefined)?.userNo ?? '—')}
              {(redeemDetail.user as { phone?: string | null } | undefined)?.phone
                ? ` / ${(redeemDetail.user as { phone?: string | null }).phone}`
                : ''}
            </Descriptions.Item>
            <Descriptions.Item label="门店">
              {String((redeemDetail.store as { name?: string } | undefined)?.name ?? '—')}
              {(redeemDetail.store as { cityName?: string } | undefined)?.cityName
                ? `（${(redeemDetail.store as { cityName?: string }).cityName}）`
                : ''}
            </Descriptions.Item>
            <Descriptions.Item label="门店地址">
              {String((redeemDetail.store as { address?: string } | undefined)?.address ?? '—')}
            </Descriptions.Item>
            <Descriptions.Item label="合伙人">
              {String(
                (redeemDetail.store as { partnerAccount?: { companyName?: string } } | undefined)
                  ?.partnerAccount?.companyName ?? '—',
              )}
            </Descriptions.Item>
            <Descriptions.Item label="权益券号">
              {String((redeemDetail.coupon as { couponNo?: string } | undefined)?.couponNo ?? '—')}
            </Descriptions.Item>
            <Descriptions.Item label="关联订单">
              {String(
                (redeemDetail.coupon as { order?: { orderNo?: string } } | undefined)?.order?.orderNo ??
                  '—',
              )}
            </Descriptions.Item>
            {Array.isArray(redeemDetail.allocations) &&
            (redeemDetail.allocations as unknown[]).length > 0 ? (
              <Descriptions.Item label="券分摊">
                {(
                  redeemDetail.allocations as Array<{
                    couponNo?: string;
                    orderNo?: string | null;
                    amount?: number;
                    sortOrder?: number;
                  }>
                )
                  .map((a, idx) => {
                    const role = idx === 0 ? '主' : '次';
                    return `${role} ${a.couponNo ?? '—'}¥${Number(a.amount ?? 0).toFixed(2)}${
                      a.orderNo ? `（订单 ${a.orderNo}）` : ''
                    }`;
                  })
                  .join('；')}
              </Descriptions.Item>
            ) : null}
            {redeemDetail.payout ? (
              <Descriptions.Item label="门店结算单">
                ¥{Number((redeemDetail.payout as { settleAmount?: number }).settleAmount ?? 0).toFixed(2)}
                {' / '}
                {String((redeemDetail.payout as { status?: string }).status ?? '—')}
              </Descriptions.Item>
            ) : null}
            {redeemDetail.rating ? (
              <Descriptions.Item label="评价">
                服务 {(redeemDetail.rating as { serviceScore?: number }).serviceScore ?? '—'} 分 / 环境{' '}
                {(redeemDetail.rating as { envScore?: number }).envScore ?? '—'} 分
              </Descriptions.Item>
            ) : null}
          </Descriptions>
        ) : null}
      </Drawer>

      <Modal
        title={shipTarget ? `配送发货 · ${shipTarget.orderNo}` : '配送发货'}
        open={shipModalOpen}
        onCancel={() => setShipModalOpen(false)}
        width={560}
        destroyOnClose={false}
        forceRender
        footer={
          <Space>
            <Button onClick={() => setShipModalOpen(false)}>取消</Button>
            {shipMode === 'WAREHOUSE' ? (
              <Button type="primary" loading={shipping} onClick={() => void submitShip()}>
                确认选仓发货
              </Button>
            ) : (
              <Button type="primary" loading={logisticsShipping} onClick={() => void submitLogisticsShip()}>
                提交快递单
              </Button>
            )}
          </Space>
        }
      >
        {shipTarget && (
          <>
            {shipTarget.fulfillmentHold ? (
              <Alert
                type="warning"
                showIcon
                style={{ marginBottom: 12 }}
                message="大单已拦截自动推小飞侠"
                description={
                  FULFILLMENT_HOLD_REASON_LABELS[shipTarget.fulfillmentHoldReason || ''] ||
                  '≥10箱订单需总部确认：可选仓推小飞侠，或改用快递自配送。'
                }
              />
            ) : null}
            <Descriptions size="small" column={1} style={{ marginBottom: 16 }}>
              <Descriptions.Item label="城市">{shipTarget.city?.name || '—'}</Descriptions.Item>
              <Descriptions.Item label="收货">
                {shipTarget.receiverName} {shipTarget.receiverPhone}
              </Descriptions.Item>
              <Descriptions.Item label="商品">
                {shipTarget.productName || '—'}
                {shipTarget.quantity != null ? ` ×${shipTarget.quantity}` : ''}
              </Descriptions.Item>
            </Descriptions>

            <Radio.Group
              value={shipMode}
              onChange={(e) => setShipMode(e.target.value as ShipMode)}
              optionType="button"
              buttonStyle="solid"
              style={{ marginBottom: 16 }}
              options={[
                { value: 'WAREHOUSE', label: '选仓配送' },
                { value: 'EXPRESS', label: '填写快递单号' },
              ]}
            />

            <div style={{ display: shipMode === 'WAREHOUSE' ? 'block' : 'none' }}>
              <Form form={shipForm} layout="vertical" size="small" preserve>
                <Form.Item
                  name="warehouseId"
                  label="选择仓库"
                  rules={[{ required: true, message: '请选择仓库' }]}
                >
                  <Select
                    showSearch
                    optionFilterProp="label"
                    placeholder={warehouses.length ? '选择仓库' : '暂无可用仓库'}
                    options={warehouses.map((w) => ({
                      value: w.id,
                      label: w.cityName ? `${w.cityName} · ${w.name}` : w.name,
                    }))}
                    onChange={(id) => void onWarehouseChange(id)}
                  />
                </Form.Item>
                <Form.Item name="provider" label="承运商" rules={[{ required: true }]} initialValue="XFX">
                  <Select options={[{ value: 'XFX', label: '小飞侠' }]} />
                </Form.Item>
                <Form.Item name="weight" label="重量(kg)" rules={[{ required: true }]}>
                  <InputNumber min={0.01} step={0.5} style={{ width: '100%' }} />
                </Form.Item>
                <Form.Item name="payMode" label="付费方式" rules={[{ required: true }]}>
                  <Select
                    options={[
                      { value: '1', label: '寄付' },
                      { value: '2', label: '到付' },
                    ]}
                  />
                </Form.Item>
                <Form.Item name="remark" label="备注">
                  <Input.TextArea rows={2} placeholder="可选" />
                </Form.Item>
                <Collapse
                  ghost
                  items={[{
                    key: 'from',
                    label: '寄件信息（默认仓库，可修改）',
                    children: (
                      <>
                        <Form.Item name="fromName" label="寄件人" rules={[{ required: true }]}>
                          <Input />
                        </Form.Item>
                        <Form.Item name="fromMobile" label="寄件手机" rules={[{ required: true }]}>
                          <Input />
                        </Form.Item>
                        <Form.Item name="fromAddress" label="寄件区域" rules={[{ required: true }]}>
                          <Input />
                        </Form.Item>
                        <Form.Item name="fromAddressDetail" label="寄件详细地址" rules={[{ required: true }]}>
                          <Input />
                        </Form.Item>
                        <Space>
                          <Form.Item name="fromLng" label="经度">
                            <InputNumber step={0.001} />
                          </Form.Item>
                          <Form.Item name="fromLat" label="纬度">
                            <InputNumber step={0.001} />
                          </Form.Item>
                        </Space>
                      </>
                    ),
                  }]}
                />
              </Form>
            </div>

            <div style={{ display: shipMode === 'EXPRESS' ? 'block' : 'none' }}>
              <Form form={logisticsForm} layout="vertical" size="small" preserve>
                <Typography.Paragraph type="secondary" style={{ fontSize: 12, marginTop: 0 }}>
                  填写快递公司与运单号即可完成发货
                </Typography.Paragraph>
                <Form.Item
                  name="logisticsCompany"
                  label="快递公司"
                  rules={[{ required: true, message: '请填写快递公司' }]}
                >
                  <Input placeholder="如 顺丰速运、京东物流" />
                </Form.Item>
                <Form.Item
                  name="trackingNo"
                  label="运单号"
                  rules={[{ required: true, message: '请填写运单号' }]}
                >
                  <Input placeholder="请输入运单号" />
                </Form.Item>
                <Form.Item name="manualQueryUrl" label="物流查询链接（可选）">
                  <Input placeholder="https://..." />
                </Form.Item>
              </Form>
            </div>
          </>
        )}
      </Modal>

      <Modal
        title={`确认批量删除（${selectedOrders.length} 笔）`}
        open={batchDeleteOpen}
        okText="确认删除"
        okButtonProps={{ danger: true, loading: batchDeleting }}
        onOk={() => void confirmBatchDelete()}
        onCancel={() => setBatchDeleteOpen(false)}
        width={720}
        destroyOnClose
      >
        <Alert
          type="error"
          showIcon
          style={{ marginBottom: 16 }}
          message="此操作不可恢复"
          description="将删除所选订单及其配送单、权益券、核销记录等关联业务数据。订单状态流转等业务日志将保留。"
        />
        <Table
          size="small"
          rowKey="id"
          pagination={false}
          scroll={{ x: 600, y: 280 }}
          dataSource={selectedOrders}
          columns={[
            { title: '订单号', dataIndex: 'orderNo', width: 170 },
            {
              title: '城市',
              width: 80,
              render: (_, row) => row.city?.name || '—',
            },
            {
              title: '商品',
              width: 160,
              ellipsis: true,
              render: (_, row) =>
                row.productName
                  ? `${row.productName}${row.quantity != null ? ` ×${row.quantity}` : ''}`
                  : '—',
            },
            {
              title: '状态',
              dataIndex: 'status',
              width: 100,
              render: (s) => (
                <Tag color={ORDER_STATUS_COLORS[s] || 'default'}>{ORDER_STATUS_LABELS[s] || s}</Tag>
              ),
            },
            { title: '实付', dataIndex: 'payAmount', width: 90, render: (v) => `¥${v}` },
            { title: '收货人', dataIndex: 'receiverName', width: 90 },
            { title: '下单时间', dataIndex: 'createdAt', width: 160, render: fmtTime },
          ]}
        />
      </Modal>

      <ProxyOrderModal
        open={proxyOpen}
        onClose={() => setProxyOpen(false)}
        onSuccess={(order) => {
          setProxyOpen(false);
          void load();
          void openDetail(order.id);
        }}
      />

      <OrderTrackDrawer
        open={trackOpen}
        orderId={detail?.id ?? null}
        orderNo={detail?.orderNo}
        orderStatus={detail?.status}
        onClose={() => setTrackOpen(false)}
      />
    </div>
  );
}
