import {
  ArrowDownOutlined,
  ArrowUpOutlined,
  DeleteOutlined,
  PlusOutlined,
  ReloadOutlined,
  SaveOutlined,
  SearchOutlined,
} from '@ant-design/icons'
import {
  Alert,
  Button,
  Card,
  Empty,
  Input,
  InputNumber,
  Select,
  Space,
  Spin,
  Switch,
  Table,
  Tabs,
  Tag,
  Typography,
} from 'antd'
import type { TableColumnsType } from 'antd'
import { useEffect, useMemo, useState } from 'react'

import PageHeader from '@/components/admin/PageHeader'
import { showError, showSuccess } from '@/lib/feedback'
import {
  fetchAdminCloudtentaclesOverrideRules,
  fetchAdminCloudtentaclesSkuList,
  fetchAdminCloudtentaclesSourceConfig,
  fetchAdminFulfillmentRoutingConfig,
  fetchAdminKuaishouFeifeiConfig,
  matchAdminKuaishouFeifeiProduct,
  previewAdminFulfillmentRouting,
  saveAdminCloudtentaclesOverrideRules,
  saveAdminFulfillmentRoutingConfig,
  syncAdminKuaishouFeifeiProducts,
} from '@/services/admin'
import type {
  AdminCloudtentaclesOverrideDeliveryItem,
  AdminCloudtentaclesOverrideRule,
  AdminCloudtentaclesSessionItem,
  AdminCloudtentaclesSessionsMap,
  AdminCloudtentaclesSkuItem,
  AdminCloudtentaclesSourceItem,
  AdminFulfillmentRoutingConfig,
  AdminFulfillmentRoutingPreviewResult,
  AdminFulfillmentRoutingRule,
  AdminKuaishouFeifeiConfigResponse,
  AdminKuaishouFeifeiMatchResult,
  AdminKuaishouFeifeiProductRule,
} from '@/types/admin'
import { hasAdminRole } from '@/utils/admin-auth'
import { buildAdminLocalTablePagination } from '@/utils/admin-pagination'

type EditableOverrideRule = Omit<AdminCloudtentaclesOverrideRule, 'normalizedProductName'> & {
  normalizedProductName?: string
}
type EditableRoutingRule = Omit<AdminFulfillmentRoutingRule, 'normalizedProductName'> & {
  normalizedProductName?: string
}

type SourceRow = AdminCloudtentaclesSourceItem & {
  session: AdminCloudtentaclesSessionItem | null
  ready: boolean
}

const ROUTING_EXECUTORS = [
  { key: 'kuaishou_ct_assisted', label: 'kuaishou-lewan', color: 'blue' },
  { key: 'kuaishou_feifei', label: 'kuaishou-feifei', color: 'purple' },
  { key: 'affiliate_dash', label: 'affiliate-dash', color: 'gold' },
  { key: 'manual_dispatch', label: '人工履约', color: 'orange' },
]

export default function AdminPlatformFulfillmentPage() {
  return (
    <section className="page-stack">
      <PageHeader
        title="履约配置"
        description="维护 91 卡券商品到 kuaishou-feifei 与 kuaishou-lewan 的履约映射规则。"
      />

      {!hasAdminRole('admin') ? (
        <Card>
          <Empty description="仅管理员可以查看履约配置" />
        </Card>
      ) : (
        <Tabs
          className="platform-tabs"
          destroyOnHidden={false}
          items={[
            {
              key: 'fulfillment-routing',
              label: '履约路由',
              children: <FulfillmentRoutingPanel />,
            },
            {
              key: 'kuaishou-feifei',
              label: 'kuaishou-feifei',
              children: <KuaishouFeifeiFulfillmentPanel />,
            },
            {
              key: 'kuaishou-cloud',
              label: 'kuaishou-lewan',
              children: <KuaishouCloudFulfillmentPanel />,
            },
          ]}
        />
      )}
    </section>
  )
}

function FulfillmentRoutingPanel() {
  const [loading, setLoading] = useState(true)
  const [saving, setSaving] = useState(false)
  const [previewing, setPreviewing] = useState(false)
  const [errorMessage, setErrorMessage] = useState('')
  const [enabled, setEnabled] = useState(true)
  const [priority, setPriority] = useState<string[]>(['kuaishou_ct_assisted', 'kuaishou_feifei'])
  const [unmatchedExecutorKey, setUnmatchedExecutorKey] = useState('')
  const [executors, setExecutors] = useState<AdminFulfillmentRoutingConfig['executors']>({})
  const [rules, setRules] = useState<EditableRoutingRule[]>([])
  const [previewInput, setPreviewInput] = useState('')
  const [previewResult, setPreviewResult] = useState<AdminFulfillmentRoutingPreviewResult | null>(
    null,
  )

  const enabledRuleCount = rules.filter((rule) => rule.enabled !== false).length
  const selectedExecutorKey = previewResult?.fulfillmentRoute?.selectedExecutorKey || ''

  useEffect(() => {
    void loadConfig()
  }, [])

  async function loadConfig() {
    setLoading(true)
    setErrorMessage('')

    try {
      const response = await fetchAdminFulfillmentRoutingConfig()
      hydrateConfig(response.data)
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : '读取履约路由配置失败')
    } finally {
      setLoading(false)
    }
  }

  async function saveConfig() {
    setSaving(true)
    setErrorMessage('')

    try {
      const response = await saveAdminFulfillmentRoutingConfig({
        enabled,
        defaultExecutorPriority: priority,
        unmatchedExecutorKey,
        executors,
        rules: rules.map((rule) => ({
          id: rule.id,
          enabled: rule.enabled !== false,
          productName: rule.productName,
          normalizedProductName: rule.normalizedProductName || '',
          matchType: rule.matchType,
          executorKey: rule.executorKey,
          priority: rule.priority,
          notes: rule.notes,
        })),
      })
      hydrateConfig(response.data)
      showSuccess('履约路由配置已保存')
    } catch (error) {
      const message = error instanceof Error ? error.message : '保存履约路由配置失败'
      setErrorMessage(message)
      showError(message)
    } finally {
      setSaving(false)
    }
  }

  async function previewRoute() {
    const productName = previewInput.trim()
    if (!productName) {
      showError('请输入 91 商品名')
      return
    }

    setPreviewing(true)
    setPreviewResult(null)

    try {
      const response = await previewAdminFulfillmentRouting(productName)
      setPreviewResult(response.data)
    } catch (error) {
      showError(error instanceof Error ? error.message : '预览履约路由失败')
    } finally {
      setPreviewing(false)
    }
  }

  function hydrateConfig(data: AdminFulfillmentRoutingConfig) {
    setEnabled(data.enabled !== false)
    setPriority(normalizeRoutingPriority(data.defaultExecutorPriority))
    setUnmatchedExecutorKey(data.unmatchedExecutorKey || '')
    setExecutors(normalizeRoutingExecutors(data.executors))
    setRules(Array.isArray(data.rules) ? data.rules.map((rule) => normalizeRoutingRule(rule)) : [])
  }

  function movePriority(executorKey: string, offset: -1 | 1) {
    const currentIndex = priority.indexOf(executorKey)
    const nextIndex = currentIndex + offset
    if (currentIndex < 0 || nextIndex < 0 || nextIndex >= priority.length) {
      return
    }

    const next = [...priority]
    const [item] = next.splice(currentIndex, 1)
    next.splice(nextIndex, 0, item)
    setPriority(next)
  }

  function updateExecutorEnabled(executorKey: string, nextEnabled: boolean) {
    setExecutors({
      ...executors,
      [executorKey]: {
        enabled: nextEnabled,
      },
    })
  }

  function updateRule(index: number, patch: Partial<EditableRoutingRule>) {
    setRules((current) =>
      current.map((rule, ruleIndex) =>
        ruleIndex === index
          ? {
              ...rule,
              ...patch,
            }
          : rule,
      ),
    )
  }

  function addRule() {
    const productName = previewInput.trim()
    const nextId = `${Date.now()}-${rules.length + 1}`
    setRules([
      {
        id: nextId,
        enabled: true,
        productName,
        normalizedProductName: '',
        matchType: 'exact',
        executorKey: 'kuaishou_feifei',
        priority: 100,
        notes: '',
      },
      ...rules,
    ])
  }

  function removeRule(index: number) {
    setRules((current) => current.filter((_, ruleIndex) => ruleIndex !== index))
  }

  if (loading) {
    return <Spin />
  }

  return (
    <section className="platform-panel-stack">
      {errorMessage ? <Alert type="error" showIcon message={errorMessage} /> : null}

      <div className="metric-grid four">
        <MetricCard label="路由状态" value={enabled ? '启用' : '停用'} />
        <MetricCard
          label="商品规则"
          value={String(rules.length)}
          detail={`启用 ${enabledRuleCount} 条`}
        />
        <MetricCard
          label="全局优先级"
          value={`${priority.length} 个通道`}
          detail={priority.map(formatRoutingExecutorLabel).join(' > ') || '未配置'}
        />
        <Card>
          <Space wrap>
            <Button icon={<ReloadOutlined />} loading={loading} onClick={loadConfig}>
              刷新
            </Button>
            <Button type="primary" icon={<SaveOutlined />} loading={saving} onClick={saveConfig}>
              保存配置
            </Button>
          </Space>
        </Card>
      </div>

      <Card title="通道开关">
        <div className="platform-routing-grid">
          <div className="field-switch">
            <span>履约路由</span>
            <Switch
              checked={enabled}
              checkedChildren="启用"
              unCheckedChildren="停用"
              onChange={setEnabled}
            />
          </div>
          {ROUTING_EXECUTORS.map((executor) => (
            <div key={executor.key} className="field-switch">
              <span>{executor.label}</span>
              <Switch
                checked={executors[executor.key]?.enabled !== false}
                checkedChildren="启用"
                unCheckedChildren="停用"
                onChange={(checked) => updateExecutorEnabled(executor.key, checked)}
              />
            </div>
          ))}
        </div>
      </Card>

      <Card title="全局优先级">
        <Space direction="vertical" className="full-width" size={10}>
          {priority.map((executorKey, index) => (
            <div key={executorKey} className="platform-routing-priority-row">
              <Space>
                <Tag color={resolveRoutingExecutorColor(executorKey)}>
                  {index + 1}. {formatRoutingExecutorLabel(executorKey)}
                </Tag>
              </Space>
              <Space>
                <Button
                  size="small"
                  icon={<ArrowUpOutlined />}
                  disabled={index === 0}
                  onClick={() => movePriority(executorKey, -1)}
                />
                <Button
                  size="small"
                  icon={<ArrowDownOutlined />}
                  disabled={index === priority.length - 1}
                  onClick={() => movePriority(executorKey, 1)}
                />
              </Space>
            </div>
          ))}
          <Select
            value={unmatchedExecutorKey}
            options={[
              { label: '未命中时保持未配置', value: '' },
              { label: '未命中时转人工履约', value: 'manual_dispatch' },
            ]}
            onChange={(value) => setUnmatchedExecutorKey(String(value || ''))}
          />
        </Space>
      </Card>

      <Card
        title="路由预览"
        extra={
          <Button icon={<PlusOutlined />} onClick={addRule}>
            新增规则
          </Button>
        }
      >
        <Space.Compact className="full-width">
          <Input
            allowClear
            value={previewInput}
            placeholder="91 商品名 / productNo"
            onChange={(event) => setPreviewInput(event.target.value)}
            onPressEnter={previewRoute}
          />
          <Button icon={<SearchOutlined />} loading={previewing} onClick={previewRoute}>
            预览路由
          </Button>
        </Space.Compact>

        {previewResult ? (
          <Alert
            className="platform-section-gap"
            type={previewResult.isConfigured ? 'success' : 'warning'}
            showIcon
            message={
              previewResult.isConfigured
                ? `最终路由：${formatRoutingExecutorLabel(selectedExecutorKey)}`
                : '未命中可用履约通道'
            }
            description={
              <Space direction="vertical" size={4}>
                <Typography.Text>
                  {previewResult.fulfillmentRoute?.reason || previewResult.normalizedProductName}
                </Typography.Text>
                <Space wrap>
                  {previewResult.fulfillmentRoute?.candidates.map((candidate) => (
                    <Tag
                      key={candidate.executorKey}
                      color={candidate.available ? 'green' : 'default'}
                    >
                      {formatRoutingExecutorLabel(candidate.executorKey)}
                      {candidate.available ? ' 可用' : ' 未命中'}
                    </Tag>
                  ))}
                </Space>
              </Space>
            }
          />
        ) : null}
      </Card>

      <Card
        title="商品路由规则"
        extra={
          <Space wrap>
            <Button icon={<PlusOutlined />} onClick={addRule}>
              新增规则
            </Button>
            <Button type="primary" icon={<SaveOutlined />} loading={saving} onClick={saveConfig}>
              保存规则
            </Button>
          </Space>
        }
      >
        {rules.length === 0 ? (
          <Empty description="暂无商品路由规则" />
        ) : (
          <Space direction="vertical" className="full-width" size={12}>
            {rules.map((rule, index) => (
              <div key={rule.id} className="platform-route-rule">
                <div className="platform-route-rule-head">
                  <Space wrap>
                    <Switch
                      size="small"
                      checked={rule.enabled !== false}
                      onChange={(checked) => updateRule(index, { enabled: checked })}
                    />
                    <Typography.Text strong>{rule.productName || '未命名规则'}</Typography.Text>
                  </Space>
                  <Button
                    danger
                    size="small"
                    icon={<DeleteOutlined />}
                    onClick={() => removeRule(index)}
                  >
                    删除
                  </Button>
                </div>
                <div className="platform-route-rule-grid">
                  <Input
                    value={rule.productName}
                    placeholder="91 商品名 / productNo"
                    onChange={(event) => updateRule(index, { productName: event.target.value })}
                  />
                  <Select
                    value={rule.matchType}
                    options={[
                      { label: '精确', value: 'exact' },
                      { label: '包含', value: 'contains' },
                    ]}
                    onChange={(matchType) =>
                      updateRule(index, {
                        matchType: matchType === 'contains' ? 'contains' : 'exact',
                      })
                    }
                  />
                  <Select
                    value={rule.executorKey}
                    options={ROUTING_EXECUTORS.map((executor) => ({
                      label: executor.label,
                      value: executor.key,
                    }))}
                    onChange={(executorKey) =>
                      updateRule(index, { executorKey: String(executorKey || '') })
                    }
                  />
                  <InputNumber
                    value={rule.priority}
                    min={0}
                    max={9999}
                    onChange={(priorityValue) =>
                      updateRule(index, { priority: Number(priorityValue || 0) || 0 })
                    }
                  />
                </div>
                <Input
                  value={rule.notes}
                  placeholder="备注"
                  onChange={(event) => updateRule(index, { notes: event.target.value })}
                />
              </div>
            ))}
          </Space>
        )}
      </Card>
    </section>
  )
}

function KuaishouFeifeiFulfillmentPanel() {
  const [loading, setLoading] = useState(true)
  const [syncing, setSyncing] = useState(false)
  const [matching, setMatching] = useState(false)
  const [errorMessage, setErrorMessage] = useState('')
  const [rules, setRules] = useState<AdminKuaishouFeifeiProductRule[]>([])
  const [matchInput, setMatchInput] = useState('')
  const [matchResult, setMatchResult] = useState<AdminKuaishouFeifeiMatchResult | null>(null)
  const [lastSyncText, setLastSyncText] = useState('')

  const enabledRuleCount = rules.filter((rule) => rule.enabled !== false).length
  const mappingCount = rules.filter(
    (rule) => rule.productName.trim() && rule.productCode.trim(),
  ).length

  useEffect(() => {
    void loadConfig()
  }, [])

  async function loadConfig() {
    setLoading(true)
    setErrorMessage('')

    try {
      const response = await fetchAdminKuaishouFeifeiConfig()
      hydrateConfig(response.data)
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : '读取 kuaishou-feifei 履约映射失败')
    } finally {
      setLoading(false)
    }
  }

  async function syncProducts() {
    setSyncing(true)
    setErrorMessage('')

    try {
      const response = await syncAdminKuaishouFeifeiProducts({ status: 'on_sale' })
      hydrateConfig(response.data)
      const text = `商品 ${response.data.sync.productCount} 个，映射 ${response.data.sync.ruleCount} 条`
      setLastSyncText(text)
      showSuccess(`kuaishou-feifei 商品映射已同步，${text}`)
    } catch (error) {
      const message = error instanceof Error ? error.message : '同步 kuaishou-feifei 商品映射失败'
      setErrorMessage(message)
      showError(message)
    } finally {
      setSyncing(false)
    }
  }

  async function previewMatch() {
    const productName = matchInput.trim()
    if (!productName) {
      showError('请输入 91 商品名')
      return
    }

    setMatching(true)
    setMatchResult(null)

    try {
      const response = await matchAdminKuaishouFeifeiProduct(productName)
      setMatchResult(response.data)
    } catch (error) {
      showError(error instanceof Error ? error.message : '预览 kuaishou-feifei 映射失败')
    } finally {
      setMatching(false)
    }
  }

  function hydrateConfig(data: AdminKuaishouFeifeiConfigResponse) {
    setRules(
      Array.isArray(data.source.productRules)
        ? data.source.productRules.map((rule) => normalizeFeifeiRule(rule))
        : [],
    )
  }

  const columns: TableColumnsType<AdminKuaishouFeifeiProductRule> = [
    {
      title: 'feifei 商品名',
      dataIndex: 'productName',
      minWidth: 260,
      render: (_, row) => (
        <div className="cell-stack">
          <Typography.Text strong ellipsis>
            {row.productName || row.skuName || '-'}
          </Typography.Text>
          <Typography.Text type="secondary" ellipsis>
            {row.normalizedProductName || '-'}
          </Typography.Text>
        </div>
      ),
    },
    { title: 'product_code', dataIndex: 'productCode', minWidth: 150 },
    { title: '展示名称', dataIndex: 'skuName', minWidth: 220 },
    {
      title: '状态',
      width: 100,
      render: (_, row) => (
        <Tag color={row.enabled !== false ? 'green' : 'default'}>
          {row.enabled !== false ? '启用' : '停用'}
        </Tag>
      ),
    },
    { title: '来源', dataIndex: 'notes', minWidth: 180 },
  ]

  if (loading) {
    return <Spin />
  }

  return (
    <section className="platform-panel-stack">
      {errorMessage ? <Alert type="error" showIcon message={errorMessage} /> : null}

      <div className="metric-grid three">
        <MetricCard
          label="名字映射"
          value={String(mappingCount)}
          detail={`启用 ${enabledRuleCount} 条`}
        />
        <MetricCard label="匹配方式" value="同名" detail="使用 91 商品名规范化匹配" />
        <Card>
          <Space wrap>
            <Button icon={<ReloadOutlined />} loading={loading} onClick={loadConfig}>
              刷新
            </Button>
            <Button
              type="primary"
              icon={<ReloadOutlined />}
              loading={syncing}
              onClick={syncProducts}
            >
              同步商品映射
            </Button>
          </Space>
        </Card>
      </div>

      <Card
        title="商品名字映射"
        extra={
          <Typography.Text type="secondary">
            {lastSyncText || 'feifei 商品名会按规范化名字匹配 91 商品名。'}
          </Typography.Text>
        }
      >
        <Space.Compact className="full-width">
          <Input
            allowClear
            value={matchInput}
            placeholder="91 商品名，例如 套装-Alan Walker"
            onChange={(event) => setMatchInput(event.target.value)}
            onPressEnter={previewMatch}
          />
          <Button icon={<SearchOutlined />} loading={matching} onClick={previewMatch}>
            预览命中
          </Button>
        </Space.Compact>

        {matchResult ? (
          <Alert
            className="platform-section-gap"
            type={matchResult.matched ? 'success' : 'warning'}
            showIcon
            message={matchResult.matched ? '已命中' : '未命中'}
            description={
              matchResult.match
                ? `${matchResult.match.productName} -> ${matchResult.match.productCode}`
                : matchResult.normalizedProductName || matchResult.productName
            }
          />
        ) : null}

        <Table<AdminKuaishouFeifeiProductRule>
          rowKey={(row) => row.id || `${row.productName}-${row.productCode}`}
          columns={columns}
          dataSource={rules}
          pagination={buildAdminLocalTablePagination()}
          scroll={{ x: 920, y: 520 }}
          locale={{ emptyText: '暂无 kuaishou-feifei 商品映射' }}
          className="platform-section-gap"
        />
      </Card>
    </section>
  )
}

function KuaishouCloudFulfillmentPanel() {
  const [loading, setLoading] = useState(true)
  const [skuLoading, setSkuLoading] = useState(false)
  const [overrideSaving, setOverrideSaving] = useState(false)
  const [errorMessage, setErrorMessage] = useState('')
  const [skuErrorMessage, setSkuErrorMessage] = useState('')
  const [overrideErrorMessage, setOverrideErrorMessage] = useState('')
  const [selectedSourceKey, setSelectedSourceKey] = useState('')
  const [sources, setSources] = useState<AdminCloudtentaclesSourceItem[]>([])
  const [sessions, setSessions] = useState<AdminCloudtentaclesSessionsMap>({})
  const [skuItems, setSkuItems] = useState<AdminCloudtentaclesSkuItem[]>([])
  const [overrideEnabled, setOverrideEnabled] = useState(true)
  const [overrideRules, setOverrideRules] = useState<EditableOverrideRule[]>([])
  const [matchInput, setMatchInput] = useState('')

  const sourceRows = useMemo(
    () =>
      sources.map((source) => {
        const session = sessions[source.key] || null
        return {
          ...source,
          session,
          ready: source.enabled !== false && Boolean(session?.hasToken),
        }
      }),
    [sessions, sources],
  )
  const readySources = sourceRows.filter((source) => source.ready)
  const selectedSource = sourceRows.find((source) => source.key === selectedSourceKey) || null
  const matchedSku = useMemo(() => {
    const normalizedInput = normalizeMatchName(matchInput)
    if (!normalizedInput) {
      return null
    }

    return (
      skuItems.find((item) => String(item.name || '').trim() === matchInput.trim()) ||
      skuItems.find((item) => normalizeMatchName(item.name) === normalizedInput) ||
      null
    )
  }, [matchInput, skuItems])
  const metrics = {
    sourceCount: sources.length,
    readySourceCount: readySources.length,
    skuCount: skuItems.length,
    inventoryTotal: skuItems.reduce(
      (sum, item) => sum + Math.max(0, Number(item.inventory || 0)),
      0,
    ),
    overrideRuleCount: overrideRules.length,
  }

  useEffect(() => {
    void loadPage()
  }, [])

  useEffect(() => {
    if (selectedSourceKey) {
      void loadSkuList(selectedSourceKey)
    } else {
      setSkuItems([])
    }
  }, [selectedSourceKey])

  async function loadPage() {
    setLoading(true)
    setErrorMessage('')

    try {
      const [sourceResponse, overrideResponse] = await Promise.all([
        fetchAdminCloudtentaclesSourceConfig(),
        fetchAdminCloudtentaclesOverrideRules(),
      ])
      const nextSources = Array.isArray(sourceResponse.data.sources)
        ? sourceResponse.data.sources
        : []
      const nextSessions = sourceResponse.data.sessions || {}
      const nextRows = nextSources.map((source) => {
        const session = nextSessions[source.key] || null
        return {
          ...source,
          session,
          ready: source.enabled !== false && Boolean(session?.hasToken),
        }
      })

      setSources(nextSources)
      setSessions(nextSessions)
      setOverrideEnabled(overrideResponse.data.enabled !== false)
      setOverrideRules(
        Array.isArray(overrideResponse.data.rules)
          ? overrideResponse.data.rules.map((rule) => normalizeEditableRule(rule))
          : [],
      )
      setSelectedSourceKey(resolveDefaultSourceKey(nextRows, selectedSourceKey))
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : '读取 kuaishou-lewan 履约配置失败')
    } finally {
      setLoading(false)
    }
  }

  async function loadSkuList(sourceKey = selectedSourceKey) {
    if (!sourceKey) {
      setSkuItems([])
      return
    }

    setSkuLoading(true)
    setSkuErrorMessage('')

    try {
      const response = await fetchAdminCloudtentaclesSkuList({ sourceKey })
      setSkuItems(Array.isArray(response.data.items) ? response.data.items : [])
    } catch (error) {
      setSkuItems([])
      setSkuErrorMessage(error instanceof Error ? error.message : '读取 kuaishou-lewan 商品失败')
    } finally {
      setSkuLoading(false)
    }
  }

  async function saveOverrideRules() {
    setOverrideSaving(true)
    setOverrideErrorMessage('')

    try {
      const response = await saveAdminCloudtentaclesOverrideRules({
        enabled: overrideEnabled,
        rules: overrideRules.map((rule) => ({
          id: rule.id,
          enabled: rule.enabled,
          productName: rule.productName,
          sourceKey: rule.sourceKey,
          deliveryItems: rule.deliveryItems,
          notes: rule.notes,
        })),
      })
      setOverrideEnabled(response.data.enabled !== false)
      setOverrideRules(
        Array.isArray(response.data.rules)
          ? response.data.rules.map((rule) => normalizeEditableRule(rule))
          : [],
      )
      showSuccess(`商品覆盖规则已保存，共 ${response.data.rules.length} 条`)
    } catch (error) {
      const message = error instanceof Error ? error.message : '保存 kuaishou-lewan 覆盖规则失败'
      setOverrideErrorMessage(message)
      showError(message)
    } finally {
      setOverrideSaving(false)
    }
  }

  function addOverrideRule() {
    setOverrideRules((current) => [
      {
        id: createRuleId(),
        enabled: true,
        productName: matchInput.trim(),
        normalizedProductName: normalizeMatchName(matchInput),
        sourceKey: selectedSourceKey,
        deliveryItems: [createDeliveryItem(skuItems)],
        notes: '',
      },
      ...current,
    ])
  }

  function updateRule(index: number, patch: Partial<EditableOverrideRule>) {
    setOverrideRules((current) =>
      current.map((rule, ruleIndex) => (ruleIndex === index ? { ...rule, ...patch } : rule)),
    )
  }

  function updateDeliveryItem(
    ruleIndex: number,
    itemIndex: number,
    patch: Partial<AdminCloudtentaclesOverrideDeliveryItem>,
  ) {
    setOverrideRules((current) =>
      current.map((rule, currentRuleIndex) => {
        if (currentRuleIndex !== ruleIndex) {
          return rule
        }

        return {
          ...rule,
          deliveryItems: rule.deliveryItems.map((item, currentItemIndex) =>
            currentItemIndex === itemIndex ? { ...item, ...patch } : item,
          ),
        }
      }),
    )
  }

  function removeOverrideRule(index: number) {
    setOverrideRules((current) => current.filter((_, ruleIndex) => ruleIndex !== index))
  }

  function addDeliveryItem(ruleIndex: number) {
    setOverrideRules((current) =>
      current.map((rule, currentRuleIndex) =>
        currentRuleIndex === ruleIndex
          ? { ...rule, deliveryItems: [...rule.deliveryItems, createDeliveryItem(skuItems)] }
          : rule,
      ),
    )
  }

  function removeDeliveryItem(ruleIndex: number, itemIndex: number) {
    setOverrideRules((current) =>
      current.map((rule, currentRuleIndex) => {
        if (currentRuleIndex !== ruleIndex) {
          return rule
        }

        const nextItems = rule.deliveryItems.filter(
          (_, currentItemIndex) => currentItemIndex !== itemIndex,
        )
        return {
          ...rule,
          deliveryItems: nextItems.length ? nextItems : [createDeliveryItem(skuItems)],
        }
      }),
    )
  }

  function handleDeliverySkuChange(ruleIndex: number, itemIndex: number, skuId: number) {
    const sku = skuItems.find((item) => Number(item.id || 0) === Number(skuId || 0))
    updateDeliveryItem(ruleIndex, itemIndex, {
      cloudSkuId: Number(skuId || 0) || 0,
      cloudSkuName: String(sku?.name || '').trim(),
    })
  }

  if (loading) {
    return <Spin />
  }

  return (
    <section className="platform-panel-stack">
      {errorMessage ? <Alert type="error" showIcon message={errorMessage} /> : null}

      <div className="metric-grid five">
        <MetricCard
          label="履约账号"
          value={`${metrics.readySourceCount} / ${metrics.sourceCount}`}
        />
        <MetricCard label="可发商品" value={String(metrics.skuCount)} />
        <MetricCard label="总库存" value={String(metrics.inventoryTotal)} />
        <MetricCard label="覆盖规则" value={String(metrics.overrideRuleCount)} />
        <Card>
          <Button icon={<ReloadOutlined />} loading={loading || skuLoading} onClick={loadPage}>
            刷新
          </Button>
        </Card>
      </div>

      <div className="platform-split-layout">
        <Card title="kuaishou-lewan 账号" className="platform-side-card">
          {sourceRows.length === 0 ? (
            <Empty description="暂无账号，请先到平台配置登录。" />
          ) : (
            <Space direction="vertical" className="full-width">
              {sourceRows.map((source) => (
                <button
                  key={source.key}
                  type="button"
                  className={
                    source.key === selectedSourceKey
                      ? 'platform-select-card active'
                      : 'platform-select-card'
                  }
                  onClick={() => setSelectedSourceKey(source.key)}
                >
                  <span>
                    <strong>{formatSourceLabel(source)}</strong>
                    <small>{source.username || source.key}</small>
                  </span>
                  <Tag
                    color={source.ready ? 'green' : source.enabled === false ? 'default' : 'orange'}
                  >
                    {source.ready ? '可用' : source.enabled === false ? '已停用' : '未登录'}
                  </Tag>
                </button>
              ))}
            </Space>
          )}
        </Card>

        <section className="platform-panel-stack">
          <Card
            title="匹配状态与覆盖规则"
            extra={
              <Space wrap>
                <Typography.Text type="secondary">
                  当前账号：{selectedSource ? formatSourceLabel(selectedSource) : '-'}
                </Typography.Text>
                <Button
                  icon={<ReloadOutlined />}
                  loading={skuLoading}
                  disabled={!selectedSourceKey}
                  onClick={() => loadSkuList()}
                >
                  刷新商品
                </Button>
              </Space>
            }
          >
            {skuErrorMessage ? (
              <Alert
                type="error"
                showIcon
                message={skuErrorMessage}
                className="platform-section-gap"
              />
            ) : null}

            <Space className="full-width" direction="vertical">
              <Space.Compact className="full-width">
                <Input
                  allowClear
                  value={matchInput}
                  placeholder="输入 91 卡券 productNo / 商品名字，查看命中的 kuaishou-lewan 商品"
                  onChange={(event) => setMatchInput(event.target.value)}
                />
                <Button icon={<PlusOutlined />} onClick={addOverrideRule}>
                  生成规则
                </Button>
              </Space.Compact>
              {matchedSku ? (
                <Tag color="green">
                  命中 #{matchedSku.id} {matchedSku.name}
                </Tag>
              ) : matchInput.trim() ? (
                <Tag color="orange">未命中</Tag>
              ) : null}
            </Space>
          </Card>

          <Card
            title="商品覆盖规则"
            extra={
              <Space wrap>
                <Switch
                  checked={overrideEnabled}
                  checkedChildren="启用"
                  unCheckedChildren="停用"
                  onChange={setOverrideEnabled}
                />
                <Button icon={<PlusOutlined />} onClick={addOverrideRule}>
                  新增规则
                </Button>
                <Button
                  type="primary"
                  icon={<SaveOutlined />}
                  loading={overrideSaving}
                  onClick={saveOverrideRules}
                >
                  保存规则
                </Button>
              </Space>
            }
          >
            {overrideErrorMessage ? (
              <Alert
                type="error"
                showIcon
                message={overrideErrorMessage}
                className="platform-section-gap"
              />
            ) : null}

            {overrideRules.length === 0 ? (
              <Empty description="暂无覆盖规则" />
            ) : (
              <Space direction="vertical" className="full-width" size={12}>
                {overrideRules.map((rule, ruleIndex) => (
                  <Card
                    key={rule.id}
                    size="small"
                    title={
                      <Space>
                        <Switch
                          size="small"
                          checked={rule.enabled !== false}
                          onChange={(enabled) => updateRule(ruleIndex, { enabled })}
                        />
                        <span>{rule.productName || '未命名规则'}</span>
                      </Space>
                    }
                    extra={
                      <Button
                        danger
                        size="small"
                        icon={<DeleteOutlined />}
                        onClick={() => removeOverrideRule(ruleIndex)}
                      >
                        删除
                      </Button>
                    }
                  >
                    <div className="platform-rule-head">
                      <Input
                        value={rule.productName}
                        placeholder="91 商品名 / productNo"
                        onChange={(event) =>
                          updateRule(ruleIndex, { productName: event.target.value })
                        }
                      />
                      <Select
                        allowClear
                        value={rule.sourceKey || undefined}
                        placeholder="全部账号"
                        options={[
                          { label: '全部账号', value: '' },
                          ...sourceRows.map((source) => ({
                            label: formatSourceLabel(source),
                            value: source.key,
                          })),
                        ]}
                        onChange={(sourceKey) => {
                          updateRule(ruleIndex, { sourceKey: String(sourceKey || '') })
                          if (sourceKey) {
                            setSelectedSourceKey(String(sourceKey))
                          }
                        }}
                      />
                    </div>

                    <Space
                      direction="vertical"
                      className="full-width platform-section-gap"
                      size={8}
                    >
                      {rule.deliveryItems.map((item, itemIndex) => (
                        <div key={`${rule.id}-${itemIndex}`} className="platform-delivery-row">
                          <Select
                            showSearch
                            value={item.cloudSkuId || undefined}
                            placeholder="选择 kuaishou-lewan 商品"
                            optionFilterProp="label"
                            options={skuItems.map((sku) => ({
                              label: formatSkuOption(sku),
                              value: sku.id,
                            }))}
                            onChange={(skuId) =>
                              handleDeliverySkuChange(ruleIndex, itemIndex, Number(skuId || 0))
                            }
                          />
                          <Input
                            value={item.cloudSkuName}
                            placeholder="kuaishou-lewan 商品名"
                            onChange={(event) =>
                              updateDeliveryItem(ruleIndex, itemIndex, {
                                cloudSkuName: event.target.value,
                              })
                            }
                          />
                          <InputNumber
                            min={1}
                            max={999}
                            value={item.quantity}
                            onChange={(quantity) =>
                              updateDeliveryItem(ruleIndex, itemIndex, {
                                quantity: Math.max(1, Number(quantity || 1) || 1),
                              })
                            }
                          />
                          <Button onClick={() => removeDeliveryItem(ruleIndex, itemIndex)}>
                            删除
                          </Button>
                        </div>
                      ))}
                      <Button onClick={() => addDeliveryItem(ruleIndex)}>增加发货商品</Button>
                    </Space>

                    <Input
                      className="platform-section-gap"
                      value={rule.notes}
                      placeholder="备注"
                      onChange={(event) => updateRule(ruleIndex, { notes: event.target.value })}
                    />
                  </Card>
                ))}
              </Space>
            )}
          </Card>

          <Card title="kuaishou-lewan 商品列表">
            <Table<AdminCloudtentaclesSkuItem>
              rowKey="id"
              loading={skuLoading}
              dataSource={skuItems}
              columns={[
                {
                  title: 'kuaishou-lewan 商品',
                  dataIndex: 'name',
                  minWidth: 260,
                  render: (_, row) => (
                    <div className="cell-stack">
                      <Typography.Text strong ellipsis>
                        {row.name || '-'}
                      </Typography.Text>
                      <Typography.Text type="secondary" ellipsis>
                        #{row.id} · {row.description || row.name || '-'}
                      </Typography.Text>
                    </div>
                  ),
                },
                {
                  title: '91 自动匹配名',
                  dataIndex: 'name',
                  minWidth: 220,
                  render: (value) => <code>{String(value || '-')}</code>,
                },
                { title: '价格', dataIndex: 'price', width: 120, render: formatCloudPrice },
                {
                  title: '库存',
                  dataIndex: 'inventory',
                  width: 120,
                  sorter: (a, b) => a.inventory - b.inventory,
                },
                {
                  title: '发货限制',
                  width: 150,
                  render: (_, row) => `${row.buyLimitMin || 1} - ${row.buyLimitMax || 1}`,
                },
                {
                  title: '状态',
                  width: 120,
                  render: (_, row) => (
                    <Tag color={Number(row.inventory || 0) > 0 ? 'green' : 'red'}>
                      {Number(row.inventory || 0) > 0 ? '可履约' : '无库存'}
                    </Tag>
                  ),
                },
              ]}
              pagination={buildAdminLocalTablePagination()}
              scroll={{ x: 1000, y: 420 }}
              locale={{ emptyText: '当前账号暂无可展示商品' }}
            />
          </Card>
        </section>
      </div>
    </section>
  )
}

function MetricCard({ label, value, detail }: { label: string; value: string; detail?: string }) {
  return (
    <Card className="metric-card">
      <span>{label}</span>
      <strong>{value}</strong>
      {detail ? <small>{detail}</small> : null}
    </Card>
  )
}

function normalizeRoutingPriority(value: unknown) {
  const rawItems = Array.isArray(value) ? value : []
  const allowed = ROUTING_EXECUTORS.filter((executor) => executor.key !== 'manual_dispatch').map(
    (executor) => executor.key,
  )
  const seen = new Set<string>()
  const items = rawItems
    .map((item) => String(item || '').trim())
    .filter((item) => allowed.includes(item) && !seen.has(item) && (seen.add(item), true))

  return items.length > 0 ? items : ['kuaishou_ct_assisted', 'kuaishou_feifei']
}

function normalizeRoutingExecutors(value: unknown): AdminFulfillmentRoutingConfig['executors'] {
  const source =
    value && typeof value === 'object' && !Array.isArray(value)
      ? (value as AdminFulfillmentRoutingConfig['executors'])
      : {}

  return ROUTING_EXECUTORS.reduce<AdminFulfillmentRoutingConfig['executors']>(
    (result, executor) => {
      result[executor.key] = {
        enabled: source[executor.key]?.enabled !== false,
      }
      return result
    },
    {},
  )
}

function normalizeRoutingRule(rule: AdminFulfillmentRoutingRule): EditableRoutingRule {
  const productName = String(rule.productName || '').trim()
  const executorKey = String(rule.executorKey || '').trim()

  return {
    id: String(rule.id || `${productName}-${executorKey}` || createRuleId()).trim(),
    enabled: rule.enabled !== false,
    productName,
    normalizedProductName: String(rule.normalizedProductName || '').trim(),
    matchType: rule.matchType === 'contains' ? 'contains' : 'exact',
    executorKey: executorKey || 'kuaishou_feifei',
    priority: Number(rule.priority || 0) || 0,
    notes: String(rule.notes || '').trim(),
  }
}

function formatRoutingExecutorLabel(executorKey: unknown) {
  const key = String(executorKey || '').trim()
  return ROUTING_EXECUTORS.find((executor) => executor.key === key)?.label || key || '-'
}

function resolveRoutingExecutorColor(executorKey: unknown) {
  const key = String(executorKey || '').trim()
  return ROUTING_EXECUTORS.find((executor) => executor.key === key)?.color || 'default'
}

function normalizeFeifeiRule(
  rule: Partial<AdminKuaishouFeifeiProductRule>,
): AdminKuaishouFeifeiProductRule {
  const productName = String(rule.productName || '').trim()
  const productCode = String(rule.productCode || '').trim()

  return {
    id: String(rule.id || productName || productCode).trim(),
    enabled: rule.enabled !== false,
    productName,
    normalizedProductName: String(rule.normalizedProductName || '').trim(),
    productCode,
    skuName: String(rule.skuName || productName || productCode).trim(),
    notes: String(rule.notes || '').trim(),
  }
}

function normalizeEditableRule(rule: AdminCloudtentaclesOverrideRule): EditableOverrideRule {
  return {
    id: String(rule.id || createRuleId()).trim(),
    enabled: rule.enabled !== false,
    productName: String(rule.productName || '').trim(),
    normalizedProductName: String(rule.normalizedProductName || '').trim(),
    sourceKey: String(rule.sourceKey || '').trim(),
    deliveryItems:
      Array.isArray(rule.deliveryItems) && rule.deliveryItems.length > 0
        ? rule.deliveryItems.map((item) => ({
            cloudSkuId: Number(item.cloudSkuId || 0) || 0,
            cloudSkuName: String(item.cloudSkuName || '').trim(),
            quantity: Math.max(1, Number(item.quantity || 1) || 1),
          }))
        : [createDeliveryItem([])],
    notes: String(rule.notes || '').trim(),
  }
}

function createDeliveryItem(
  skuItems: AdminCloudtentaclesSkuItem[],
): AdminCloudtentaclesOverrideDeliveryItem {
  const firstSku = skuItems[0]
  return {
    cloudSkuId: Number(firstSku?.id || 0) || 0,
    cloudSkuName: String(firstSku?.name || '').trim(),
    quantity: 1,
  }
}

function resolveDefaultSourceKey(sourceRows: SourceRow[], selectedSourceKey: string) {
  const current = sourceRows.find((source) => source.key === selectedSourceKey)
  if (current?.ready) {
    return current.key
  }

  return sourceRows.find((source) => source.ready)?.key || sourceRows[0]?.key || ''
}

function normalizeMatchName(value: unknown) {
  return String(value || '')
    .toLowerCase()
    .replace(/[【】[\]（）()]/g, ' ')
    .replace(/(自动发货|秒发|极速发货|官方直充|官方充值)/gi, ' ')
    .replace(/[^\p{L}\p{N}]+/gu, ' ')
    .replace(/\s+/g, ' ')
    .trim()
}

function formatSourceLabel(
  source: Pick<AdminCloudtentaclesSourceItem, 'key' | 'label' | 'username'>,
) {
  return source.label || source.username || source.key
}

function formatCloudPrice(value: unknown) {
  const price = Number(value)
  return Number.isFinite(price) ? String(price) : '-'
}

function formatSkuOption(sku: AdminCloudtentaclesSkuItem) {
  return `#${sku.id} ${sku.name}`
}

function createRuleId() {
  return `rule_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`
}
