import KFEmpty, { EmptyType } from '@/components/KFEmpty';
import KFIcon from '@/components/KFIcon';
import { CommonTabKeys } from '@/enums';
import AddModelModal from '@/pages/Dataset/components/AddModelModal';
import { openAntdModal } from '@/utils/modal';
import { to } from '@/utils/promise';
import { modalConfirm } from '@/utils/ui';
import { useNavigate } from '@umijs/max';
import { App, Button, Input, Pagination, PaginationProps } from 'antd';
import { pick } from 'lodash';
import { Ref, forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react';
import { CategoryData, ResourceData, ResourceType, resourceConfig } from '../../config';
import AddDatasetModal from '../AddDatasetModal';
import ResourceItem from '../ResourceItem';
import styles from './index.less';

export type ResourceListRef = {
  reset: () => void;
};

type ResourceListProps = {
  resourceType: ResourceType;
  dataType?: string;
  dataTag?: string;
  isPublic: boolean;
  typeList: CategoryData[];
  tagList: CategoryData[];
  initialSearchText?: string;
  initialPagination?: PaginationProps;
  setCacheState: (state?: any) => void;
};

function ResourceList(
  {
    resourceType,
    dataType,
    dataTag,
    typeList,
    tagList,
    isPublic,
    initialSearchText,
    initialPagination,
    setCacheState,
  }: ResourceListProps,
  ref: Ref<ResourceListRef>,
) {
  const navigate = useNavigate();
  const [dataList, setDataList] = useState<ResourceData[] | undefined>(undefined);
  const [total, setTotal] = useState(0);
  const [pagination, setPagination] = useState<PaginationProps>(
    initialPagination ?? {
      current: 1,
      pageSize: 20,
    },
  );
  const [searchText, setSearchText] = useState(initialSearchText);
  const [inputText, setInputText] = useState(initialSearchText);
  const { message } = App.useApp();
  const config = resourceConfig[resourceType];

  // 获取数据请求
  const getDataList = useCallback(async () => {
    const params: Record<string, any> = {
      page: pagination.current! - 1,
      size: pagination.pageSize,
      is_public: isPublic,
      [config.typeParamKey]: dataType,
      [config.tagParamKey]: dataTag,
      name: searchText || undefined,
    };
    const request = config.getList;
    const [res] = await to(request(params));
    if (res && res.data && res.data.content) {
      setDataList(res.data.content);
      setTotal(res.data.totalElements);
    } else {
      setDataList([]);
      setTotal(0);
    }
  }, [dataType, dataTag, pagination, searchText, isPublic, config]);

  useEffect(() => {
    getDataList();
  }, [getDataList]);

  useImperativeHandle(
    ref,
    () => {
      return {
        reset: () => {
          setPagination({
            current: 1,
            pageSize: 20,
          });
          setSearchText('');
          setInputText('');
          setDataList(undefined);
          setTotal(0);
        },
      };
    },
    [],
  );

  // 删除请求
  const deleteRecord = async (params: { owner: string; identifier: string; repo_id?: number }) => {
    const request = config.deleteRecord;
    const [res] = await to(request(params));
    if (res) {
      getDataList();
      message.success('删除成功');
    }
  };

  // 搜索
  const handleSearch = (value: string) => {
    setSearchText(value);
    setPagination((prev) => ({
      ...prev,
      current: 1,
    }));
  };

  // 删除
  const handleRemove = (record: ResourceData) => {
    modalConfirm({
      title: config.deleteModalTitle,
      onOk: () => {
        deleteRecord(pick(record, ['owner', 'identifier', 'id', 'is_public']));
      },
    });
  };

  // 跳转
  const handleClick = (record: ResourceData) => {
    setCacheState({
      activeTab: isPublic ? CommonTabKeys.Public : CommonTabKeys.Private,
      pagination,
      searchText,
      activeType: dataType,
      activeTag: dataTag,
    });
    const prefix = config.prefix;
    navigate(
      `/dataset/${prefix}/info/${record.id}?name=${record.name}&owner=${record.owner}&identifier=${record.identifier}&is_public=${record.is_public}`,
    );
  };

  // 分页切换
  const handlePageChange: PaginationProps['onChange'] = (page, pageSize) => {
    setPagination({
      current: page,
      pageSize: pageSize,
    });
  };

  // 新建弹框
  const showModal = () => {
    const Modal = resourceType === ResourceType.Dataset ? AddDatasetModal : AddModelModal;
    const { close } = openAntdModal(Modal, {
      typeList: typeList,
      tagList: tagList,
      onOk: () => {
        getDataList();
        close();
      },
    });
  };

  return (
    <div className={styles['resource-list']}>
      <div className={styles['resource-list__header']}>
        <span>数据总数：{total} 个</span>
        <div>
          <Input.Search
            placeholder={`按${config.name}名称筛选`}
            allowClear
            onSearch={handleSearch}
            style={{
              width: 300,
            }}
            onChange={(e) => setInputText(e.target.value)}
            value={inputText}
          />
          {!isPublic && (
            <Button
              type="default"
              style={{ marginLeft: '20px' }}
              onClick={showModal}
              icon={<KFIcon type="icon-xinjian2" />}
            >
              {config.addBtnTitle}
            </Button>
          )}
        </div>
      </div>
      {dataList && dataList.length > 0 && (
        <>
          <div className={styles['resource-list__content']}>
            {dataList?.map((item) => (
              <ResourceItem
                item={item}
                key={item.id}
                isPublic={isPublic}
                onRemove={handleRemove}
                onClick={handleClick}
              ></ResourceItem>
            ))}
          </div>
          <Pagination
            align="end"
            total={total}
            showSizeChanger
            defaultPageSize={20}
            pageSizeOptions={[20, 40, 60, 80, 100]}
            showQuickJumper
            onChange={handlePageChange}
            {...pagination}
          />
        </>
      )}
      {dataList && dataList.length === 0 && (
        <KFEmpty
          className={styles['resource-list__empty']}
          type={EmptyType.NoData}
          title="暂无数据"
          content={'很抱歉，没有搜索到您想要的内容\n建议刷新试试'}
          hasFooter={true}
          onButtonClick={getDataList}
        />
      )}
    </div>
  );
}

export default forwardRef(ResourceList);
