import {
  DeleteOutlined,
  DownloadOutlined,
  FileOutlined,
  FolderOutlined,
  ReloadOutlined,
  UploadOutlined,
} from '@ant-design/icons'
import { Button, Empty, Grid, Popconfirm, Space, Table, Tag, Tooltip } from 'antd'
import type { ColumnsType } from 'antd/es/table'
import { useMemo } from 'react'
import type { FileCategory, FileRecord } from '../../api'
import { colors, fontSizes } from '../../tokens'
import { formatDateTime } from '../../utils/date'
import { extensionColor, formatFileSize } from '../../utils/fileFormat'
import { getCategoryPath } from '../../utils/fileTree'

interface FileTableProps {
  files: FileRecord[]
  categories: FileCategory[]
  loading: boolean
  categoryName: string
  onRefresh: () => void
  onOpenUpload: () => void
  onDownload: (record: FileRecord) => Promise<void>
  onDelete: (id: string) => Promise<void>
}

export default function FileTable({
  files,
  categories,
  loading,
  categoryName,
  onRefresh,
  onOpenUpload,
  onDownload,
  onDelete,
}: FileTableProps) {
  const screens = Grid.useBreakpoint()
  const totalSize = useMemo(() => files.reduce((sum, file) => sum + file.file_size, 0), [files])
  const extensionCounts = useMemo(() => files.reduce<Record<string, number>>((counts, file) => {
    counts[file.file_ext] = (counts[file.file_ext] || 0) + 1
    return counts
  }, {}), [files])

  const renderLocation = (record: FileRecord, mobile = false) => {
    const categoryPath = record.category_id
      ? getCategoryPath(categories, record.category_id)
      : []
    const categoryLabel = categoryPath.length > 0 ? categoryPath.join(' / ') : '未分类'

    return (
      <div className={`files-location-cell${mobile ? ' files-location-mobile' : ''}`}>
        <div className="files-category-path" title={categoryLabel}>
          <FolderOutlined />
          <span>{categoryLabel}</span>
        </div>
        <code title={record.storage_directory}>{record.storage_directory}</code>
      </div>
    )
  }

  const columns: ColumnsType<FileRecord> = [
    {
      title: '文件名',
      dataIndex: 'original_name',
      key: 'name',
      ellipsis: true,
      render: (name: string, record) => (
        <div className="files-name-stack">
          <div className="files-name-row">
            <FileOutlined style={{ color: extensionColor(record.file_ext), fontSize: 16 }} />
            <span className="files-name-cell">{name}</span>
          </div>
          {renderLocation(record, true)}
        </div>
      ),
    },
    {
      title: '文件位置',
      key: 'location',
      width: 260,
      responsive: ['md'],
      render: (_, record) => renderLocation(record),
    },
    {
      title: '大小',
      dataIndex: 'file_size',
      key: 'size',
      width: 100,
      responsive: ['sm'],
      render: (size: number) => (
        <span style={{ fontSize: fontSizes.body, color: colors.textSecondary }}>
          {formatFileSize(size)}
        </span>
      ),
    },
    {
      title: '类型',
      dataIndex: 'file_ext',
      key: 'type',
      width: 90,
      render: (extension: string) => (
        <Tag color={extensionColor(extension)} style={{ margin: 0, fontWeight: 600, fontSize: 11 }}>
          {extension.toUpperCase()}
        </Tag>
      ),
    },
    {
      title: '上传时间',
      dataIndex: 'created_at',
      key: 'created_at',
      width: 170,
      responsive: ['md'],
      render: (time: string | null) => (
        <span style={{ fontSize: fontSizes.body, color: colors.textSecondary }}>
          {time ? formatDateTime(time) : '-'}
        </span>
      ),
    },
    {
      title: '操作',
      key: 'action',
      width: 100,
      fixed: 'right',
      render: (_, record) => (
        <Space size={0}>
          <Tooltip title="下载">
            <Button
              size="small"
              type="text"
              aria-label={`下载${record.original_name}`}
              icon={<DownloadOutlined />}
              onClick={() => void onDownload(record)}
            />
          </Tooltip>
          <Popconfirm title="确认删除此文件？" onConfirm={() => onDelete(record.id)}>
            <Tooltip title="删除">
              <Button
                size="small"
                type="text"
                danger
                aria-label={`删除${record.original_name}`}
                icon={<DeleteOutlined />}
              />
            </Tooltip>
          </Popconfirm>
        </Space>
      ),
    },
  ]

  const topExtensions = Object.entries(extensionCounts)
    .sort((left, right) => right[1] - left[1])
    .slice(0, 5)

  return (
    <section className="files-list-panel">
      <div className="files-list-header">
        <div className="files-current-category">
          <FolderOutlined style={{ color: colors.primary, fontSize: 18 }} />
          <span>{categoryName}</span>
        </div>
        <span className="files-stat">{files.length} 个文件</span>
        <span className="files-stat">{formatFileSize(totalSize)}</span>
        <Space size={4} wrap className="files-extension-stats">
          {topExtensions.map(([extension, count]) => (
            <Tag key={extension} color={extensionColor(extension)} style={{ margin: 0, fontSize: 11 }}>
              {extension.toUpperCase()} {count}
            </Tag>
          ))}
          {Object.keys(extensionCounts).length > 5 && (
            <span style={{ fontSize: 11, color: colors.textMuted }}>
              +{Object.keys(extensionCounts).length - 5} 种
            </span>
          )}
        </Space>
        <div className="files-list-actions">
          <Tooltip title="刷新文件列表">
            <Button icon={<ReloadOutlined />} aria-label="刷新文件列表" onClick={onRefresh} />
          </Tooltip>
          <Button type="primary" icon={<UploadOutlined />} onClick={onOpenUpload}>
            上传文件
          </Button>
        </div>
      </div>
      <div className="files-table-scroll">
        <Table<FileRecord>
          dataSource={files}
          columns={columns}
          rowKey="id"
          loading={loading}
          scroll={screens.md ? { x: 900 } : undefined}
          pagination={files.length > 20 ? {
            pageSize: 20,
            showTotal: (total) => `共 ${total} 个文件`,
          } : false}
          locale={{
            emptyText: <Empty description="暂无文件" image={Empty.PRESENTED_IMAGE_SIMPLE} />,
          }}
        />
      </div>
    </section>
  )
}
