import { useCallback, useEffect, useMemo, useState } from 'react'
import { useLocation } from 'react-router-dom'
import {
  Button,
  Card,
  Col,
  Descriptions,
  Form,
  Input,
  InputNumber,
  Modal,
  Popconfirm,
  Row,
  Select,
  Space,
  Table,
  Tabs,
  Tag,
  Typography,
  message,
} from 'antd'
import {
  ApiOutlined,
  ClockCircleOutlined,
  CopyOutlined,
  DollarOutlined,
  LinkOutlined,
  PlusOutlined,
  ReloadOutlined,
  WalletOutlined,
} from '@ant-design/icons'
import type { ColumnsType } from 'antd/es/table'
import { merchantApi } from '../api'
import { formatDateTime } from '../utils/time'
import { PageHeader } from '../components/PageHeader'
import type {
  ApiClient,
  ApiCredential,
  CallbackCredential,
  CallbackSubscription,
  CreateTestOrderResult,
  FulfillmentOrder,
  Merchant,
  MerchantMember,
  MerchantProduct,
  PageResult,
  WalletAccount,
  WalletLedgerEntry,
} from '../types'

const orderStatusMap: Record<string, { color: string; text: string }> = {
  paid: { color: 'blue', text: '待发货' },
  delivering: { color: 'cyan', text: '发货中' },
  delivered: { color: 'green', text: '已交付' },
  ship_failed: { color: 'red', text: '发货失败' },
  cancelled: { color: 'default', text: '已取消' },
}

const memberRoleOptions = [
  { value: 'owner', label: '负责人' },
  { value: 'operator', label: '运营' },
  { value: 'finance', label: '财务' },
  { value: 'viewer', label: '只读' },
]

const apiClientMax = 5

const scopeOptions = [
  { value: 'products:read', label: '商品读取' },
  { value: 'orders:read', label: '订单读取' },
  { value: 'orders:write', label: '订单写入' },
  { value: 'shipping:read', label: '发货读取' },
  { value: 'wallet:read', label: '钱包读取' },
]

const eventOptions = [
  { value: 'order.created', label: '订单创建' },
  { value: 'order.shipping.updated', label: '发货更新' },
  { value: 'order.cancelled', label: '订单取消' },
]

const testOrderStatusOptions = [
  { value: 'paid', label: '已支付，可发货' },
  { value: 'ship_failed', label: '发货失败，可重试' },
  { value: 'cancelled', label: '已取消，不可发货' },
]

type MerchantCenterTab = 'products' | 'orders' | 'wallet' | 'api' | 'callbacks' | 'members'

interface MerchantCenterProps {
  fixedTab?: MerchantCenterTab
  title?: string
}

export default function MerchantCenter({ fixedTab, title = '商户中心' }: MerchantCenterProps = {}) {
  const location = useLocation()
  const routeTab = useMemo(() => fixedTab ?? tabFromSearch(location.search), [fixedTab, location.search])
  const [merchant, setMerchant] = useState<Merchant | null>(null)
  const [merchantRole, setMerchantRole] = useState<MerchantMember['role']>()
  const [activeTab, setActiveTab] = useState<MerchantCenterTab>(routeTab ?? 'products')
  const [products, setProducts] = useState<PageResult<MerchantProduct>>({ list: [], total: 0, page: 1, size: 10 })
  const [orders, setOrders] = useState<PageResult<FulfillmentOrder>>({ list: [], total: 0, page: 1, size: 10 })
  const [ledger, setLedger] = useState<PageResult<WalletLedgerEntry>>({ list: [], total: 0, page: 1, size: 10 })
  const [wallet, setWallet] = useState<WalletAccount | null>(null)
  const [apiClients, setApiClients] = useState<ApiClient[]>([])
  const [callback, setCallback] = useState<CallbackSubscription | null>(null)
  const [members, setMembers] = useState<MerchantMember[]>([])
  const [loading, setLoading] = useState(false)
  const [productOpen, setProductOpen] = useState(false)
  const [editingProduct, setEditingProduct] = useState<MerchantProduct | null>(null)
  const [apiClientOpen, setApiClientOpen] = useState(false)
  const [apiCredential, setApiCredential] = useState<ApiCredential | null>(null)
  const [callbackCredential, setCallbackCredential] = useState<CallbackCredential | null>(null)
  const [memberOpen, setMemberOpen] = useState(false)
  const [testOrderOpen, setTestOrderOpen] = useState(false)
  const [testOrderProducts, setTestOrderProducts] = useState<MerchantProduct[]>([])
  const [testOrderProductsLoading, setTestOrderProductsLoading] = useState(false)
  const [testOrderResult, setTestOrderResult] = useState<CreateTestOrderResult | null>(null)
  const [productForm] = Form.useForm()
  const [walletFilterForm] = Form.useForm()
  const [apiClientForm] = Form.useForm()
  const [callbackForm] = Form.useForm()
  const [memberForm] = Form.useForm()
  const [testOrderForm] = Form.useForm()

  const canManage = merchantRole === 'owner' || merchantRole === 'operator'
  const canFinance = merchantRole === 'owner' || merchantRole === 'finance'
  const enabledFeatures = useMemo(() => new Set(featuresToList(merchant?.features)), [merchant?.features])
  const hasFeature = useCallback((feature: string) => !merchant || enabledFeatures.has(feature), [enabledFeatures, merchant])
  const testOrderProductOptions = useMemo(() => testOrderProducts.map((item) => ({
    value: item.sku,
    label: productOptionLabel(item),
  })), [testOrderProducts])

  const copyDeliveryLink = useCallback((orderNo: string) => {
    merchantApi.getDeliveryLink(orderNo)
      .then((data) => navigator.clipboard.writeText(data.delivery_url).then(() => message.success('发货链接已复制')))
      .catch((e) => message.error(e instanceof Error ? e.message : '复制失败'))
  }, [])

  const openDeliveryLink = useCallback((orderNo: string) => {
    merchantApi.getDeliveryLink(orderNo)
      .then((data) => window.open(data.delivery_url, '_blank', 'noopener,noreferrer'))
      .catch((e) => message.error(e instanceof Error ? e.message : '打开失败'))
  }, [])

  const patchDeliveryLinkState = useCallback((orderNo: string, patch: Partial<FulfillmentOrder>) => {
    setOrders((prev) => ({
      ...prev,
      list: prev.list.map((item) => item.order_no === orderNo ? { ...item, ...patch } : item),
    }))
    setTestOrderResult((prev) => prev?.order.order_no === orderNo ? {
      ...prev,
      order: { ...prev.order, ...patch },
    } : prev)
  }, [])

  const loadCurrent = useCallback(async () => {
    const data = await merchantApi.current()
    setMerchant(data.merchant)
    setMerchantRole(data.role)
    return data
  }, [])

  const loadProducts = useCallback(async (page = products.page, size = products.size) => {
    const data = await merchantApi.products({ page, size })
    setProducts(data)
  }, [products.page, products.size])

  const loadOrders = useCallback(async (page = orders.page, size = orders.size) => {
    const data = await merchantApi.orders({ page, size })
    setOrders(data)
  }, [orders.page, orders.size])

  const revokeDeliveryLink = useCallback((orderNo: string) => {
    merchantApi.revokeDeliveryLink(orderNo)
      .then(() => {
        const revokedAt = new Date().toISOString()
        message.success('发货链接已作废')
        patchDeliveryLinkState(orderNo, { delivery_link_revoked_at: revokedAt })
      })
      .catch((e) => message.error(e instanceof Error ? e.message : '作废失败'))
  }, [patchDeliveryLinkState])

  const restoreDeliveryLink = useCallback((orderNo: string) => {
    merchantApi.restoreDeliveryLink(orderNo)
      .then((data) => {
        message.success('发货链接已恢复')
        patchDeliveryLinkState(orderNo, {
          delivery_link_expires_at: data.expires_at,
          delivery_link_revoked_at: null,
        })
      })
      .catch((e) => message.error(e instanceof Error ? e.message : '恢复失败'))
  }, [patchDeliveryLinkState])

  const loadWallet = useCallback(async (
    page = ledger.page,
    size = ledger.size,
    role = merchantRole,
    filters?: { reference_no?: string; type?: string },
  ) => {
    const walletData = await merchantApi.wallet()
    setWallet(walletData)
    if (role === 'owner' || role === 'finance') {
      const ledgerData = await merchantApi.ledger({ page, size, ...filters })
      setLedger(ledgerData)
    } else {
      setLedger({ list: [], total: 0, page, size })
    }
  }, [ledger.page, ledger.size, merchantRole])

  const loadAPIClients = useCallback(async () => {
    const clientData = await merchantApi.apiClients()
    setApiClients(clientData || [])
  }, [])

  const loadCallbacks = useCallback(async (role = merchantRole) => {
    if (role !== 'owner' && role !== 'operator') {
      setCallback(null)
      callbackForm.resetFields()
      return
    }
    const callbackData = await merchantApi.callbacks()
    setCallback(callbackData || null)
    callbackForm.setFieldsValue(callbackData ? {
      url: callbackData.url,
      events: eventsToValue(callbackData.events),
      status: callbackData.status,
    } : defaultCallbackFormValues())
  }, [callbackForm, merchantRole])

  const loadMembers = useCallback(async (role = merchantRole) => {
    if (role !== 'owner' && role !== 'operator') {
      setMembers([])
      return
    }
    const memberData = await merchantApi.members()
    setMembers(memberData || [])
  }, [merchantRole])

  const loadActiveTab = useCallback(async (role = merchantRole, tab = activeTab) => {
    switch (tab) {
      case 'products':
        await loadProducts()
        return
      case 'orders':
        await loadOrders()
        return
      case 'wallet':
        await loadWallet(undefined, undefined, role)
        return
      case 'api':
        await loadAPIClients()
        return
      case 'callbacks':
        await loadCallbacks(role)
        return
      case 'members':
        await loadMembers(role)
        return
    }
  }, [activeTab, loadAPIClients, loadCallbacks, loadMembers, loadOrders, loadProducts, loadWallet, merchantRole])

  const loadAll = useCallback(async () => {
    setLoading(true)
    try {
      const current = await loadCurrent()
      const nextTab = fixedTab ?? resolveEnabledTab(routeTab ?? activeTab, current.merchant.features)
      if (!fixedTab && nextTab !== activeTab) {
        setActiveTab(nextTab)
      }
      await loadActiveTab(current.role, nextTab)
    } catch (e) {
      message.error(e instanceof Error ? e.message : '加载失败')
    } finally {
      setLoading(false)
    }
  }, [activeTab, fixedTab, loadActiveTab, loadCurrent, routeTab])

  useEffect(() => {
    loadAll()
  }, [loadAll])

  useEffect(() => {
    if (routeTab && activeTab !== routeTab) {
      setActiveTab(routeTab)
    }
  }, [activeTab, routeTab])

  const openProductCreate = () => {
    setEditingProduct(null)
    productForm.resetFields()
    productForm.setFieldsValue({
      currency: 'POINT',
      stock: -1,
      status: 'active',
      price_amount: 0,
      cost_amount: 0,
    })
    setProductOpen(true)
  }

  const openProductEdit = (record: MerchantProduct) => {
    setEditingProduct(record)
    productForm.setFieldsValue({
      ...record,
    })
    setProductOpen(true)
  }

  const submitProduct = async () => {
    const values = await productForm.validateFields()
    try {
      const payload = {
        ...values,
      }
      if (editingProduct) {
        await merchantApi.updateProduct(editingProduct.id, payload)
        message.success('商品已更新')
      } else {
        await merchantApi.createProduct(payload)
        message.success('商品已创建')
      }
      setProductOpen(false)
      loadProducts()
    } catch (e) {
      message.error(e instanceof Error ? e.message : '保存失败')
    }
  }

  const handleWalletFilter = async () => {
    const values = await walletFilterForm.validateFields()
    loadWallet(1, ledger.size, merchantRole, {
      reference_no: values.reference_no || undefined,
      type: values.type || undefined,
    })
  }

  const handleWalletFilterReset = () => {
    walletFilterForm.resetFields()
    loadWallet(1, ledger.size, merchantRole, {})
  }

  const openTestOrderCreate = () => {
    testOrderForm.resetFields()
    testOrderForm.setFieldsValue({
      buyer_reference: '测试买家',
      note: '联调测试订单',
      order_status: 'paid',
    })
    setTestOrderOpen(true)
    setTestOrderProductsLoading(true)
    merchantApi.products({ page: 1, size: 100 })
      .then((data) => {
        const activeProducts = (data.list || []).filter((item) => item.status === 'active')
        setTestOrderProducts(activeProducts)
        if (activeProducts.length > 0) {
          testOrderForm.setFieldsValue({ sku: activeProducts[0].sku })
        } else {
          message.warning('没有可用商品')
        }
      })
      .catch((e) => {
        message.error(e instanceof Error ? e.message : '商品加载失败')
      })
      .finally(() => setTestOrderProductsLoading(false))
  }

  const submitTestOrder = async () => {
    const values = await testOrderForm.validateFields()
    try {
      const result = await merchantApi.createTestOrder({
        sku: values.sku,
        buyer_reference: values.buyer_reference,
        note: values.note,
        order_status: values.order_status,
      })
      setTestOrderOpen(false)
      setTestOrderResult(result)
      message.success('测试订单已创建')
      loadOrders()
    } catch (e) {
      message.error(e instanceof Error ? e.message : '创建失败')
    }
  }

  const submitAPIClient = async () => {
    const values = await apiClientForm.validateFields()
    try {
      const credential = await merchantApi.createApiClient({
        name: values.name,
        scopes: (values.scopes || []).join(','),
        signature_version: values.signature_version,
        expires_at: values.expires_at,
      })
      setApiCredential(credential)
      setApiClientOpen(false)
      message.success('API 密钥已创建')
      loadAPIClients()
    } catch (e) {
      message.error(e instanceof Error ? e.message : '创建失败')
    }
  }

  const submitCallback = async () => {
    const values = await callbackForm.validateFields()
    try {
      const credential = await merchantApi.saveCallback({
        url: values.url,
        events: (values.events || []).join(','),
        status: values.status,
      })
      setCallback(credential.subscription)
      if (credential.secret) {
        setCallbackCredential(credential)
      }
      message.success('回调配置已保存')
    } catch (e) {
      message.error(e instanceof Error ? e.message : '保存失败')
    }
  }

  const rotateCallbackSecret = async () => {
    const values = await callbackForm.validateFields()
    try {
      const credential = await merchantApi.saveCallback({
        url: values.url,
        events: (values.events || []).join(','),
        status: values.status,
        rotate_secret: true,
      })
      setCallback(credential.subscription)
      if (credential.secret) {
        setCallbackCredential(credential)
      }
      message.success('回调密钥已重置，旧密钥立即失效')
    } catch (e) {
      message.error(e instanceof Error ? e.message : '重置失败')
    }
  }

  const submitMember = async () => {
    const values = await memberForm.validateFields()
    try {
      await merchantApi.addMember({
        user_id: values.user_id,
        role: values.role,
        is_default: values.is_default,
      })
      setMemberOpen(false)
      message.success('成员已添加')
      loadMembers()
    } catch (e) {
      message.error(e instanceof Error ? e.message : '添加失败')
    }
  }

  const toggleAPIClient = async (record: ApiClient) => {
    try {
      await merchantApi.updateApiClientStatus(record.id, record.status === 'active' ? 'disabled' : 'active')
      message.success('状态已更新')
      loadAPIClients()
    } catch (e) {
      message.error(e instanceof Error ? e.message : '更新失败')
    }
  }

  const deleteAPIClient = async (record: ApiClient) => {
    try {
      await merchantApi.deleteApiClient(record.id)
      message.success('密钥已删除')
      loadAPIClients()
    } catch (e) {
      message.error(e instanceof Error ? e.message : '删除失败')
    }
  }

  const productColumns: ColumnsType<MerchantProduct> = [
    {
      title: '商户 SKU',
      dataIndex: 'sku',
      width: 180,
      ellipsis: true,
      render: (v) => <Typography.Text code copyable={{ tooltips: false }} style={{ maxWidth: '100%' }}>{v}</Typography.Text>,
    },
    {
      title: '商品名称',
      dataIndex: 'display_name',
      width: 220,
      ellipsis: true,
      render: (_, r) => (
        <div>
          <div style={{ fontWeight: 600, color: '#0f172a' }}>{r.display_name || r.product?.name || '-'}</div>
          {r.product?.category && (
            <span style={{ fontSize: 11.5, color: '#64748b' }}>{r.product.category}</span>
          )}
        </div>
      ),
    },
    {
      title: '目录编码',
      dataIndex: ['product', 'code'],
      width: 150,
      ellipsis: true,
      render: (_, r) => r.product?.code ? <Typography.Text code>{r.product.code}</Typography.Text> : '-',
    },
    {
      title: '对外售价',
      dataIndex: 'price_amount',
      width: 120,
      render: (v) => <span style={{ fontWeight: 700, color: '#2563eb' }}>{money(v)}</span>,
    },
    {
      title: '成本价',
      dataIndex: 'cost_amount',
      width: 120,
      render: (v) => <span style={{ color: '#64748b' }}>{money(v)}</span>,
    },
    {
      title: '当前库存',
      dataIndex: 'stock',
      width: 110,
      render: (v) => (v < 0 ? <Tag color="blue">无限库存</Tag> : v === 0 ? <Tag color="red">已缺货</Tag> : `${v} 件`),
    },
    {
      title: '状态',
      dataIndex: 'status',
      width: 100,
      render: productStatusTag,
    },
    {
      title: '操作',
      key: 'action',
      width: 90,
      fixed: 'right',
      render: (_, record) => canManage ? (
        <Button type="link" size="small" onClick={() => openProductEdit(record)}>编辑</Button>
      ) : '-',
    },
  ]

  const orderColumns: ColumnsType<FulfillmentOrder> = [
    {
      title: '平台订单号',
      dataIndex: 'order_no',
      width: 190,
      ellipsis: true,
      render: (v) => <Typography.Text copyable ellipsis style={{ maxWidth: '100%' }}>{v}</Typography.Text>,
    },
    { title: '商户单号', dataIndex: 'client_order_no', width: 140, ellipsis: true },
    {
      title: 'SKU',
      dataIndex: 'product_sku',
      width: 130,
      ellipsis: true,
      render: (v) => <Typography.Text code ellipsis style={{ maxWidth: '100%' }}>{v}</Typography.Text>,
    },
    { title: '商品', dataIndex: 'product_name', width: 220, ellipsis: true },
    { title: '基础金额', dataIndex: 'base_amount', width: 88, render: money },
    { title: '手续费', dataIndex: 'service_fee_amount', width: 82, render: money },
    { title: '扣款合计', dataIndex: 'amount', width: 88, render: money },
    { title: '状态', dataIndex: 'order_status', width: 92, render: orderStatusTag },
    {
      title: '链接有效期',
      dataIndex: 'delivery_link_expires_at',
      width: 140,
      render: (_, record) => record.delivery_link_revoked_at ? <Tag color="red">已作废</Tag> : formatDateTime(record.delivery_link_expires_at),
    },
    { title: '时间', dataIndex: 'created_at', width: 150, render: formatDateTime },
    {
      title: '发货链接',
      key: 'delivery_link',
      width: 150,
      render: (_, record) => record.delivery_link_revoked_at ? (
        <Button type="link" size="small" onClick={() => restoreDeliveryLink(record.order_no)}>取消作废</Button>
      ) : (
        <Space size={4} wrap>
          <Button type="link" size="small" onClick={() => copyDeliveryLink(record.order_no)}>复制</Button>
          <Button type="link" size="small" onClick={() => openDeliveryLink(record.order_no)}>打开</Button>
          <Button type="link" danger size="small" onClick={() => revokeDeliveryLink(record.order_no)}>作废</Button>
        </Space>
      ),
    },
  ]

  const ledgerColumns: ColumnsType<WalletLedgerEntry> = [
    { title: '流水号', dataIndex: 'entry_no', width: 260, render: (v) => <Typography.Text code copyable={{ tooltips: false }}>{v}</Typography.Text> },
    { title: '类型', dataIndex: 'type', width: 90, render: ledgerTypeTag },
    { title: '变动积分', dataIndex: 'amount', width: 130, render: moneyWithSign },
    { title: '结余积分', dataIndex: 'balance_after', width: 130, render: (v) => <span style={{ fontWeight: 600, color: '#0f172a' }}>{money(v)}</span> },
    { title: '关联单号', dataIndex: 'reference_no', width: 200, ellipsis: true, render: (v) => v ? <Typography.Text code ellipsis style={{ maxWidth: '100%' }}>{v}</Typography.Text> : '-' },
    { title: '备注说明', dataIndex: 'note', width: 220, ellipsis: { showTitle: false }, render: (v) => <Typography.Text ellipsis title={v}>{v || '-'}</Typography.Text> },
    { title: '变动时间', dataIndex: 'created_at', width: 170, render: formatDateTime },
  ]

  const apiClientColumns: ColumnsType<ApiClient> = [
    { title: '名称', dataIndex: 'name', width: 140, ellipsis: true },
    { title: 'App Key', dataIndex: 'app_key', width: 230, render: (v) => <Typography.Text code copyable>{v}</Typography.Text> },
    { title: '签名', dataIndex: 'signature_version', width: 80, render: (v) => <Tag>{v}</Tag> },
    { title: '权限', dataIndex: 'scopes', width: 250, render: scopesTag },
    { title: '状态', dataIndex: 'status', width: 80, render: activeStatusTag },
    { title: '最后使用', dataIndex: 'last_used_at', width: 170, render: formatDateTime },
    {
      title: '操作',
      key: 'action',
      width: 150,
      render: (_, record) => canManage ? (
        <Space size={0}>
          <Button type="link" size="small" onClick={() => toggleAPIClient(record)}>
            {record.status === 'active' ? '禁用' : '启用'}
          </Button>
          <Popconfirm
            title="删除该密钥？"
            description={record.status === 'active' ? '请先停用该密钥再删除' : '删除后不可恢复，使用该密钥的对接方将无法调用开放接口。'}
            okText="删除"
            okButtonProps={{ danger: true }}
            onConfirm={() => deleteAPIClient(record)}
          >
            <Button type="link" size="small" danger disabled={record.status === 'active'}>
              删除
            </Button>
          </Popconfirm>
        </Space>
      ) : '-',
    },
  ]

  const memberColumns: ColumnsType<MerchantMember> = [
    { title: '用户', dataIndex: ['user', 'username'], render: (_, r) => r.user?.username || `#${r.user_id}` },
    { title: '昵称', dataIndex: ['user', 'nickname'], render: (_, r) => r.user?.nickname || '-' },
    { title: '角色', dataIndex: 'role', width: 120, render: memberRoleTag },
    { title: '默认', dataIndex: 'is_default', width: 80, render: (v) => (v ? <Tag color="blue">默认</Tag> : '-') },
    { title: '状态', dataIndex: 'status', width: 90, render: (v) => (v === 1 ? <Tag color="green">启用</Tag> : <Tag>禁用</Tag>) },
  ]

  const productContent = (
    <Space direction="vertical" style={{ width: '100%' }} size="middle">
      <Card size="small" style={{ background: '#f8fafc', border: '1px solid #e2e8f0', borderRadius: 8 }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div>
            <span style={{ fontWeight: 600, color: '#0f172a', marginRight: 8 }}>商品上架与定额售价管理</span>
            <Typography.Text type="secondary" style={{ fontSize: 13 }}>
              通用皮肤与游戏道具通过唯一的商户 SKU 进行对外销售与统一发货。
            </Typography.Text>
          </div>
          {canManage && (
            <Button type="primary" icon={<PlusOutlined />} onClick={openProductCreate}>
              新增商品
            </Button>
          )}
        </div>
      </Card>
      <Table
        rowKey="id"
        loading={loading}
        columns={productColumns}
        dataSource={products.list}
        scroll={{ x: 1100 }}
        pagination={pageConfig(products, loadProducts)}
      />
    </Space>
  )

  const orderContent = (
    <Space direction="vertical" style={{ width: '100%' }} size="middle">
      <Space style={{ width: '100%', justifyContent: 'space-between' }}>
        <Typography.Text type="secondary">发货链接由后端生成并带签名，用户只填写游戏 UID。</Typography.Text>
        {canManage && (
          <Space>
            <Button type="primary" icon={<PlusOutlined />} onClick={openTestOrderCreate}>
              创建测试订单
            </Button>
          </Space>
        )}
      </Space>
      <Table
        rowKey="id"
        loading={loading}
        columns={orderColumns}
        dataSource={orders.list}
        tableLayout="fixed"
        scroll={{ x: 1660 }}
        pagination={pageConfig(orders, loadOrders)}
      />
    </Space>
  )

  const walletContent = (
    <Space direction="vertical" style={{ width: '100%' }} size="middle">
      <Row gutter={[16, 16]}>
        <Col xs={24} sm={8}>
          <div className="metric-card-box">
            <div className="metric-card-header">
              <span className="metric-card-title">可用余额</span>
              <div className="metric-card-icon metric-card-icon--emerald"><WalletOutlined /></div>
            </div>
            <div className="metric-card-value" style={{ color: '#16a34a' }}>
              {(wallet?.available_balance ?? 0).toLocaleString('zh-CN')}
              <span style={{ fontSize: 13, fontWeight: 500, marginLeft: 4, color: '#64748b' }}>积分</span>
            </div>
            <div className="metric-card-footer">
              <span>充值/调账</span>
              <span style={{ fontWeight: 600, color: '#64748b' }}>仅平台管理员可操作</span>
            </div>
          </div>
        </Col>
        <Col xs={24} sm={8}>
          <div className="metric-card-box">
            <div className="metric-card-header">
              <span className="metric-card-title">冻结余额</span>
              <div className="metric-card-icon"><ClockCircleOutlined /></div>
            </div>
            <div className="metric-card-value">
              {(wallet?.frozen_balance ?? 0).toLocaleString('zh-CN')}
              <span style={{ fontSize: 13, fontWeight: 500, marginLeft: 4, color: '#64748b' }}>积分</span>
            </div>
            <div className="metric-card-footer">
              <span>提现/发货预扣</span>
              <span style={{ fontWeight: 600, color: '#0f172a' }}>0 笔预扣</span>
            </div>
          </div>
        </Col>
        <Col xs={24} sm={8}>
          <div className="metric-card-box">
            <div className="metric-card-header">
              <span className="metric-card-title">结算币种与状态</span>
              <div className="metric-card-icon metric-card-icon--purple"><DollarOutlined /></div>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4 }}>
              <Tag color="blue" style={{ fontSize: 13, padding: '2px 8px', borderRadius: 4, margin: 0, fontWeight: 600 }}>
                {wallet?.currency || 'POINT'}
              </Tag>
              <span className="status-tag status-tag--green">
                <span className="status-dot"></span>
                账户正常
              </span>
            </div>
            <div className="metric-card-footer">
              <span>计费方式</span>
              <span style={{ fontWeight: 600, color: '#0f172a' }}>自动按单扣减</span>
            </div>
          </div>
        </Col>
      </Row>

      {canFinance && (
        <Card size="small" style={{ background: '#f8fafc', border: '1px solid #e2e8f0', borderRadius: 8 }}>
          <Form form={walletFilterForm} layout="inline" onFinish={handleWalletFilter}>
            <Form.Item name="reference_no" label="关联单号">
              <Input placeholder="店铺单号 / 充值单号" allowClear style={{ width: 220, borderRadius: 6 }} />
            </Form.Item>
            <Form.Item name="type" label="收支类型">
              <Select placeholder="全部类型" allowClear style={{ width: 140 }}>
                <Select.Option value="credit">入账 (Credit)</Select.Option>
                <Select.Option value="debit">扣款 (Debit)</Select.Option>
                <Select.Option value="refund">退款 (Refund)</Select.Option>
                <Select.Option value="adjust">调账 (Adjust)</Select.Option>
              </Select>
            </Form.Item>
            <Form.Item>
              <Space>
                <Button onClick={handleWalletFilterReset}>重置</Button>
                <Button type="primary" htmlType="submit">查询</Button>
              </Space>
            </Form.Item>
          </Form>
        </Card>
      )}
      {canFinance ? (
        <Table
          rowKey="id"
          loading={loading}
          columns={ledgerColumns}
          dataSource={ledger.list}
          tableLayout="fixed"
          scroll={{ x: 1300 }}
          pagination={pageConfig(ledger, (page, size) => {
            const values = walletFilterForm.getFieldsValue()
            loadWallet(page, size, merchantRole, {
              reference_no: values.reference_no || undefined,
              type: values.type || undefined,
            })
          })}
        />
      ) : (
        <Typography.Text type="secondary">当前角色可查看余额，钱包流水仅财务或负责人可见。</Typography.Text>
      )}
    </Space>
  )

  const apiKeyContent = (
    <Space direction="vertical" style={{ width: '100%' }} size="middle">
      <Space style={{ width: '100%', justifyContent: 'space-between' }}>
        <Typography.Text type="secondary">用于开放 API 调用鉴权。新 Secret 只在创建后显示一次，请及时保存。每个商户最多 {apiClientMax} 个。</Typography.Text>
        {canManage && <Button type="primary" icon={<ApiOutlined />} disabled={apiClients.length >= apiClientMax} onClick={() => {
          apiClientForm.resetFields()
          apiClientForm.setFieldsValue({ signature_version: 'v1', scopes: ['products:read', 'orders:read', 'orders:write'] })
          setApiClientOpen(true)
        }}>新增密钥（{apiClients.length}/{apiClientMax}）</Button>}
      </Space>
      <Table rowKey="id" loading={loading} columns={apiClientColumns} dataSource={apiClients} tableLayout="fixed" scroll={{ x: 1050 }} />
    </Space>
  )

  const callbackContent = (
    <Space direction="vertical" style={{ width: '100%' }} size="middle">
      <Typography.Text type="secondary">
        回调事件通过 outbox 持久化推送，失败按固定间隔退避重试（最多 16 次）后标记失败。每个商户只保留一份回调配置。
      </Typography.Text>
      <Card size="small" loading={loading}>
        <Form
          form={callbackForm}
          layout="vertical"
          disabled={!canManage}
          onFinish={submitCallback}
          initialValues={defaultCallbackFormValues()}
        >
          <Form.Item name="url" label="回调 URL" rules={[{ required: true, message: '请填写回调 URL' }]}>
            <Input placeholder="https://example.com/callback" />
          </Form.Item>
          <Form.Item name="events" label="事件" rules={[{ required: true, message: '请选择回调事件' }]}>
            <Select mode="multiple" options={eventOptions} />
          </Form.Item>
          <Form.Item name="status" label="状态" rules={[{ required: true }]}>
            <Select options={[{ value: 'active', label: '启用' }, { value: 'disabled', label: '禁用' }]} />
          </Form.Item>
          <Space style={{ width: '100%', justifyContent: 'space-between' }}>
            <Typography.Text type="secondary">
              {callback?.updated_at ? `上次保存：${formatDateTime(callback.updated_at)}` : '尚未保存回调配置'}
            </Typography.Text>
            <Space>
              {canManage && (
                <Popconfirm
                  title="重置回调密钥？"
                  description="重置后旧密钥立即失效，平台将用新密钥签名推送，新密钥仅展示一次。"
                  okText="重置"
                  okButtonProps={{ danger: true }}
                  onConfirm={rotateCallbackSecret}
                >
                  <Button>重置密钥</Button>
                </Popconfirm>
              )}
              {canManage && <Button type="primary" htmlType="submit">保存配置</Button>}
            </Space>
          </Space>
        </Form>
      </Card>
    </Space>
  )

  const memberContent = (
    <Space direction="vertical" style={{ width: '100%' }} size="middle">
      <Space style={{ width: '100%', justifyContent: 'space-between' }}>
        <Typography.Text type="secondary">成员角色独立于平台账号角色。</Typography.Text>
        {merchantRole === 'owner' && <Button type="primary" icon={<PlusOutlined />} onClick={() => {
          memberForm.resetFields()
          memberForm.setFieldsValue({ role: 'operator' })
          setMemberOpen(true)
        }}>添加成员</Button>}
      </Space>
      <Table rowKey="id" loading={loading} columns={memberColumns} dataSource={members} tableLayout="fixed" />
    </Space>
  )

  const tabItems = [
    { key: 'products', label: '商品', disabled: !hasFeature('products'), children: productContent },
    { key: 'orders', label: '发货订单', disabled: !hasFeature('orders'), children: orderContent },
    { key: 'wallet', label: '钱包', disabled: !hasFeature('wallet'), children: walletContent },
    { key: 'api', label: 'API 密钥', disabled: !hasFeature('api'), children: apiKeyContent },
    { key: 'callbacks', label: '回调', disabled: !hasFeature('callbacks'), children: callbackContent },
    { key: 'members', label: '成员', children: memberContent },
  ]
  const fixedTabContent = tabItems.find((item) => item.key === fixedTab)?.children

  return (
    <div>
      <PageHeader
        title={title}
        subtitle={merchant ? `${merchant.name} (${merchant.code}) · 当前身份: ${merchantRole ? roleText(merchantRole) : '-'}` : '商户配置与管理中心'}
        breadcrumbs={[{ title: title }]}
        extra={
          <Button icon={<ReloadOutlined />} loading={loading} onClick={loadAll}>
            刷新
          </Button>
        }
      />

      {fixedTab ? fixedTabContent : (
        <Tabs
          activeKey={activeTab}
          onChange={(key) => setActiveTab(key as MerchantCenterTab)}
          items={tabItems}
        />
      )}

      <Modal title={editingProduct ? '编辑商品' : '新增商品'} open={productOpen} onOk={submitProduct} onCancel={() => setProductOpen(false)} destroyOnClose width={620}>
        <Form form={productForm} layout="vertical" style={{ marginTop: 16 }}>
          {!editingProduct && (
            <>
              <Form.Item name="product_code" label="目录编码">
                <Input placeholder="已有目录编码可选填" />
              </Form.Item>
              <Form.Item name="product_name" label="商品名称" rules={[{ required: true }]}>
                <Input />
              </Form.Item>
            </>
          )}
          <Space size="middle" style={{ width: '100%' }}>
            <Form.Item name="sku" label="商户 SKU" rules={[{ required: true }]} style={{ width: 280 }}>
              <Input disabled={!!editingProduct} />
            </Form.Item>
            <Form.Item name="display_name" label="展示名" style={{ width: 280 }}>
              <Input />
            </Form.Item>
          </Space>
          <Space size="middle" style={{ width: '100%' }}>
            <Form.Item name="price_amount" label="售价（积分）" rules={[{ required: true }]} style={{ width: 180 }}>
              <InputNumber min={0} precision={0} style={{ width: '100%' }} />
            </Form.Item>
            <Form.Item name="cost_amount" label="成本（积分）" style={{ width: 180 }}>
              <InputNumber min={0} precision={0} style={{ width: '100%' }} />
            </Form.Item>
            <Form.Item name="currency" label="币种" style={{ width: 180 }}>
              <Select options={[{ value: 'POINT', label: 'POINT（积分）' }]} />
            </Form.Item>
          </Space>
          <Space size="middle" style={{ width: '100%' }}>
            <Form.Item name="stock" label="库存（-1 无限）" style={{ width: 180 }}>
              <InputNumber style={{ width: '100%' }} />
            </Form.Item>
            <Form.Item name="status" label="状态" style={{ width: 180 }}>
              <Select options={[{ value: 'active', label: '上架' }, { value: 'inactive', label: '下架' }]} />
            </Form.Item>
            {!editingProduct && (
              <Form.Item name="category" label="品类" style={{ width: 180 }}>
                <Input />
              </Form.Item>
            )}
          </Space>
          <Form.Item name="fulfillment_config" label="发货配置">
            <Input.TextArea rows={3} placeholder='{"provider":"manual"}' />
          </Form.Item>
        </Form>
      </Modal>

      <Modal title="创建测试订单" open={testOrderOpen} onOk={submitTestOrder} onCancel={() => setTestOrderOpen(false)} destroyOnClose width={560}>
        <Form form={testOrderForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item name="sku" label="商品皮肤" rules={[{ required: true, message: '请选择商品' }]}>
            <Select
              showSearch
              loading={testOrderProductsLoading}
              optionFilterProp="label"
              options={testOrderProductOptions}
            />
          </Form.Item>
          <Form.Item name="buyer_reference" label="买家名称" rules={[{ max: 128 }]}>
            <Input />
          </Form.Item>
          <Form.Item name="order_status" label="订单状态" rules={[{ required: true }]}>
            <Select options={testOrderStatusOptions} />
          </Form.Item>
          <Form.Item name="note" label="备注" rules={[{ max: 512 }]}>
            <Input.TextArea rows={3} />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="测试订单"
        open={!!testOrderResult}
        onCancel={() => setTestOrderResult(null)}
        footer={(
          <Space>
            <Button onClick={() => setTestOrderResult(null)}>关闭</Button>
            {testOrderResult?.order.delivery_link_revoked_at ? (
              <Button onClick={() => restoreDeliveryLink(testOrderResult?.order.order_no || '')}>取消作废</Button>
            ) : (
              <>
                <Button
                  icon={<CopyOutlined />}
                  onClick={() => copyDeliveryLink(testOrderResult?.order.order_no || '')}
                >
                  复制发货链接
                </Button>
                <Button type="primary" icon={<LinkOutlined />} onClick={() => openDeliveryLink(testOrderResult?.order.order_no || '')}>
                  打开发货页
                </Button>
                <Button danger onClick={() => revokeDeliveryLink(testOrderResult?.order.order_no || '')}>作废链接</Button>
              </>
            )}
          </Space>
        )}
      >
        {testOrderResult && (
          <Descriptions size="small" bordered column={1} style={{ marginTop: 16 }}>
            <Descriptions.Item label="订单号">
              <Typography.Text copyable>{testOrderResult.order.order_no}</Typography.Text>
            </Descriptions.Item>
            <Descriptions.Item label="SKU">
              <Typography.Text code>{testOrderResult.order.product_sku}</Typography.Text>
            </Descriptions.Item>
            <Descriptions.Item label="可发货">
              <Tag color={testOrderResult.can_ship ? 'green' : 'red'}>
                {testOrderResult.can_ship ? 'can_ship=true' : 'can_ship=false'}
              </Tag>
            </Descriptions.Item>
            {!testOrderResult.can_ship && (
              <Descriptions.Item label="不可发货原因">
                <Typography.Text type="secondary">{testOrderResult.cannot_ship_reason || '-'}</Typography.Text>
              </Descriptions.Item>
            )}
            <Descriptions.Item label="链接有效期">
              {testOrderResult.order.delivery_link_revoked_at ? <Tag color="red">已作废</Tag> : formatDateTime(testOrderResult.order.delivery_link_expires_at)}
            </Descriptions.Item>
            <Descriptions.Item label="链接状态">
              <Typography.Text type="secondary">由后端签名生成，可复制、打开或作废。</Typography.Text>
            </Descriptions.Item>
          </Descriptions>
        )}
      </Modal>

      <Modal title="新增 API 密钥" open={apiClientOpen} onOk={submitAPIClient} onCancel={() => setApiClientOpen(false)} destroyOnClose>
        <Form form={apiClientForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item
            name="name"
            label="名称"
            rules={[{ required: true }, { max: 64, message: '名称最长 64 个字符' }]}
          >
            <Input placeholder="按用途命名，如：下单系统 / 对账脚本" maxLength={64} />
          </Form.Item>
          <Form.Item name="scopes" label="权限" rules={[{ required: true }]}>
            <Select mode="multiple" options={scopeOptions} />
          </Form.Item>
          <Form.Item name="signature_version" label="签名版本">
            <Select options={[{ value: 'v1', label: 'v1' }]} />
          </Form.Item>
          <Typography.Text type="secondary">
            建议不同用途（下单、查询、对账）分别创建密钥，便于独立禁用与审计。每个商户最多 {apiClientMax} 个。
          </Typography.Text>
        </Form>
      </Modal>

      <Modal title="API 密钥" open={!!apiCredential} onCancel={() => setApiCredential(null)} footer={<Button type="primary" onClick={() => setApiCredential(null)}>我已保存</Button>}>
        {apiCredential && <SecretBlock appKey={apiCredential.client.app_key} secret={apiCredential.secret} />}
      </Modal>

      <Modal title="回调密钥" open={!!callbackCredential} onCancel={() => setCallbackCredential(null)} footer={<Button type="primary" onClick={() => setCallbackCredential(null)}>我已保存</Button>}>
        {callbackCredential && <SecretBlock secret={callbackCredential.secret} />}
      </Modal>

      <Modal title="添加成员" open={memberOpen} onOk={submitMember} onCancel={() => setMemberOpen(false)} destroyOnClose>
        <Form form={memberForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item name="user_id" label="用户 ID" rules={[{ required: true }]}>
            <InputNumber min={1} precision={0} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="role" label="角色" rules={[{ required: true }]}>
            <Select options={memberRoleOptions} />
          </Form.Item>
          <Form.Item name="is_default" label="默认商户">
            <Select options={[{ value: true, label: '是' }, { value: false, label: '否' }]} />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  )
}

function pageConfig<T extends { page: number; size: number; total: number }>(
  data: T,
  load: (page: number, size: number) => void,
) {
  return {
    current: data.page,
    pageSize: data.size,
    total: data.total,
    showSizeChanger: true,
    showTotal: (total: number) => `共 ${total} 条`,
    onChange: load,
  }
}

function SecretBlock({ appKey, secret }: { appKey?: string; secret: string }) {
  return (
    <Space direction="vertical" style={{ width: '100%' }} size="middle">
      {appKey && (
        <div>
          <Typography.Text type="secondary">App Key</Typography.Text>
          <Typography.Paragraph copyable={{ text: appKey }} code style={{ marginTop: 8 }}>{appKey}</Typography.Paragraph>
        </div>
      )}
      <div>
        <Typography.Text type="secondary">Secret</Typography.Text>
        <Typography.Paragraph copyable={{ text: secret }} code style={{ marginTop: 8 }}>{secret}</Typography.Paragraph>
      </div>
      <Button icon={<CopyOutlined />} onClick={() => navigator.clipboard.writeText(secret).then(() => message.success('已复制'))}>
        复制 Secret
      </Button>
    </Space>
  )
}

function featuresToList(features?: string) {
  const list = (features || '')
    .split(/[,\s]+/)
    .map((item) => item.trim())
    .filter(Boolean)
  return list.length > 0 ? list : ['products', 'orders', 'wallet', 'api', 'callbacks']
}

function defaultCallbackFormValues() {
  return {
    events: ['order.shipping.updated'],
    status: 'active',
  }
}

function eventsToValue(events?: string) {
  return (events || '')
    .split(',')
    .map((item) => item.trim())
    .filter(Boolean)
}

function tabFromSearch(search: string): MerchantCenterTab | null {
  const tab = new URLSearchParams(search).get('tab')
  const allowedTabs: MerchantCenterTab[] = ['products', 'orders', 'wallet', 'api', 'callbacks', 'members']
  return allowedTabs.includes(tab as MerchantCenterTab) ? tab as MerchantCenterTab : null
}

function resolveEnabledTab(current: MerchantCenterTab, features?: string): MerchantCenterTab {
  const enabled = new Set(featuresToList(features))
  const tabFeatures: Record<MerchantCenterTab, string | null> = {
    products: 'products',
    orders: 'orders',
    wallet: 'wallet',
    api: 'api',
    callbacks: 'callbacks',
    members: null,
  }
  const feature = tabFeatures[current]
  if (feature === null || enabled.has(feature)) {
    return current
  }
  return (['products', 'orders', 'wallet', 'api', 'callbacks'] as MerchantCenterTab[]).find((key) => enabled.has(key)) || 'members'
}

function money(value?: number | null) {
  return `${Number(value || 0)} 积分`
}

function moneyWithSign(value?: number | null) {
  const amount = Number(value || 0)
  if (amount > 0) {
    return <span style={{ fontWeight: 700, color: '#16a34a' }}>+{money(amount)}</span>
  }
  if (amount < 0) {
    return <span style={{ fontWeight: 700, color: '#dc2626' }}>{money(amount)}</span>
  }
  return <span style={{ fontWeight: 600, color: '#64748b' }}>{money(amount)}</span>
}

function productStatusTag(value: string) {
  return value === 'active' ? (
    <span className="status-tag status-tag--green">
      <span className="status-dot"></span>
      已上架
    </span>
  ) : (
    <span className="status-tag status-tag--gray">
      <span className="status-dot"></span>
      已下架
    </span>
  )
}

function activeStatusTag(value: string) {
  return value === 'active' ? (
    <span className="status-tag status-tag--green">
      <span className="status-dot"></span>
      已启用
    </span>
  ) : (
    <span className="status-tag status-tag--gray">
      <span className="status-dot"></span>
      已禁用
    </span>
  )
}

function productOptionLabel(item: MerchantProduct) {
  const name = item.display_name || item.product?.name || item.sku
  return name === item.sku ? item.sku : `${name} / ${item.sku}`
}

function orderStatusTag(value: string) {
  const item = orderStatusMap[value] || { color: 'default', text: value }
  const tagClassMap: Record<string, string> = {
    paid: 'status-tag--blue',
    delivering: 'status-tag--cyan',
    delivered: 'status-tag--green',
    ship_failed: 'status-tag--red',
    cancelled: 'status-tag--gray',
  }
  const tagClass = tagClassMap[value] || 'status-tag--gray'
  return (
    <span className={`status-tag ${tagClass}`}>
      <span className="status-dot"></span>
      {item.text}
    </span>
  )
}

function ledgerTypeTag(value: string) {
  const map: Record<string, { color: string; text: string }> = {
    credit: { color: 'green', text: '入账' },
    debit: { color: 'red', text: '扣款' },
    refund: { color: 'purple', text: '退款' },
    adjust: { color: 'blue', text: '调整' },
  }
  const item = map[value] || { color: 'default', text: value }
  return <Tag color={item.color}>{item.text}</Tag>
}

function memberRoleTag(value: MerchantMember['role']) {
  return <Tag color={value === 'owner' ? 'gold' : 'blue'}>{roleText(value)}</Tag>
}

function scopesTag(value: string) {
  const scopes = (value || '').split(',').filter(Boolean)
  if (scopes.length === 0) {
    return '-'
  }
  return (
    <Space size={4} wrap>
      {scopes.map((s) => <Tag key={s}>{scopeLabel(s)}</Tag>)}
    </Space>
  )
}

function scopeLabel(scope: string) {
  return scopeOptions.find((item) => item.value === scope)?.label || scope
}

function roleText(value: MerchantMember['role']) {
  return memberRoleOptions.find((item) => item.value === value)?.label || value
}
