import { PlayCircleOutlined, ReloadOutlined, SearchOutlined } from '@ant-design/icons'
import { useQuery, useQueryClient } from '@tanstack/react-query'
import {
  App,
  Button,
  Card,
  Descriptions,
  Input,
  Modal,
  Select,
  Space,
  Switch,
  Table,
  Tabs,
  Tag,
  Typography,
} from 'antd'
import type { TableColumnsType } from 'antd'
import { useState } from 'react'
import { useNavigate } from 'react-router'

import JsonPreview from '@/components/admin/JsonPreview'
import { AdminRangePicker } from '@/components/admin/AdminDatePicker'
import dayjs, { ADMIN_DATE_FORMAT } from '@/lib/dayjs'
import {
  fetchAdminKuaishouIndustryShops,
  fetchAdminKuaishouMatchSources,
  fetchAdminWorkerProductMatchConfig,
  fetchAdminWorkProductMatchLogs,
  saveAdminWorkerProductMatchConfig,
  testAdminKuaishouProductMatch,
} from '@/services/admin'
import type { KuaishouMatchSource, WorkProductMatchLog } from '@/types/worker-platform'
import type { AdminKuaishouIndustryShopOption } from '@/types/admin'
import { formatAdminDateTime } from '@/utils/admin-time'
import { ADMIN_DEFAULT_PAGE_SIZE, buildAdminTablePagination } from '@/utils/admin-pagination'

export default function ProductMatchPanel() {
  const { message } = App.useApp()
  const queryClient = useQueryClient()
  const navigate = useNavigate()
  const [testPayload, setTestPayload] = useState('')
  const [testResult, setTestResult] = useState<
    Awaited<ReturnType<typeof testAdminKuaishouProductMatch>>['data'] | null
  >(null)
  const [selectedLog, setSelectedLog] = useState<WorkProductMatchLog | null>(null)
  const [activeTab, setActiveTab] = useState('sources')
  const [logStatus, setLogStatus] = useState('')
  const [logKeywordInput, setLogKeywordInput] = useState('')
  const [logKeyword, setLogKeyword] = useState('')
  const [logCreatedRange, setLogCreatedRange] = useState<[string, string] | null>(null)
  const [logPage, setLogPage] = useState(1)

  const shopsQuery = useQuery({
    queryKey: ['admin-kuaishou-industry-shops', 'product-match'],
    queryFn: fetchAdminKuaishouIndustryShops,
  })
  const sourcesQuery = useQuery({
    queryKey: ['admin-worker-platform-product-match-sources'],
    queryFn: () => fetchAdminKuaishouMatchSources(200),
  })
  const logsQuery = useQuery({
    queryKey: [
      'admin-worker-platform-product-match-logs',
      logStatus,
      logKeyword,
      logCreatedRange,
      logPage,
    ],
    queryFn: () =>
      fetchAdminWorkProductMatchLogs({
        matchStatus: logStatus || undefined,
        keyword: logKeyword || undefined,
        createdFrom: logCreatedRange?.[0],
        createdTo: logCreatedRange?.[1],
        page: logPage,
        pageSize: ADMIN_DEFAULT_PAGE_SIZE,
      }),
  })
  const matchConfigQuery = useQuery({
    queryKey: ['admin-worker-platform-product-match-config'],
    queryFn: fetchAdminWorkerProductMatchConfig,
  })

  const sources = sourcesQuery.data?.data.items || []
  const logs = logsQuery.data?.data.items || []
  const logsPagination = logsQuery.data?.data.pagination
  const shops = shopsQuery.data?.data.shops || []
  const matchConfig = matchConfigQuery.data?.data
  const shopNameBySellerId = createShopNameBySellerId(shops)

  function bindToTemplate(source: KuaishouMatchSource) {
    const params = new URLSearchParams({
      tab: 'rules',
      bind: '1',
      sellerId: source.sellerId,
      relItemId: source.relItemId || '',
      itemTitle: source.itemTitle || '',
      relSkuId: source.relSkuId || '',
      skuNick: source.skuNick || '',
    })
    void navigate(`/admin/worker-platform?${params.toString()}`)
  }

  async function runMatchTest() {
    if (!testPayload.trim()) {
      message.warning('请选择或粘贴快手原始载荷')
      return
    }
    try {
      const response = await testAdminKuaishouProductMatch(testPayload)
      setTestResult(response.data)
    } catch (error) {
      message.error(error instanceof Error ? error.message : '匹配测试失败')
    }
  }

  async function updateLegacyFallback(legacyFallbackEnabled: boolean) {
    try {
      await saveAdminWorkerProductMatchConfig({ legacyFallbackEnabled })
      message.success(legacyFallbackEnabled ? '兼容旧模板匹配已开启' : '兼容旧模板匹配已关闭')
      await queryClient.invalidateQueries({
        queryKey: ['admin-worker-platform-product-match-config'],
      })
    } catch (error) {
      message.error(error instanceof Error ? error.message : '保存商品匹配配置失败')
    }
  }

  const sourceColumns: TableColumnsType<KuaishouMatchSource> = [
    {
      title: '快手商品 / SKU',
      key: 'source',
      render: (_, row) => (
        <div className="cell-stack">
          <Typography.Text strong ellipsis={{ tooltip: row.itemTitle }}>
            {row.itemTitle || row.relItemId}
          </Typography.Text>
          <Typography.Text type="secondary" style={{ fontSize: 12 }}>
            店铺 {formatShopLabel(row.sellerId, shopNameBySellerId)} · {row.skuNick || '商品默认'}
          </Typography.Text>
        </div>
      ),
    },
    {
      title: '出现',
      dataIndex: 'seenCount',
      width: 70,
      render: (value) => `${value} 次`,
    },
    {
      title: '最近',
      dataIndex: 'lastSeenAt',
      width: 160,
      render: (value) => formatAdminDateTime(value),
    },
    {
      title: '操作',
      key: 'actions',
      width: 160,
      render: (_, row) => (
        <Space size={4} wrap>
          <Button type="link" onClick={() => bindToTemplate(row)}>
            绑定到模板
          </Button>
          <Button
            type="text"
            onClick={() => {
              setTestPayload(JSON.stringify(row.rawPayload, null, 2))
              setActiveTab('test')
            }}
          >
            测试
          </Button>
        </Space>
      ),
    },
  ]

  const logColumns: TableColumnsType<WorkProductMatchLog> = [
    {
      title: '时间',
      dataIndex: 'createdAt',
      width: 165,
      render: (value) => formatAdminDateTime(value),
    },
    {
      title: '店铺 / 商品 / SKU',
      key: 'target',
      render: (_, row) => (
        <div className="cell-stack">
          <Typography.Text ellipsis={{ tooltip: row.itemTitle }}>
            {row.itemTitle || '-'}
          </Typography.Text>
          <Typography.Text type="secondary" style={{ fontSize: 12 }}>
            {formatShopLabel(row.sellerId, shopNameBySellerId)} ·{' '}
            {row.skuNick || row.relSkuId || '商品默认'}
          </Typography.Text>
        </div>
      ),
    },
    {
      title: '结果',
      dataIndex: 'status',
      width: 100,
      render: (value) => <MatchStatusTag status={value} />,
    },
    {
      title: '模板',
      key: 'rule',
      width: 170,
      render: (_, row) => row.productName || row.ruleKey || '-',
    },
    {
      title: '载荷',
      key: 'payload',
      width: 80,
      render: (_, row) => (
        <Button type="link" onClick={() => setSelectedLog(row)}>
          查看
        </Button>
      ),
    },
  ]

  return (
    <Card bordered={false} title="匹配诊断">
      <Space align="center" style={{ marginBottom: 16 }}>
        <Switch
          checked={matchConfig?.legacyFallbackEnabled === true}
          loading={matchConfigQuery.isLoading || matchConfigQuery.isFetching}
          onChange={updateLegacyFallback}
        />
        <Typography.Text>兼容旧模板匹配（迁移用）</Typography.Text>
        <Typography.Text type="secondary">
          默认关闭；正常快手订单按「接单模板 → 商品绑定」匹配
        </Typography.Text>
      </Space>
      <Tabs
        activeKey={activeTab}
        onChange={setActiveTab}
        items={[
          {
            key: 'sources',
            label: `已接收商品 (${sources.length})`,
            children: (
              <div className="page-stack">
                <Space>
                  <Button
                    icon={<ReloadOutlined />}
                    loading={sourcesQuery.isFetching}
                    onClick={() => sourcesQuery.refetch()}
                  >
                    刷新
                  </Button>
                  <Typography.Text type="secondary">
                    发现新商品后，点击「绑定到模板」在接单模板页配置匹配
                  </Typography.Text>
                </Space>
                <Table<KuaishouMatchSource>
                  rowKey={(row) =>
                    `${row.sellerId}-${row.relItemId}-${row.itemTitle}-${row.relSkuId}-${row.skuNick}`
                  }
                  loading={sourcesQuery.isLoading}
                  columns={sourceColumns}
                  dataSource={sources}
                  pagination={{ pageSize: 10, showSizeChanger: false }}
                  size="small"
                />
              </div>
            ),
          },
          {
            key: 'test',
            label: '匹配测试',
            children: (
              <div className="page-stack">
                <Space wrap>
                  <Select
                    showSearch
                    optionFilterProp="label"
                    style={{ minWidth: 360 }}
                    placeholder="选择已接收的快手原始载荷"
                    options={sources.map((source, index) => ({
                      value: index,
                      label: `${formatShopLabel(source.sellerId, shopNameBySellerId)} · ${source.itemTitle} · ${source.skuNick || '商品默认'}`,
                    }))}
                    onChange={(index) => {
                      const source = sources[Number(index)]
                      if (source) setTestPayload(JSON.stringify(source.rawPayload, null, 2))
                    }}
                  />
                  <Button type="primary" icon={<PlayCircleOutlined />} onClick={runMatchTest}>
                    测试匹配
                  </Button>
                </Space>
                <Input.TextArea
                  value={testPayload}
                  onChange={(event) => setTestPayload(event.target.value)}
                  rows={16}
                  placeholder="粘贴快手 send-code 原始载荷"
                />
                {testResult ? (
                  <div className="page-stack">
                    <Descriptions bordered size="small" column={{ xs: 1, md: 2 }}>
                      <Descriptions.Item label="结果">
                        <MatchStatusTag status={testResult.status} />
                      </Descriptions.Item>
                      <Descriptions.Item label="命中模板">
                        {testResult.rule?.productName || testResult.rule?.ruleKey || '-'}
                      </Descriptions.Item>
                      <Descriptions.Item label="店铺">
                        {testResult.context.sellerId
                          ? formatShopLabel(testResult.context.sellerId, shopNameBySellerId)
                          : '-'}
                      </Descriptions.Item>
                      <Descriptions.Item label="具体 SKU">
                        {testResult.context.skuNick || '-'}
                      </Descriptions.Item>
                    </Descriptions>
                    <JsonPreview
                      value={{ mappingId: testResult.mappingId, candidates: testResult.candidates }}
                    />
                  </div>
                ) : null}
              </div>
            ),
          },
          {
            key: 'logs',
            label: `匹配日志 (共 ${logsPagination?.total ?? 0} 条)`,
            children: (
              <div className="page-stack">
                <Space wrap>
                  <Select
                    allowClear
                    value={logStatus || undefined}
                    style={{ width: 130 }}
                    placeholder="全部结果"
                    options={[
                      { value: 'matched', label: '命中' },
                      { value: 'unmatched', label: '未命中' },
                      { value: 'ambiguous', label: '冲突' },
                    ]}
                    onChange={(value) => {
                      setLogStatus(value || '')
                      setLogPage(1)
                    }}
                  />
                  <Input
                    allowClear
                    value={logKeywordInput}
                    style={{ width: 240 }}
                    placeholder="商品名 / 商品ID / SKU / 店铺ID"
                    onChange={(event) => setLogKeywordInput(event.target.value)}
                    onPressEnter={() => {
                      setLogKeyword(logKeywordInput.trim())
                      setLogPage(1)
                    }}
                  />
                  <AdminRangePicker
                    value={
                      logCreatedRange
                        ? [dayjs(logCreatedRange[0]), dayjs(logCreatedRange[1])]
                        : null
                    }
                    onChange={(dates) => {
                      const [start, end] = dates || []
                      setLogCreatedRange(
                        start && end
                          ? [start.format(ADMIN_DATE_FORMAT), end.format(ADMIN_DATE_FORMAT)]
                          : null,
                      )
                      setLogPage(1)
                    }}
                  />
                  <Button
                    type="primary"
                    icon={<SearchOutlined />}
                    onClick={() => {
                      setLogKeyword(logKeywordInput.trim())
                      setLogPage(1)
                    }}
                  >
                    查询
                  </Button>
                  <Button
                    icon={<ReloadOutlined />}
                    loading={logsQuery.isFetching}
                    onClick={() => logsQuery.refetch()}
                  >
                    刷新
                  </Button>
                  <Typography.Text type="secondary">
                    日志全量保留，可按结果、关键词与日期筛选
                  </Typography.Text>
                </Space>
                <Table<WorkProductMatchLog>
                  rowKey="logId"
                  loading={logsQuery.isLoading}
                  columns={logColumns}
                  dataSource={logs}
                  pagination={buildAdminTablePagination({
                    page: logPage,
                    pageSize: ADMIN_DEFAULT_PAGE_SIZE,
                    total: logsPagination?.total || 0,
                    onChange: setLogPage,
                  })}
                  size="small"
                />
              </div>
            ),
          },
        ]}
      />
      <Modal
        title="匹配原始载荷"
        open={Boolean(selectedLog)}
        footer={null}
        width={760}
        onCancel={() => setSelectedLog(null)}
      >
        <JsonPreview value={selectedLog?.rawPayload} />
      </Modal>
    </Card>
  )
}

function MatchStatusTag({ status }: { status: string }) {
  const color = status === 'matched' ? 'green' : status === 'ambiguous' ? 'orange' : 'red'
  const label = status === 'matched' ? '命中' : status === 'ambiguous' ? '冲突' : '未命中'
  return <Tag color={color}>{label}</Tag>
}

function createShopNameBySellerId(shops: AdminKuaishouIndustryShopOption[]) {
  const names = new Map<string, string>()
  for (const shop of shops) {
    const name = String(shop.shopName || '').trim()
    if (!name) continue
    const sellerId = String(shop.sellerId || '').trim()
    const shopId = String(shop.shopId || '').trim()
    if (sellerId) names.set(sellerId, name)
    if (shopId) names.set(shopId, name)
  }
  return names
}

function formatShopLabel(sellerId: string, shopNameBySellerId: Map<string, string>) {
  const name = shopNameBySellerId.get(sellerId)
  return name ? `${name}（${sellerId}）` : sellerId
}
