import type { TableColumnsType, TableProps } from "antd";

import { DeleteOutlined, EditOutlined } from "@ant-design/icons";
import { Button, Popconfirm, Space, Table, Tag } from "antd";
import { useMemo } from "react";

import type { Model, ModelListResponse, ProviderOption } from "../../../../shared/api";

import { formatDatetime } from "../../../shared/utils/format";

interface ModelTableProps {
  data: ModelListResponse | undefined;
  loading: boolean;
  onChange: (
    pagination: { current?: number; pageSize?: number },
    sorter: { columnKey?: string; field?: string | string[]; order?: string },
  ) => void;
  onDelete: (id: string) => Promise<void>;
  onEdit: (model: Model) => void;
  page: number;
  pageSize: number;
  providers: ProviderOption[];
  sortBy?: string;
  sortOrder?: string;
}

const CAPABILITY_LABELS: Record<string, string> = {
  "audio-generation": "音频生成",
  "audio-recognition": "音频识别",
  "image-generation": "图片生成",
  "image-recognition": "图片识别",
  reasoning: "推理",
  text: "文本",
  "video-generation": "视频生成",
  "video-recognition": "视频识别",
};

export function ModelTable({
  data,
  loading,
  onChange,
  onDelete,
  onEdit,
  page,
  pageSize,
  providers,
  sortBy,
  sortOrder,
}: ModelTableProps) {
  const columns = useMemo<TableColumnsType<Model>>(
    () => [
      {
        dataIndex: "name",
        ellipsis: true,
        sorter: true,
        sortOrder:
          sortBy === "name" ? (sortOrder === "asc" ? "ascend" : sortOrder === "desc" ? "descend" : null) : null,
        title: "名称",
        width: 180,
      },
      {
        dataIndex: "providerId",
        ellipsis: true,
        render: (_value: unknown, record: Model) => getProviderName(record.providerId, providers),
        title: "供应商",
        width: 120,
      },
      {
        dataIndex: "capabilities",
        render: (value: string[]) =>
          value.length > 0 ? (
            <Space size={[4, 4]} wrap>
              {value.map((c) => (
                <Tag key={c}>{CAPABILITY_LABELS[c] ?? c}</Tag>
              ))}
            </Space>
          ) : null,
        title: "能力",
      },
      {
        align: "center",
        dataIndex: "createdAt",
        render: (_value: unknown, record: Model) => formatDatetime(record.createdAt),
        sorter: true,
        sortOrder:
          sortBy === "createdAt" ? (sortOrder === "asc" ? "ascend" : sortOrder === "desc" ? "descend" : null) : null,
        title: "创建时间",
        width: 180,
      },
      {
        dataIndex: "op",
        render: (_value: unknown, record: Model) => (
          <Space size="small">
            <Button icon={<EditOutlined />} onClick={() => onEdit(record)} size="small" type="link">
              编辑
            </Button>
            <Popconfirm
              description="此操作不可恢复。"
              onConfirm={() => void onDelete(record.id)}
              title="确认删除此模型？"
            >
              <Button danger icon={<DeleteOutlined />} size="small" type="link">
                删除
              </Button>
            </Popconfirm>
          </Space>
        ),
        title: "操作",
        width: 180,
      },
    ],
    [onEdit, onDelete, providers, sortBy, sortOrder],
  );

  const handleTableChange: TableProps<Model>["onChange"] = (pagination, _filters, sorter) => {
    const sortInfo =
      sorter && typeof sorter === "object" && "columnKey" in sorter
        ? (sorter as { columnKey?: string; field?: string | string[]; order?: string })
        : {};
    onChange({ current: pagination.current, pageSize: pagination.pageSize }, sortInfo);
  };

  return (
    <Table
      columns={columns}
      dataSource={data?.items ?? []}
      loading={loading}
      locale={{ emptyText: "暂无模型数据" }}
      onChange={handleTableChange}
      pagination={{
        current: page,
        hideOnSinglePage: false,
        pageSize,
        showSizeChanger: true,
        showTotal: (total) => `共 ${total} 条`,
        total: data?.total ?? 0,
      }}
      rowKey="id"
    />
  );
}

function getProviderName(providerId: string, providers: ProviderOption[]): string {
  return providers.find((p) => p.id === providerId)?.name ?? providerId;
}
