import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';
import omit from 'lodash/omit';
import { SwapOutlined } from '@ant-design/icons';
import classNames from 'classnames';
import kebabCase from 'lodash.kebabcase';
import { useUrlSearchParams } from 'use-url-search-params';
import useLocalStorage from 'react-use/lib/useLocalStorage';
import useMedia from 'react-use/lib/useMedia';
import useUpdateEffect from 'react-use/lib/useUpdateEffect';
import useDebounce from 'react-use/lib/useDebounce';
import { useRect } from '@reach/rect';
import Table from '../table';
import {
  ApolloTableActionType,
  ApolloTableProps,
  ApolloTableRowSelection,
  OrderDirection,
  SelectedView,
  Variables,
} from './interfaces';
import withRenderByValueType from './utils/withRenderByValueType';
import Filters, { AppliedFilterInterface } from '../filters';
import { renderSearch } from './utils/renderSearch';
import { generateLabel } from './utils/generateLabel';
import { Card } from '../card';
import Popover from '../popover';
import Button from '../button';
import Radio from '../radio';
import { ConfigContext } from '../config-provider';
import { findColumn } from './utils/findColumn';
import SimplePagination from '../simple-pagination';
import { useActionType } from './hooks/useActionType';
import defaultLocale from '../locale/en_US';
import withCopyableAndEllipsis from './utils/withCopyableAndEllipsis';
import useMountMergeState from './utils/useMountMergeState';
import { useColumnSettingsStorage } from './hooks/useColumnSettingsStorage';
import { BatchActions } from './components/BatchActions';
import { filterSearchToComponent } from './utils/filterSearchToComponent';
import { ColumnsSetting } from './components/ColumnsSetting';
import withColumnSettings from './utils/withColumnSettings';
import withHidden from './utils/withHidden';
import useActiveKey from './hooks/useActiveKey';
import { SelectedViewTabs } from './components/SelectedViewTabs';
import { SelectedViewButton } from './components/SelectedViewButton';
import { filterValuesToSearch } from './utils/filterValuesToSearch';
import usePopState from './hooks/usePopState';
import Select from '../select';
import { generateQuery } from './utils/generateQuery';
import { useLayoutHeaderHeight } from '../frame/useLayoutHeaderHeight';

export const ApolloTable = <T extends {}>({
  id,
  syncToUrl,
  actionRef: propsActionRef,
  cardProps,
  columns = [],
  search,
  options = { setting: true },
  pageInfo,
  pagination,
  request,
  debounceTime = 300,
  tableAlertRender,
  rowSelection: propsRowSelection,
  components,
  dataSource,
  loading,
  sticky: propsSticky,
  ...props
}: ApolloTableProps<T>) => {
  const {
    getPrefixCls,
    locale: { ApolloTable: locale } = { ApolloTable: defaultLocale.ApolloTable },
  } = React.useContext(ConfigContext);
  const [layoutHeaderHeight] = useLayoutHeaderHeight();

  /** 计算 Card 宽度 */
  const ref = useRef<HTMLDivElement>(null);

  // 用来触发查询的
  const [depend, triggerReload] = useReducer(x => x + 1, 0);
  const isMobile = useMedia('(max-width: 458px)');
  const [before, setBefore] = useState<string>('');
  const [after, setAfter] = useState('');
  // 是否是页面载入第一次触发 handleChange
  const isChangeFirst = useRef(true);
  // 是否获取服务端视图结束
  const isSelectedViewsGetEnd = useRef(false);
  // 当前是否是全选模式
  const [isSelectedAll, setIsSelectedAll] = useState(false);

  const [columnSettings, setColumnSettings] = useColumnSettingsStorage(id, columns);

  const [searchParams, setSearchParams] = useUrlSearchParams({}, {});

  const [localValue, setLocalValue] = useLocalStorage<SelectedView[]>(
    `apollo-table-selected-views-saved:${id}`,
  );

  const [serverSelectedViews, setServerSelectedViews] = useState<SelectedView[]>([]);

  // 保存的视图，本地或服务端保存的
  const [savedSelectedViews, setSavedSelectedViews] = useMemo(() => {
    if (search && search.selectedViews) {
      if (search.selectedViews.store) {
        return [serverSelectedViews, setServerSelectedViews];
      }
      return [localValue || [], setLocalValue];
    }
    return [
      [],
      () => {
        //
      },
    ];
  }, [localValue, search, serverSelectedViews, setLocalValue]);

  // 配置的加上保存的视图
  const allSelectedViews = useMemo(() => {
    if (search && search.selectedViews?.config) {
      return search.selectedViews?.config.concat(savedSelectedViews);
    }
    return savedSelectedViews;
  }, [savedSelectedViews, search]);

  const [activeKey, setActiveKey] = useActiveKey({
    searchParams,
    columns,
    selectedViews: search ? search.selectedViews : undefined,
    localValue,
  });

  const interColumns = useMemo(() => {
    let tempColumns = [...columns];

    tempColumns = withColumnSettings(tempColumns, columnSettings);

    tempColumns = withHidden(tempColumns);

    tempColumns = withRenderByValueType(tempColumns);

    tempColumns = withCopyableAndEllipsis(tempColumns);

    return tempColumns;
  }, [columns, columnSettings]);

  /** 单选多选的相关逻辑 */
  const [selectedRowKeys, setSelectedRowKeys] = useMountMergeState<React.ReactText[]>([], {
    value: propsRowSelection ? propsRowSelection.selectedRowKeys : undefined,
  });

  const selectedRowsRef = useRef<T[]>([]);

  const setSelectedRowsAndKey = useCallback(
    (keys: React.ReactText[], rows: T[]) => {
      setSelectedRowKeys(keys);
      selectedRowsRef.current = rows;
    },
    [setSelectedRowKeys],
  );

  // ============================ RowKey ============================
  const getRowKey = React.useMemo<any>(() => {
    if (typeof props.rowKey === 'function') {
      return props.rowKey;
    }
    return (record: T, index: number) => (record as any)?.[props.rowKey as string] ?? index;
  }, [props.rowKey]);

  /** 清空所有的选中项 */
  const onCleanSelected = useCallback(() => {
    if (propsRowSelection && propsRowSelection.onChange) {
      propsRowSelection.onChange([], []);
    }
    setSelectedRowsAndKey([], []);
    // 退出全选模式
    setIsSelectedAll(false);
  }, [propsRowSelection, setSelectedRowsAndKey]);

  /** 行选择相关的问题 */
  const rowSelection: ApolloTableRowSelection<T> = useMemo(
    () => ({
      selectedRowKeys,
      ...propsRowSelection,
      onChange: (keys, rows) => {
        // 全选模式下触发 onChange 退出全选模式
        if (isSelectedAll) {
          if (propsRowSelection && propsRowSelection.onChange) {
            propsRowSelection.onChange(keys, rows);
          }
          setIsSelectedAll(false);
          setSelectedRowsAndKey(keys, rows);
        } else {
          if (propsRowSelection && propsRowSelection.onChange) {
            propsRowSelection.onChange(keys, rows);
          }
          setSelectedRowsAndKey(keys, rows);
        }
      },
    }),
    [isSelectedAll, propsRowSelection, selectedRowKeys, setSelectedRowsAndKey],
  );

  const tableAlertRenderResult = useMemo(
    () =>
      tableAlertRender
        ? tableAlertRender({
            selectedRowKeys,
            selectedRows: selectedRowsRef.current,
            onCleanSelected,
            isSelectedAll,
          })
        : false,
    [isSelectedAll, onCleanSelected, selectedRowKeys, tableAlertRender],
  );

  const rect = useRect(ref, {
    observe: tableAlertRender !== false && propsRowSelection && !!selectedRowKeys.length,
  });

  // 处理 sticky
  const { sticky } = useMemo(() => {
    if (propsSticky) {
      return {
        sticky: {
          offsetHeader: layoutHeaderHeight,
          ...(typeof propsSticky === 'object' ? { sticky: propsSticky } : {}),
        },
      };
    }
    return {
      sticky: propsSticky,
    };
  }, [propsSticky, layoutHeaderHeight]);

  const componentsHeader = useMemo(
    () =>
      tableAlertRender !== false && propsRowSelection && !!selectedRowKeys.length
        ? {
            row: ({ children }: any) => (
              <BatchActions
                rowSelection={rowSelection}
                propsRowSelection={propsRowSelection}
                size={props.size}
                tableAlertRenderResult={tableAlertRenderResult}
                hasAnyPage={!!pageInfo?.hasPreviousPage || !!pageInfo?.hasNextPage}
                isSelectedAll={isSelectedAll}
                setIsSelectedAll={setIsSelectedAll}
                dataSource={dataSource as any}
                onCleanSelected={onCleanSelected}
                setSelectedRowsAndKey={setSelectedRowsAndKey}
                getRowKey={getRowKey}
                cardLeft={rect?.left || 0}
              >
                {children}
              </BatchActions>
            ),
          }
        : {},
    [
      dataSource,
      getRowKey,
      isSelectedAll,
      onCleanSelected,
      pageInfo?.hasNextPage,
      pageInfo?.hasPreviousPage,
      props.size,
      propsRowSelection,
      rect?.left,
      rowSelection,
      selectedRowKeys.length,
      setSelectedRowsAndKey,
      tableAlertRender,
      tableAlertRenderResult,
    ],
  );

  const actionRef = useRef<ApolloTableActionType>();

  const [inputValue, setInputValue] = useState('');
  const [queryValue, setQueryValue] = useState(() => {
    // url 的优先级高
    if (searchParams.query && syncToUrl) {
      return searchParams.query as string;
    }
    return '';
  });

  // 如果是按下回车搜索，queryValue 改变就要同步 inputValue
  useEffect(() => {
    if (search && search.pressEnterToSearch) {
      setInputValue(queryValue);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [queryValue]);

  const [filterValues, setFilterValues] = useState<Record<string, any>>(() => {
    if (syncToUrl) {
      return filterSearchToComponent(searchParams, columns);
    }

    return {};
  });

  const [sortValue, setSortValue] = useState(() => {
    if (syncToUrl && searchParams.order) {
      // url 的优先级最高
      return searchParams.order as string;
    }

    if (search && search.defaultSortValue) {
      // 开启了视图
      if (search.selectedViews) {
        if (activeKey === 'all') {
          return `${search.defaultSortValue.field} ${search.defaultSortValue.direction}`;
        }
        return '';
        // 没开启视图
      }
      return `${search.defaultSortValue.field} ${search.defaultSortValue.direction}`;
    }

    return '';
  });

  useEffect(() => {
    (async () => {
      if (search && search.selectedViews?.store) {
        const result = await search.selectedViews.store.get();
        isSelectedViewsGetEnd.current = true;
        setServerSelectedViews(result || []);
        if (searchParams.saved_search_id) {
          const current = (result || []).find(i => i.id === searchParams.saved_search_id);
          if (current) {
            setQueryValue(current.query || '');
            setSortValue(
              current.orderBy ? `${current.orderBy.field} ${current.orderBy.direction}` : '',
            );
            setFilterValues(current.filters || {});
          }
        }
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // isSelectedAll 发生变化回调
  useUpdateEffect(() => {
    if (propsRowSelection && propsRowSelection.onSelectedAllChange) {
      propsRowSelection.onSelectedAllChange(isSelectedAll);
    }
  }, [isSelectedAll]);

  // activeKey 发生变化清空选中
  useUpdateEffect(() => {
    onCleanSelected();
  }, [activeKey]);

  // 数据发生改变时，且是全选模式时 ---（点击分页时触发，把）
  useUpdateEffect(() => {
    if (isSelectedAll) {
      const allKeys = (dataSource || []).map((item: any) => getRowKey(item));
      setSelectedRowsAndKey(allKeys, (dataSource as any) || []);
    }
  }, [dataSource]);

  // 一页多少个
  const pageSize = (pagination !== false && pagination?.pageSize) || 10;

  const appliedFilters = useMemo(
    (): AppliedFilterInterface[] =>
      Object.keys(filterValues).map(key => {
        const col = findColumn(columns, key);

        return {
          key,
          label: (
            <>
              {col?.title}: {generateLabel(col, filterValues[key], locale)}
            </>
          ),
          allowClear: col.search?.allowClear,
          onRemove: () => {
            setFilterValues(omit(filterValues, [key]));

            if (col.search?.onRemove) {
              col.search.onRemove();
            }
          },
          tagRender: col.search?.tagRender
            ? tagRenderProps =>
                col.search?.tagRender?.({
                  ...tagRenderProps,
                  value: filterValues[key],
                }) as React.ReactElement<any, string | React.JSXElementConstructor<any>>
            : undefined,
        };
      }),
    [columns, filterValues, locale],
  );

  // 改变 url 参数函数
  const changeHistoryState = () => {
    let queryParams: Record<string, string> = {};

    // 当前是否是服务端保存的 tab
    const isCurrentServerTab = serverSelectedViews.find(i => i.id === activeKey);

    /* ---------- 设置 selectedView、saved_search_id start ---------- */
    if (search && search.selectedViews) {
      // 服务端视图
      if (search.selectedViews.store) {
        // 如果当前是服务端 tab
        if (isCurrentServerTab) {
          // 从服务端 tab 切换到服务端 tab 或者 在服务端 tab 分页 或者 页面第一次加载 或者由 pop 触发
          if (searchParams.saved_search_id) {
            // 分页触发的 或 改变了筛选 或 页面第一次加载才会相等
            if (searchParams.saved_search_id === activeKey) {
              // 由分页触发或第一次加载或 pop
              if (before || after || isChangeFirst.current) {
                queryParams.saved_search_id = activeKey;
                // 改变了筛选
              } else {
                queryParams.selectedView = 'all';
              }
              // 从服务端 tab 切换到 服务端 tab
            } else {
              queryParams.saved_search_id = activeKey;
            }
            // queryParams.selectedView = 'all';
            // 如果是普通 tab 切换到服务端 tab
          } else {
            queryParams.saved_search_id = activeKey;
          }
        } else {
          queryParams.selectedView = activeKey;
        }
        // 本地视图
      } else {
        queryParams.selectedView = activeKey.startsWith('savedSearch') ? 'savedSearch' : activeKey;
      }
    }
    /* ---------- 设置 selectedView、saved_search_id end ---------- */

    /* ---------- 设置筛选值 start ---------- */
    const fn = () => {
      if (queryValue) {
        queryParams.query = queryValue;
      }
      if (Object.keys(filterValues).length > 0) {
        queryParams = { ...queryParams, ...filterValuesToSearch(filterValues, columns) };
      }
      if (sortValue) {
        queryParams.order = sortValue;
      }
    };
    // 如果当前的 tab 是服务端保存
    if (search && search.selectedViews?.store && isCurrentServerTab) {
      // 如果是服务端 tab切换到服务端 tab， 不用做什么
      // 如果从服务端 tab 切换到非服务端 tab，就要切换到 all
      if (searchParams.saved_search_id && !queryParams.saved_search_id && !isChangeFirst.current) {
        setActiveKey('all');
        fn();
      }
    } else {
      fn();
    }
    /* ---------- 设置筛选值 end ---------- */

    /* ---------- 设置分页  start ---------- */
    // 如果是第一次加载，要把分页数据加上去
    if (isChangeFirst.current) {
      if (searchParams.before) {
        queryParams.before = searchParams.before as string;
      }
      if (searchParams.after) {
        queryParams.after = searchParams.after as string;
      }
    } else {
      // 点击上一页
      if (before) {
        queryParams.before = before;
      }
      // 点击下一页
      if (after) {
        queryParams.after = after;
      }
    }
    /* ---------- 设置分页  end ---------- */

    // 否则不添加 before 或 after（筛选排序直接跳回第一页）

    // 把参数设置进 localstorage
    localStorage.setItem(`apollo-table-query-params:${kebabCase(id)}`, JSON.stringify(queryParams));

    // 是页面第一次加载或 pop 不执行 url 修改
    if (!isChangeFirst.current) {
      // 先把原来的都 undefined 掉
      const undefinedSearchParams: any = {};
      Object.keys(searchParams).forEach(key => {
        // 判断是否要 undefined，如果 是输入框 或 排序 或 筛选 或 分页信息
        let flag = false;
        if (isCurrentServerTab) {
          flag = true;
        } else if (
          key === 'before' ||
          key === 'after' ||
          key === 'query' ||
          key === 'order' ||
          findColumn(columns, key) ||
          key === 'selectedView' ||
          key === 'saved_search_id'
        ) {
          flag = true;
        }

        if (flag) {
          undefinedSearchParams[key] = undefined;
        }
      });

      setSearchParams({
        ...undefinedSearchParams,
        ...queryParams,
      });
    }
  };

  const handleChange = async () => {
    // 服务端保存视图时，页面第一次加载时，请求完 get 再执行
    if (
      searchParams.saved_search_id &&
      search &&
      search.selectedViews?.store &&
      !isSelectedViewsGetEnd.current
    ) {
      return;
    }

    if (search && search.pressEnterToSearch && queryValue !== inputValue) {
      setInputValue(queryValue);
    }

    const query = generateQuery(queryValue, filterValues, columns);
    const sortArr = sortValue.split(' ');

    const variables: Variables = {};

    if (query) {
      variables.query = query;
    }
    if (sortValue && sortArr.length === 2) {
      variables.orderBy = {
        field: sortArr[0],
        direction: sortArr[1] as OrderDirection,
      };
    }

    if (isChangeFirst.current) {
      const { before: firstBefore, after: firstAfter } = searchParams;
      if (firstBefore) {
        variables.last = pageSize;
        variables.before = firstBefore as string;
      } else if (firstAfter) {
        variables.first = pageSize;
        variables.after = firstAfter as string;
      } else {
        variables.first = pageSize;
      }
    } else {
      // 点击上一页
      // eslint-disable-next-line no-lonely-if
      if (before) {
        variables.last = pageSize;
        variables.before = before;
        // 点击下一页
      } else if (after) {
        variables.first = pageSize;
        variables.after = after;
        // 点击筛选或者排序或者 query
      } else {
        variables.first = pageSize;
      }
    }

    if (syncToUrl) {
      changeHistoryState();
    }

    // 如果是页面载入第一次触发不执行 changeHistoryState

    isChangeFirst.current = false;

    if (request) {
      await request(variables);
    }
  };

  // 防抖  如果是服务端保存，要在 get 结束后再请求
  useDebounce(handleChange, debounceTime, [
    queryValue,
    sortValue,
    JSON.stringify(filterValues),
    before,
    after,
    // 用来触发此函数的
    depend,
  ]);

  usePopState({
    searchParams,
    selectedViews: search ? search.selectedViews : undefined,
    localValue,
    serverSelectedViews,
    setQueryValue,
    setSortValue,
    setFilterValues,
    setActiveKey,
    defaultSortValue: search ? search.defaultSortValue : undefined,
    columns,
    setBefore,
    setAfter,
    onCleanSelected,
    on: syncToUrl,
    onMount: () => {
      isChangeFirst.current = true;
    },
  });

  /* ------- ref 操作 -------- */
  useActionType(actionRef, {
    reload: triggerReload,
    apolloQuery: generateQuery(queryValue, filterValues, columns),
    queryValue,
    sortValue: sortValue
      ? { field: sortValue.split(' ')[0], direction: sortValue.split(' ')[1] as OrderDirection }
      : undefined,
    filterValues,
    setQueryValue: value => setQueryValue(value),
    setSortValue: value => setSortValue(`${value.field} ${value.direction}`),
    setFilterValues: value => setFilterValues(value),
    resetAndReload: () => {
      setQueryValue('');
      setSortValue('');
      setFilterValues({});
      setBefore('');
      setAfter('');
      onCleanSelected();
      triggerReload();
    },
    clearSelected: onCleanSelected,
  });

  /* ------- ref 操作 -------- */
  if (propsActionRef) {
    propsActionRef.current = actionRef.current;
  }

  // 回到第一页
  const resetPage = useCallback(() => {
    setBefore('');
    setAfter('');
  }, []);

  // 筛选发生变化直接重置页码
  useUpdateEffect(() => {
    resetPage();
  }, [queryValue, JSON.stringify(filterValues), sortValue, activeKey]);

  const renderFilter = () => {
    if (search !== false) {
      return (
        <div className={getPrefixCls('apollo-table-filter-wrapper')}>
          <Filters
            hideTags={search?.hideTags}
            hideQueryField={search?.hideQueryField}
            queryProps={{
              ...search?.queryProps,
              value: search?.pressEnterToSearch ? inputValue : queryValue,
              onChange: e => {
                if (search?.pressEnterToSearch) {
                  setInputValue(e.target.value);
                } else {
                  setQueryValue(e.target.value);
                }
                search?.queryProps?.onChange?.(e);
              },
              onPressEnter: e => {
                if (search?.pressEnterToSearch) {
                  e.preventDefault();
                  setQueryValue(e.currentTarget.value);
                }
                search?.queryProps?.onPressEnter?.(e);
              },
            }}
            appliedFilters={appliedFilters}
            filters={renderSearch(columns, filterValues, setFilterValues, getPrefixCls)}
            onClearAll={() => {
              setFilterValues({});
              setQueryValue('');

              if (search?.onClearAll) {
                search.onClearAll();
              }
            }}
            filtersExtra={
              isMobile &&
              search?.sortOptions && (
                <>
                  <Select
                    value={sortValue || undefined}
                    onChange={(value: string) => setSortValue(value)}
                    placeholder={locale?.sortPlaceholder}
                    style={{ flex: 1 }}
                    options={search.sortOptions.map(item => ({
                      label: item.label,
                      value: `${item.field} ${item.direction}`,
                    }))}
                  />
                  {options && options.setting && (
                    <ColumnsSetting
                      shouldSpace
                      columns={columns}
                      onColumnSettingsChange={setColumnSettings}
                      columnSettings={columnSettings}
                    />
                  )}
                </>
              )
            }
          >
            {(search?.selectedViews ||
              (search?.sortOptions && !isMobile) ||
              search?.extra ||
              (options && options.setting && (search?.sortOptions ? !isMobile : true))) && (
              <>
                {search?.selectedViews && (
                  <SelectedViewButton
                    columns={columns}
                    defaultSortValue={search?.defaultSortValue}
                    allSelectedViews={allSelectedViews}
                    onActiveKeyChange={setActiveKey}
                    searchParams={searchParams}
                    value={search.selectedViews.store ? serverSelectedViews : localValue || []}
                    onChange={setSavedSelectedViews}
                    selectedViews={search.selectedViews}
                    activeKey={activeKey}
                    queryValue={queryValue}
                    sortValue={sortValue}
                    filterValues={filterValues}
                    setQueryValue={setQueryValue}
                    setSortValue={setSortValue}
                    setFilterValues={setFilterValues}
                    setSearchParams={setSearchParams}
                  />
                )}
                {search?.sortOptions && !isMobile && (
                  <Popover
                    placement="bottomRight"
                    trigger="click"
                    overlayInnerStyle={{ maxHeight: 300, overflowY: 'auto' }}
                    content={
                      <>
                        <p className={getPrefixCls('apollo-table-sort-title')}>
                          {locale?.sortingLabel}
                        </p>
                        <Radio.Group
                          className={getPrefixCls('apollo-table-radio')}
                          value={sortValue}
                          onChange={e => {
                            setSortValue(e.target.value);
                            search.onSortChange?.(e);
                          }}
                        >
                          {search?.sortOptions.map((item, index) => (
                            // eslint-disable-next-line react/no-array-index-key
                            <Radio key={index} value={`${item.field} ${item.direction}`}>
                              {item.label}
                            </Radio>
                          ))}
                        </Radio.Group>
                      </>
                    }
                  >
                    <Button
                      icon={<SwapOutlined rotate={90} />}
                      style={search && search.selectedViews ? { marginLeft: 8 } : undefined}
                    >
                      {locale?.sort}
                    </Button>
                  </Popover>
                )}

                {search?.extra}

                {options && options.setting && (search?.sortOptions ? !isMobile : true) && (
                  <ColumnsSetting
                    shouldSpace={
                      !!search?.sortOptions || !!search?.extra || !!search?.selectedViews
                    }
                    columns={columns}
                    onColumnSettingsChange={setColumnSettings}
                    columnSettings={columnSettings}
                  />
                )}
              </>
            )}
          </Filters>
        </div>
      );
    }
    if (options && options.setting) {
      return (
        <div className={getPrefixCls('apollo-table-setting-wrapper')}>
          <ColumnsSetting
            columns={columns}
            onColumnSettingsChange={setColumnSettings}
            columnSettings={columnSettings}
          />
        </div>
      );
    }
  };

  const selectedViewTabsDom = useMemo(
    () =>
      search &&
      search.selectedViews && (
        <SelectedViewTabs
          allSelectedViews={allSelectedViews}
          setQueryValue={setQueryValue}
          setFilterValues={setFilterValues}
          defaultSortValue={search ? search.defaultSortValue : undefined}
          activeKey={activeKey}
          setActiveKey={val => {
            setActiveKey(val);
            triggerReload();
          }}
          columns={columns}
          setSortValue={setSortValue}
        />
      ),
    [activeKey, allSelectedViews, columns, search, setActiveKey],
  );

  const tableDom = useMemo(
    () => (
      <Table
        {...props}
        sticky={sticky}
        loading={loading}
        dataSource={dataSource}
        columns={interColumns}
        pagination={false}
        rowSelection={propsRowSelection && rowSelection}
        components={{
          ...components,
          header: { ...componentsHeader, ...components?.header },
        }}
        className={classNames(props.className, {
          [getPrefixCls('apollo-table-wrapper')]: true,
        })}
      />
    ),
    [
      components,
      componentsHeader,
      dataSource,
      getPrefixCls,
      interColumns,
      loading,
      props,
      propsRowSelection,
      rowSelection,
      sticky,
    ],
  );

  const paginationDom = useMemo(
    () =>
      pagination !== false &&
      (pagination?.hideOnSinglePage
        ? pageInfo?.hasNextPage || pageInfo?.hasPreviousPage
        : true) && (
        <div className={getPrefixCls('apollo-table-pagination-wrapper')}>
          <SimplePagination
            hasNext={!loading && pageInfo?.hasNextPage}
            hasPrevious={!loading && pageInfo?.hasPreviousPage}
            onNext={() => {
              setBefore('');
              setAfter(pageInfo?.endCursor || '');
            }}
            onPrevious={() => {
              setBefore(pageInfo?.startCursor || '');
              setAfter('');
            }}
          />
        </div>
      ),
    [
      getPrefixCls,
      loading,
      pageInfo?.endCursor,
      pageInfo?.hasNextPage,
      pageInfo?.hasPreviousPage,
      pageInfo?.startCursor,
      pagination,
    ],
  );

  return (
    <Card ref={ref} {...cardProps}>
      {selectedViewTabsDom}
      {renderFilter()}
      {tableDom}
      {paginationDom}
    </Card>
  );
};
