import { useEffect, useLayoutEffect, useMemo, useRef, useState, type CSSProperties } from 'react'
import {
  Table, Tag, Space, Card, Select, Input, Button,
  Modal, Spin, Empty, Tooltip, Typography, Grid
} from 'antd'
import type { ColumnsType } from 'antd/es/table'
import type { CustomTagProps } from 'rc-select/lib/BaseSelect'
import {
  DatabaseOutlined, GlobalOutlined, CloudServerOutlined,
  AppstoreOutlined, EyeOutlined, SearchOutlined, FilterOutlined, ReloadOutlined
} from '@ant-design/icons'
import axios from 'axios'
import AppLayout from '../../components/AppLayout/AppLayout'

const { Title, Text } = Typography
const { useBreakpoint } = Grid

interface CollectedData {
  id: number
  source: string
  source_id: string
  data_type: string
  name: string
  title: string | null
  description: string | null
  country: string | null
  city: string | null
  latitude: string | null
  longitude: string | null
  value: string | null
  unit: string | null
  cores: string | null
  rmax: string | null
  rpeak: string | null
  power: string | null
  metadata: Record<string, any> | null
  collected_at: string
  reference_date: string | null
  is_valid: number
}

interface Summary {
  total_records: number
  by_source: Record<string, Record<string, number>>
  source_totals: Array<{ source: string; count: number }>
}

const DETAIL_FIELD_LABELS: Record<string, string> = {
  id: 'ID',
  source: '数据源',
  source_id: '原始ID',
  data_type: '数据类型',
  name: '名称',
  title: '标题',
  description: '描述',
  country: '国家',
  city: '城市',
  latitude: '纬度',
  longitude: '经度',
  value: '数值',
  unit: '单位',
  collected_at: '采集时间',
  reference_date: '参考日期',
  is_valid: '有效状态',
  rank: '排名',
  cores: '核心数量',
  rmax: '实际最大算力',
  rpeak: '理论算力',
  power: '功耗',
  manufacturer: '厂商',
  site: '站点',
  processor: '处理器',
  interconnect: '互连',
  installation_year: '安装年份',
  nmax: 'Nmax',
  hpcg: 'HPCG',
  power_measurement_level: '功耗测量等级',
  operating_system: '操作系统',
  compiler: '编译器',
  math_library: '数学库',
  mpi: 'MPI',
  raw_country: '原始国家值',
  country_validation: '国家校验',
}

const DETAIL_BASE_FIELDS = [
  'source',
  'data_type',
  'source_id',
  'country',
  'city',
  'collected_at',
  'reference_date',
]

function formatFieldLabel(key: string) {
  if (DETAIL_FIELD_LABELS[key]) {
    return DETAIL_FIELD_LABELS[key]
  }

  return key
    .split('_')
    .filter(Boolean)
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join(' ')
}

function formatDetailValue(key: string, value: unknown) {
  if (value === null || value === undefined || value === '') {
    return '-'
  }

  if (key === 'collected_at' || key === 'reference_date') {
    const date = new Date(String(value))
    return Number.isNaN(date.getTime())
      ? String(value)
      : key === 'reference_date'
        ? date.toLocaleDateString('zh-CN')
        : date.toLocaleString('zh-CN')
  }

  if (typeof value === 'boolean') {
    return value ? '是' : '否'
  }

  if (typeof value === 'object') {
    return JSON.stringify(value, null, 2)
  }

  return String(value)
}

function NameMarquee({ text }: { text: string }) {
  const containerRef = useRef<HTMLSpanElement | null>(null)
  const textRef = useRef<HTMLSpanElement | null>(null)
  const [overflowing, setOverflowing] = useState(false)

  useLayoutEffect(() => {
    const updateOverflow = () => {
      const container = containerRef.current
      const content = textRef.current
      if (!container || !content) return
      setOverflowing(content.scrollWidth > container.clientWidth + 1)
    }

    updateOverflow()

    if (typeof ResizeObserver === 'undefined') {
      return undefined
    }

    const observer = new ResizeObserver(updateOverflow)
    if (containerRef.current) observer.observe(containerRef.current)
    if (textRef.current) observer.observe(textRef.current)

    return () => observer.disconnect()
  }, [text])

  return (
    <span
      ref={containerRef}
      className={`data-list-name-marquee${overflowing ? ' data-list-name-marquee--overflow' : ''}`}
    >
      <span ref={textRef} className="data-list-name-marquee__text">
        {text}
      </span>
    </span>
  )
}

function estimateTreemapRows(
  items: Array<{ colSpan: number; rowSpan: number }>,
  columns: number
): number {
  const occupancy: boolean[][] = []

  const ensureRow = (rowIndex: number) => {
    while (occupancy.length <= rowIndex) {
      occupancy.push(Array(columns).fill(false))
    }
  }

  for (const item of items) {
    let placed = false
    let rowIndex = 0

    while (!placed) {
      ensureRow(rowIndex)

      for (let columnIndex = 0; columnIndex <= columns - item.colSpan; columnIndex += 1) {
        let canPlace = true

        for (let rowOffset = 0; rowOffset < item.rowSpan; rowOffset += 1) {
          ensureRow(rowIndex + rowOffset)

          for (let columnOffset = 0; columnOffset < item.colSpan; columnOffset += 1) {
            if (occupancy[rowIndex + rowOffset][columnIndex + columnOffset]) {
              canPlace = false
              break
            }
          }

          if (!canPlace) break
        }

        if (!canPlace) continue

        for (let rowOffset = 0; rowOffset < item.rowSpan; rowOffset += 1) {
          for (let columnOffset = 0; columnOffset < item.colSpan; columnOffset += 1) {
            occupancy[rowIndex + rowOffset][columnIndex + columnOffset] = true
          }
        }

        placed = true
        break
      }

      rowIndex += 1
    }
  }

  return Math.max(occupancy.length, 1)
}

function DataList() {
  const screens = useBreakpoint()
  const isCompact = !screens.lg
  const topbarRef = useRef<HTMLDivElement | null>(null)
  const workspaceRef = useRef<HTMLDivElement | null>(null)
  const mainAreaRef = useRef<HTMLDivElement | null>(null)
  const rightColumnRef = useRef<HTMLDivElement | null>(null)
  const tableHeaderRef = useRef<HTMLDivElement | null>(null)
  const summaryBodyRef = useRef<HTMLDivElement | null>(null)
  const hasCustomLeftWidthRef = useRef(false)

  const [mainAreaWidth, setMainAreaWidth] = useState(0)
  const [mainAreaHeight, setMainAreaHeight] = useState(0)
  const [rightColumnHeight, setRightColumnHeight] = useState(0)
  const [tableHeaderHeight, setTableHeaderHeight] = useState(0)
  const [leftPanelWidth, setLeftPanelWidth] = useState(360)
  const [summaryBodyHeight, setSummaryBodyHeight] = useState(0)

  const [data, setData] = useState<CollectedData[]>([])
  const [loading, setLoading] = useState(false)
  const [summary, setSummary] = useState<Summary | null>(null)
  const [total, setTotal] = useState(0)
  const [page, setPage] = useState(1)
  const [pageSize, setPageSize] = useState(20)
  const [sourceFilter, setSourceFilter] = useState<string[]>([])
  const [typeFilter, setTypeFilter] = useState<string[]>([])
  const [searchText, setSearchText] = useState('')
  const [sources, setSources] = useState<string[]>([])
  const [types, setTypes] = useState<string[]>([])
  const [detailVisible, setDetailVisible] = useState(false)
  const [detailData, setDetailData] = useState<CollectedData | null>(null)
  const [detailLoading, setDetailLoading] = useState(false)

  useEffect(() => {
    const updateLayout = () => {
      setMainAreaWidth(mainAreaRef.current?.offsetWidth || 0)
      setMainAreaHeight(mainAreaRef.current?.offsetHeight || 0)
      setRightColumnHeight(rightColumnRef.current?.offsetHeight || 0)
      setTableHeaderHeight(tableHeaderRef.current?.offsetHeight || 0)
      setSummaryBodyHeight(summaryBodyRef.current?.offsetHeight || 0)
    }

    updateLayout()

    if (typeof ResizeObserver === 'undefined') {
      return undefined
    }

    const observer = new ResizeObserver(updateLayout)
    if (workspaceRef.current) observer.observe(workspaceRef.current)
    if (topbarRef.current) observer.observe(topbarRef.current)
    if (mainAreaRef.current) observer.observe(mainAreaRef.current)
    if (rightColumnRef.current) observer.observe(rightColumnRef.current)
    if (tableHeaderRef.current) observer.observe(tableHeaderRef.current)
    if (summaryBodyRef.current) observer.observe(summaryBodyRef.current)

    return () => observer.disconnect()
  }, [isCompact])

  useEffect(() => {
    if (isCompact || mainAreaWidth === 0) {
      return
    }

    const minLeft = 260
    const minRight = 360
    const maxLeft = Math.max(minLeft, mainAreaWidth - minRight - 12)
    const preferredLeft = Math.max(minLeft, Math.min(Math.round((mainAreaWidth - 12) / 4), maxLeft))

    setLeftPanelWidth((current) => {
      if (!hasCustomLeftWidthRef.current) {
        return preferredLeft
      }
      return Math.max(minLeft, Math.min(current, maxLeft))
    })
  }, [isCompact, mainAreaWidth])

  const beginHorizontalResize = (event: React.MouseEvent<HTMLDivElement>) => {
    if (isCompact) return
    event.preventDefault()
    hasCustomLeftWidthRef.current = true
    const startX = event.clientX
    const startWidth = leftPanelWidth
    const containerWidth = mainAreaRef.current?.offsetWidth || 0

    const onMove = (moveEvent: MouseEvent) => {
      const minLeft = 260
      const minRight = 360
      const maxLeft = Math.max(minLeft, containerWidth - minRight - 12)
      const nextWidth = startWidth + moveEvent.clientX - startX
      setLeftPanelWidth(Math.max(minLeft, Math.min(nextWidth, maxLeft)))
    }

    const onUp = () => {
      window.removeEventListener('mousemove', onMove)
      window.removeEventListener('mouseup', onUp)
    }

    window.addEventListener('mousemove', onMove)
    window.addEventListener('mouseup', onUp)
  }

  const fetchData = async () => {
    setLoading(true)
    try {
      const params = new URLSearchParams({
        page: page.toString(),
        page_size: pageSize.toString(),
      })
      if (sourceFilter.length > 0) params.append('source', sourceFilter.join(','))
      if (typeFilter.length > 0) params.append('data_type', typeFilter.join(','))
      if (searchText) params.append('search', searchText)

      const res = await axios.get(`/api/v1/collected?${params}`)
      setData(res.data.data)
      setTotal(res.data.total)
    } catch (error) {
      console.error('Failed to fetch data:', error)
    } finally {
      setLoading(false)
    }
  }

  const fetchSummary = async () => {
    try {
      const res = await axios.get('/api/v1/collected/summary')
      setSummary(res.data)
    } catch (error) {
      console.error('Failed to fetch summary:', error)
    }
  }

  const fetchFilters = async () => {
    try {
      const [sourcesRes, typesRes] = await Promise.all([
        axios.get('/api/v1/collected/sources'),
        axios.get('/api/v1/collected/types'),
      ])
      setSources(sourcesRes.data.sources || [])
      setTypes(typesRes.data.data_types || [])
    } catch (error) {
      console.error('Failed to fetch filters:', error)
    }
  }

  useEffect(() => {
    fetchSummary()
    fetchFilters()
  }, [])

  useEffect(() => {
    fetchData()
  }, [page, pageSize, sourceFilter, typeFilter])

  const handleSearch = () => {
    setPage(1)
    fetchData()
  }

  const handleReset = () => {
    setSourceFilter([])
    setTypeFilter([])
    setSearchText('')
    setPage(1)
    setTimeout(fetchData, 0)
  }

  const handleViewDetail = async (id: number) => {
    setDetailVisible(true)
    setDetailLoading(true)
    try {
      const res = await axios.get(`/api/v1/collected/${id}`)
      setDetailData(res.data)
    } catch (error) {
      console.error('Failed to fetch detail:', error)
    } finally {
      setDetailLoading(false)
    }
  }

  const getSourceIcon = (source: string) => {
    const iconMap: Record<string, React.ReactNode> = {
      top500: <CloudServerOutlined />,
      huggingface_models: <AppstoreOutlined />,
      huggingface_datasets: <DatabaseOutlined />,
      huggingface_spaces: <AppstoreOutlined />,
      telegeography_cables: <GlobalOutlined />,
      epoch_ai_gpu: <CloudServerOutlined />,
    }
    return iconMap[source] || <DatabaseOutlined />
  }

  const getSourceTagColor = (source: string) => {
    const colorMap: Record<string, string> = {
      top500: 'geekblue',
      huggingface_models: 'purple',
      huggingface_datasets: 'cyan',
      huggingface_spaces: 'magenta',
      telegeography_cables: 'green',
      epoch_ai_gpu: 'volcano',
    }
    return colorMap[source] || 'blue'
  }

  const getDataTypeTagColor = (dataType: string) => {
    const colorMap: Record<string, string> = {
      supercomputer: 'geekblue',
      model: 'purple',
      dataset: 'cyan',
      space: 'magenta',
      submarine_cable: 'green',
      cable_landing_point: 'lime',
      cable_landing_relation: 'gold',
      gpu_cluster: 'volcano',
      generic: 'default',
    }
    return colorMap[dataType] || 'default'
  }

  const renderFilterTag = (tagProps: CustomTagProps, getColor: (value: string) => string) => {
    const { label, value, closable, onClose } = tagProps
    return (
      <Tag
        color={getColor(String(value))}
        closable={closable}
        onClose={onClose}
        style={{ marginInlineEnd: 4 }}
      >
        {label}
      </Tag>
    )
  }

  const getTypeColor = (type: string) => {
    const colors: Record<string, string> = {
      supercomputer: 'red',
      model: 'blue',
      dataset: 'green',
      space: 'purple',
      submarine_cable: 'cyan',
      gpu_cluster: 'orange',
      ixp: 'magenta',
      network: 'gold',
      facility: 'lime',
    }
    return colors[type] || 'default'
  }

  const activeFilterCount = useMemo(
    () => [sourceFilter.length > 0, typeFilter.length > 0, searchText.trim()].filter(Boolean).length,
    [sourceFilter, typeFilter, searchText]
  )

  const summaryItems = useMemo(() => {
    const items = [
      { key: 'total', label: '总记录', value: summary?.total_records || 0, icon: <DatabaseOutlined /> },
      { key: 'result', label: '筛选结果', value: total, icon: <SearchOutlined /> },
      { key: 'filters', label: '启用筛选', value: activeFilterCount, icon: <FilterOutlined /> },
      { key: 'sources', label: '数据源数', value: sources.length, icon: <DatabaseOutlined /> },
    ]

    for (const item of (summary?.source_totals || []).slice(0, isCompact ? 3 : 5)) {
      items.push({
        key: item.source,
        label: item.source,
        value: item.count,
        icon: getSourceIcon(item.source),
      })
    }

    return items
  }, [summary, total, activeFilterCount, isCompact, sources.length])

  const treemapColumns = useMemo(() => {
    if (isCompact) return 1
    if (leftPanelWidth < 360) return 2
    if (leftPanelWidth < 520) return 3
    return 4
  }, [isCompact, leftPanelWidth])

  const treemapItems = useMemo(() => {
    const palette = ['ocean', 'sky', 'mint', 'amber', 'rose', 'violet', 'slate']
    const maxValue = Math.max(...summaryItems.map((item) => item.value), 1)
    const allowFeaturedTile = !isCompact && treemapColumns > 1 && summaryItems.length > 2
    const allowSecondaryTallTiles = !isCompact && leftPanelWidth >= 520

    return summaryItems.map((item, index) => {
      const ratio = item.value / maxValue
      let colSpan = 1
      let rowSpan = 1

      if (allowFeaturedTile && index === 0) {
        colSpan = Math.min(2, treemapColumns)
        rowSpan = 2
      } else if (allowSecondaryTallTiles && ratio >= 0.7) {
        colSpan = Math.min(2, treemapColumns)
        rowSpan = 2
      } else if (allowSecondaryTallTiles && ratio >= 0.35) {
        rowSpan = 2
      }

      return {
        ...item,
        colSpan,
        rowSpan,
        tone: palette[index % palette.length],
      }
    })
  }, [summaryItems, isCompact, leftPanelWidth, treemapColumns])

  const treemapRows = useMemo(
    () => estimateTreemapRows(treemapItems, treemapColumns),
    [treemapColumns, treemapItems]
  )

  const treemapGap = isCompact ? 8 : 10
  const treemapMinRowHeight = isCompact ? 88 : 68
  const treemapTargetRowHeight = isCompact ? 88 : leftPanelWidth < 360 ? 44 : leftPanelWidth < 520 ? 48 : 56
  const treemapAvailableHeight = Math.max(summaryBodyHeight, 0)
  const treemapAutoRowHeight = treemapRows > 0
    ? Math.floor((treemapAvailableHeight - Math.max(0, treemapRows - 1) * treemapGap) / treemapRows)
    : treemapTargetRowHeight
  const treemapRowHeight = Math.max(
    treemapMinRowHeight,
    Math.min(treemapTargetRowHeight, treemapAutoRowHeight || treemapTargetRowHeight)
  )
  const treemapContentHeight = treemapRows * treemapRowHeight + Math.max(0, treemapRows - 1) * treemapGap
  const treemapTilePadding = treemapRowHeight <= 72 ? 8 : treemapRowHeight <= 84 ? 10 : 12
  const treemapLabelSize = treemapRowHeight <= 72 ? 10 : treemapRowHeight <= 84 ? 11 : 12
  const treemapValueSize = treemapRowHeight <= 72 ? 13 : treemapRowHeight <= 84 ? 15 : 16

  const pageHeight = '100%'
  const desktopTableHeight = rightColumnHeight - tableHeaderHeight - 132
  const compactTableHeight = mainAreaHeight - tableHeaderHeight - 156
  const tableHeight = Math.max(180, isCompact ? compactTableHeight : desktopTableHeight)

  const detailBaseItems = useMemo(() => {
    if (!detailData) return []

    return DETAIL_BASE_FIELDS.map((key) => ({
      key,
      label: formatFieldLabel(key),
      value: formatDetailValue(key, detailData[key as keyof CollectedData]),
    })).filter((item) => item.value !== '-')
  }, [detailData])

  const detailMetadataItems = useMemo(() => {
    if (!detailData?.metadata) return []

    return Object.entries(detailData.metadata)
      .filter(([key]) => key !== '_detail_url')
      .map(([key, value]) => ({
        key,
        label: formatFieldLabel(key),
        value: formatDetailValue(key, value),
        isBlock: typeof value === 'object' && value !== null,
      }))
  }, [detailData])

  const splitLayoutStyle = isCompact
    ? undefined
    : { gridTemplateColumns: `${leftPanelWidth}px 12px minmax(0, 1fr)` }

  const columns: ColumnsType<CollectedData> = [
    {
      title: '名称',
      dataIndex: 'name',
      key: 'name',
      width: 320,
      ellipsis: true,
      render: (name: string, record: CollectedData) => (
        <Tooltip title={name}>
          <Button type="link" className="data-list-name-link" onClick={() => handleViewDetail(record.id)}>
            <NameMarquee text={name} />
          </Button>
        </Tooltip>
      ),
    },
    {
      title: '数据源',
      dataIndex: 'source',
      key: 'source',
      minWidth: 140,
      render: (value: string) => (
        value ? (
          <div className="data-list-tag-cell">
            <Tag color={getSourceTagColor(value)} style={{ marginInlineEnd: 0 }}>
              {value}
            </Tag>
          </div>
        ) : '-'
      ),
    },
    {
      title: '数据类型',
      dataIndex: 'data_type',
      key: 'data_type',
      minWidth: 140,
      render: (value: string) => (
        value ? (
          <div className="data-list-tag-cell">
            <Tag color={getDataTypeTagColor(value)} style={{ marginInlineEnd: 0 }}>
              {value}
            </Tag>
          </div>
        ) : '-'
      ),
    },
    {
      title: '采集时间',
      dataIndex: 'collected_at',
      key: 'collected_at',
      width: 180,
      render: (time: string) => new Date(time).toLocaleString('zh-CN'),
    },
    {
      title: '参考日期',
      dataIndex: 'reference_date',
      key: 'reference_date',
      width: 120,
      render: (time: string | null) => (time ? new Date(time).toLocaleDateString('zh-CN') : '-'),
    },
    {
      title: '操作',
      key: 'action',
      width: 96,
      render: (_: unknown, record: CollectedData) => (
        <Button type="link" icon={<EyeOutlined />} onClick={() => handleViewDetail(record.id)}>
          详情
        </Button>
      ),
    },
  ]

  return (
    <AppLayout>
      <div ref={workspaceRef} className="data-list-workspace" style={{ height: pageHeight }}>
        <div ref={topbarRef} className="data-list-topbar">
          <div>
            <Title level={4} style={{ margin: 0 }}>采集数据</Title>
          </div>
          <Space size={8} wrap>
            <Tag color="blue" style={{ marginInlineEnd: 0 }}>
              结果 {total.toLocaleString()} 条
            </Tag>
            <Tag color="default" style={{ marginInlineEnd: 0 }}>
              筛选 {activeFilterCount} 项
            </Tag>
          </Space>
        </div>

        <div ref={mainAreaRef} className="data-list-controls-shell">
          <div className="data-list-split-layout" style={splitLayoutStyle}>
            <Card
              className="data-list-summary-card data-list-summary-card--panel"
              title="数据概览"
              size="small"
              styles={{ body: { padding: isCompact ? 12 : 16 } }}
            >
              <div ref={summaryBodyRef} className="data-list-summary-card-inner">
              <div
                className="data-list-summary-treemap"
                style={{
                  gridTemplateColumns: `repeat(${treemapColumns}, minmax(0, 1fr))`,
                  gridAutoRows: `${treemapRowHeight}px`,
                  gap: treemapGap,
                  minHeight: treemapAvailableHeight > 0 ? Math.min(treemapContentHeight, treemapAvailableHeight) : undefined,
                  height: treemapContentHeight,
                  ['--data-list-treemap-tile-padding' as '--data-list-treemap-tile-padding']: `${treemapTilePadding}px`,
                  ['--data-list-treemap-label-size' as '--data-list-treemap-label-size']: `${treemapLabelSize}px`,
                  ['--data-list-treemap-value-size' as '--data-list-treemap-value-size']: `${treemapValueSize}px`,
                } as CSSProperties}
              >
                {treemapItems.map((item) => (
                  <div
                    key={item.key}
                    className={`data-list-treemap-tile data-list-treemap-tile--${item.tone}`}
                    style={{
                      gridColumn: `span ${item.colSpan}`,
                      gridRow: `span ${item.rowSpan}`,
                    }}
                  >
                    <div className="data-list-treemap-head">
                      <span className="data-list-summary-tile-icon">{item.icon}</span>
                      <Text className="data-list-treemap-label">{item.label}</Text>
                    </div>
                    <div className="data-list-treemap-body">
                      <Text strong className="data-list-summary-tile-value">
                        {item.value.toLocaleString()}
                      </Text>
                    </div>
                  </div>
                ))}
              </div>
              </div>
            </Card>

            {!isCompact && (
              <div
                className="data-list-resize-handle data-list-resize-handle--vertical"
                onMouseDown={beginHorizontalResize}
                role="separator"
                aria-orientation="vertical"
                aria-label="调整左右分栏宽度"
              />
            )}

            <div ref={rightColumnRef} className="data-list-right-column">
              <Card className="data-list-table-shell" styles={{ body: { padding: 0 } }}>
                <div ref={tableHeaderRef} className="data-list-table-header data-list-table-header--with-filters">
                  <div className="data-list-table-header-main">
                    <Space size={8} wrap>
                      <Text strong>数据列表</Text>
                      <Text type="secondary">共 {total.toLocaleString()} 条结果</Text>
                    </Space>
                    <Space size={8} wrap>
                      <Button size="small" onClick={handleReset}>清空</Button>
                      <Button size="small" icon={<ReloadOutlined />} onClick={fetchData}>刷新</Button>
                      <Button size="small" type="primary" icon={<SearchOutlined />} onClick={handleSearch}>
                        搜索
                      </Button>
                    </Space>
                  </div>
                  <div className="data-list-filter-grid data-list-filter-grid--balanced data-list-filter-grid--header">
                    <Select
                      size="middle"
                      placeholder="数据源"
                      mode="multiple"
                      allowClear
                      value={sourceFilter}
                      onChange={(value) => {
                        setSourceFilter(value)
                        setPage(1)
                      }}
                      options={sources.map((source) => ({ label: source, value: source }))}
                      tagRender={(tagProps) => renderFilterTag(tagProps, getSourceTagColor)}
                      style={{ width: '100%' }}
                      className="data-list-filter-select"
                    />
                    <Select
                      size="middle"
                      placeholder="数据类型"
                      mode="multiple"
                      allowClear
                      value={typeFilter}
                      onChange={(value) => {
                        setTypeFilter(value)
                        setPage(1)
                      }}
                      options={types.map((type) => ({ label: type, value: type }))}
                      tagRender={(tagProps) => renderFilterTag(tagProps, getDataTypeTagColor)}
                      style={{ width: '100%' }}
                      className="data-list-filter-select"
                    />
                    <Input
                      size="middle"
                      placeholder="搜索名称、描述、元数据等"
                      value={searchText}
                      onChange={(event) => setSearchText(event.target.value)}
                      onPressEnter={handleSearch}
                    />
                  </div>
                </div>
                <div className="table-scroll-region data-list-table-region" style={{ padding: isCompact ? 10 : 12 }}>
                  <Table
                    columns={columns}
                    dataSource={data}
                    rowKey="id"
                    loading={loading}
                    scroll={{ x: 'max-content', y: tableHeight }}
                    tableLayout="auto"
                    size={isCompact ? 'small' : 'middle'}
                    pagination={{
                      current: page,
                      pageSize,
                      total,
                      onChange: (nextPage, nextPageSize) => {
                        setPage(nextPage)
                        setPageSize(nextPageSize)
                      },
                      showSizeChanger: true,
                      showTotal: (count) => `共 ${count} 条`,
                    }}
                  />
                </div>
              </Card>
            </div>
          </div>
        </div>
      </div>

      <Modal
        title="数据详情"
        open={detailVisible}
        onCancel={() => setDetailVisible(false)}
        footer={[
          <Button key="close" onClick={() => setDetailVisible(false)}>
            关闭
          </Button>,
        ]}
        width={880}
      >
        {detailLoading ? (
          <div style={{ textAlign: 'center', padding: 40 }}>
            <Spin size="large" />
          </div>
        ) : detailData ? (
          <div className="data-list-detail-modal">
            <section className="data-list-detail-section">
              <div className="data-list-detail-hero">
                <Text className="data-list-detail-hero__label">名称</Text>
                <Title level={5} className="data-list-detail-hero__title">
                  {detailData.name || '-'}
                </Title>
              </div>
            </section>

            {detailBaseItems.length > 0 && (
              <section className="data-list-detail-section">
                <Text strong className="data-list-detail-section__title">基础信息</Text>
                <div className="data-list-detail-grid">
                  {detailBaseItems.map((item) => (
                    <div key={item.key} className="data-list-detail-cell">
                      <Text className="data-list-detail-cell__label">{item.label}</Text>
                      <div className="data-list-detail-cell__value">{item.value}</div>
                    </div>
                  ))}
                </div>
              </section>
            )}

            {detailMetadataItems.length > 0 && (
              <section className="data-list-detail-section">
                <Text strong className="data-list-detail-section__title">扩展字段</Text>
                <div className="data-list-detail-grid">
                  {detailMetadataItems.map((item) => (
                    <div
                      key={item.key}
                      className={`data-list-detail-cell${item.isBlock ? ' data-list-detail-cell--block' : ''}`}
                    >
                      <Text className="data-list-detail-cell__label">{item.label}</Text>
                      {item.isBlock ? (
                        <pre className="data-list-detail-code">{item.value}</pre>
                      ) : (
                        <div className="data-list-detail-cell__value">{item.value}</div>
                      )}
                    </div>
                  ))}
                </div>
              </section>
            )}

            <section className="data-list-detail-section">
              <Text strong className="data-list-detail-section__title">原始元数据</Text>
              <pre className="data-list-detail-code data-list-detail-code--raw">
                {JSON.stringify(detailData.metadata || {}, null, 2)}
              </pre>
            </section>
          </div>
        ) : (
          <Empty description="暂无数据" />
        )}
      </Modal>
    </AppLayout>
  )
}

export default DataList
