import React, { useMemo, useCallback, useState, useRef } from 'react';
import {
  Button,
  message,
  Modal,
  Space,
  Divider,
  AlertProps,
  Alert,
  Typography,
  Tooltip,
} from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import ProTable, { ProColumns, ActionType, ProTableProps } from '@ant-design/pro-table';
import { Access, useAccess } from 'umi';

export interface toolBarActionsItem {
  type: 'add' | 'batchDelete';
  permission?: string;
  text?: string;
  onConfirm: (val?: string[]) => void;
}
export interface PropsType extends ProTableProps<any, any> {
  toolBarActions?: toolBarActionsItem[];
  alertProps?: AlertProps;
  indexColumn?: boolean | ProColumns<any, 'text'>;
}

type Record<K extends keyof any, T> = {
  [P in K]: T;
};

const Table = <T extends Record<string, any>>(props: PropsType) => {
  const access = useAccess();

  const {
    columns: columnsProps = [],
    search: searchProps = {},
    pagination: paginationProps,
    options = false,
    toolBarRender: toolBarRenderProps,
    toolBarActions,
    actionRef: actionRefProps,
    rowSelection: rowSelectionProps,
    toolbar: toolbarProps,
    alertProps,
    indexColumn,
  } = props;
  const defaultRef = useRef<ActionType>();
  const actionRef: any = actionRefProps || defaultRef;
  const [selectedRows, setSelectedRows] = useState<React.Key[]>([]);

  // 暂时有批量删除的话，替换rowSelection，后续有发现问题再改
  const rowSelection = useMemo(() => {
    if (toolBarActions && toolBarActions.findIndex((item) => item.type === 'batchDelete') > -1) {
      return {
        selectedRowKeys: selectedRows,
        onChange: setSelectedRows,
        preserveSelectedRowKeys: true,
      };
    }
    return rowSelectionProps
      ? {
          preserveSelectedRowKeys: true,
          ...rowSelectionProps,
        }
      : false;
  }, [rowSelectionProps, toolBarActions, setSelectedRows, selectedRows]);

  const indexColumnValue = useMemo(() => {
    if (!indexColumn) return [];
    const rankItem = [
      {
        title: '序号',
        dataIndex: 'index',
        width: 80,
        align: 'center',
        search: false,
        render: (_: any, item: any, index: number) => {
          // @ts-ignore
          const { current, pageSize } = actionRef.current?.pageInfo;
          return index + 1 + (current - 1) * pageSize;
        },
        ...(typeof indexColumn === 'object' ? indexColumn : {}),
      },
    ];
    return rankItem;
  }, [indexColumn, actionRef]);

  const columns = useMemo(() => {
    const newColumns = columnsProps.map((item) => {
      const optionRender = (_: any, val: any, ...rest: any) => {
        return (
          <Space size={0} split={<Divider type="vertical" />}>
            {(item.render && (item.render(_, val, ...rest) as []))?.map((item2) => {
              return item2;
            })}
          </Space>
        );
      };
      let { render } = item;
      if (item.valueType === 'option') {
        render = optionRender;
      }
      return {
        ...item,
        fieldProps:
          item.valueType === 'select'
            ? {
                ...item.fieldProps,
                showSearch: (item.fieldProps as any)?.options?.length > 8,
              }
            : item.fieldProps,
        render,
      };
    });

    return indexColumnValue.concat(newColumns);
  }, [columnsProps, indexColumnValue]);

  // search属性
  const search = useMemo(() => {
    if (searchProps === false) {
      return searchProps;
    }
    return {
      ...searchProps,
      optionRender: ({ searchText, resetText }, { form }) => [
        <Button
          key="search"
          type="primary"
          onClick={() => {
            form?.submit();
          }}
        >
          {searchText}
        </Button>,
        <Button
          key="rest"
          onClick={() => {
            form?.resetFields();
            form?.submit();
            props.onReset && props.onReset();
          }}
        >
          {resetText}
        </Button>,
      ],
    };
  }, [searchProps, columnsProps]);

  const handleBatchDelete = (action: any) => {
    if (selectedRows.length === 0) {
      message.warn('请选择要操作的项');
      return;
    }
    Modal.confirm({
      title: '提示',
      content: '是否确认删除?',
      okText: '确认',
      cancelText: '取消',
      onOk: () => {
        action(selectedRows);
      },
    });
  };
  // 渲染toolbarActions自定义按钮
  const toolBarActionsRender = useCallback(() => {
    const buttonList: any = [];
    toolBarActions &&
      toolBarActions.forEach((item) => {
        if (item.type === 'add') {
          buttonList.push(
            <Access accessible={access.canShowButton(item.permission)}>
              <Button
                key="add"
                type="primary"
                onClick={() => {
                  item.onConfirm();
                }}
              >
                <PlusOutlined />
                {item.text || '添加'}
              </Button>
            </Access>,
          );
        } else if (item.type === 'batchDelete') {
          buttonList.push(
            <Access accessible={access.canShowButton(item.permission)}>
              <Button
                key="del"
                danger
                onClick={() => {
                  handleBatchDelete(item.onConfirm);
                }}
              >
                {item.text || '批量删除'}
              </Button>
            </Access>,
          );
        }
      });
    return buttonList;
  }, [toolBarActions, selectedRows]);

  // 渲染toolbar
  const toolBarRender = useCallback(
    (
      action,
      rows: {
        selectedRowKeys?: (string | number)[];
        selectedRows?: T[];
      },
    ) => {
      let toolRender = toolBarRenderProps ? toolBarRenderProps(action, rows) : toolBarRenderProps;
      if (toolBarActions) {
        const buttonList: any = toolBarActionsRender();
        toolRender = toolRender ? toolRender.concat(buttonList) : buttonList;
      }
      return toolRender;
    },
    [toolBarRenderProps, toolBarActions, toolBarActionsRender],
  );
  // 分页统一为10条
  const pagination = useMemo(() => {
    if (paginationProps === undefined) {
      return { defaultCurrent: 1, defaultPageSize: 10, pageSize: 10, current: 1 };
    }
    return paginationProps;
  }, [paginationProps]);

  // 渲染tip，用toolbar的filter
  const toolbar = useMemo(() => {
    if (alertProps) {
      return {
        ...toolbarProps,
        multipleLine: true,
        filter: <Alert {...alertProps} />,
      };
    }
    return toolbarProps;
  }, [alertProps, toolbarProps]);

  return (
    <div className="ls-table">
      <ProTable<T>
        {...{
          ...props,
          search,
          pagination,
          columns,
          rowSelection,
          options,
          toolbar,
          toolBarRender: toolBarRenderProps || toolBarActions ? toolBarRender : toolBarRenderProps,
          actionRef,
          onLoad: (res) => {
            if (res.length === 0 && actionRef?.current.pageInfo.current !== 1) {
              actionRef?.current.setPageInfo({
                ...actionRef?.current.pageInfo,
                current: actionRef?.current.pageInfo.current - 1,
              });
            }
          },
        }}
      />
    </div>
  );
};

export type { ProColumns, ActionType, ProTableProps };
export default Table;
