import React, {FC, Ref, useImperativeHandle} from 'react';
import {GetProps, Pagination} from "antd";
import {cloneDeep} from "lodash";
import {useRexProConfigProvider} from '@jeoshi-design/rex-design.other.core';
import {useStateData} from '@jeoshi-design/rex-design.hooks.core';
import {BaseTable} from '@jeoshi-design/rex-design.data-display.core';
import {ActionButtons} from '@jeoshi-design/rex-design.common.core';
import {fakeDataSource} from "./fakeDataSource";

export const Table: FC<TableProps> = ({
  defaultPageSize = 50,
  hidePagination,
  api = '请配置: api',
  actionConfig,
  actionRef,
  rowSelection,
  actionButtonItems,
  showFakeDataSource,
  ...otherProps
}) => {
  const {apiClient} = useRexProConfigProvider();
  const {state, update} = useStateData(() => ({
    params: {
      page_size: defaultPageSize,
      current: 1,
    },
    otherParams: {} as Record<string, unknown>,
    dataSource: [] as unknown[],
    selectedKeys: [] as React.Key[],
    selectedItems: [] as unknown[],
    total: 0,
    result: null as TApiResult | null,
    loading: false,
  }));

  const change = async () => {
    state.loading = true;
    state.selectedKeys = [];
    state.selectedItems = [];
    update();

    try {
      const result = await apiClient(api, cloneDeep({...state.params, ...state.otherParams})) as TApiResult;
      state.dataSource = result.items || [];
      state.total = result.page?.total_items ?? 1;
      state.result = result;
    } catch (error) {
      state.dataSource = [];
      state.total = 0;
      state.result = null;
    }

    state.loading = false;
    update();
  };

  const actions: ITableActionRef = {
    getList: async ({page, otherParams} = {}) => {

      if (page) {
        state.params.current = page;
      }

      if (typeof otherParams === 'function') {
        state.otherParams = otherParams(state.otherParams);
      }
      else if (otherParams) {
        state.otherParams = otherParams;
      }

      await change();
    },
    clearSelected: () => {
      state.selectedKeys = [];
      state.selectedItems = [];
      update();
    },
    getSelectedKeys: () => {
      return state.selectedKeys;
    },
    setSelectedKeys: (keys) => {
      state.selectedKeys = keys;
      update();
    },
    getSelectedItems: () => {
      return state.selectedItems;
    },
    getApiResult: () => {
      return state.result;
    },
    getFilterValues: () => {
      return state.otherParams;
    },
  };

  useImperativeHandle<{}, ITableActionRef>(actionRef, () => actions)

  return (
    <>
      <BaseTable
        dataSource={state.dataSource as object[]}
        {...showFakeDataSource ? {dataSource: fakeDataSource} as any : {}}
        {...otherProps}
        rowSelection={{
          ...rowSelection,
          selectedRowKeys: state.selectedKeys,
          onChange(keys, items) {
            state.selectedKeys = keys as [];
            state.selectedItems = items as [];
            update();
          }
        }}
        loading={state.loading}
        pagination={false}
        extraColumns={
          actionButtonItems?.length
            ? [{
              title: '操作',
              fixed: 'right',
              dataIndex: 'webAction',
              align: 'center',
              width: 80,
              ...actionConfig?.columnConfig,
              render: (_, record, index) => {
                return (
                  <div style={{display: 'inline-flex', justifyContent: 'center', alignItems: 'center', gap: 6}}>
                    <ActionButtons
                      size="small"
                      {...actionConfig?.actionButtonProps}
                      items={actionButtonItems}
                      record={record as Record<string, unknown>}
                    />
                  </div>
                );
              }
            }]
            : []
        }
        scroll={(h) => ({x: 1000, y: h})}
      />
      {
        state.dataSource.length && !hidePagination
          ? (
            <Pagination
              style={{marginTop: 10}}
              align="end"
              size="small"
              total={state.total}
              showSizeChanger
              showQuickJumper
              showLessItems
              showTotal={(total) => `共 ${total} 条`}
              pageSize={state.params.page_size}
              current={state.params.current}
              showTitle
              onChange={(page, pageSize) => {
                state.params.current = page;
                state.params.page_size = pageSize;
                change();
              }}
            />
          )
          : <></>
      }
    </>
  );
};

interface TableProps extends Omit<GetProps<typeof BaseTable>, 'fields' | 'requestFields' | 'requestFieldsUrl' | 'requestFieldsParams' | 'columns'> {
  /**
   * 默认条数
   * @default 50
   */
  defaultPageSize?: number;
  /** 隐藏分页 */
  hidePagination?: boolean;
  /** 请求地址 */
  api?: string;
  /** 操作按钮配置 */
  actionButtonItems?: GetProps<typeof ActionButtons>['items'];
  /** 操作列配置 */
  actionConfig?: {
    /** 列配置 */
    columnConfig?: Omit<Exclude<GetProps<typeof BaseTable>['columns'], undefined>[number], 'render'>;
    /** 操作按钮props */
    actionButtonProps?: Omit<GetProps<typeof ActionButtons>, 'items'>;
  };
  /** 暴露的操作对象 */
  actionRef?: Ref<ITableActionRef>;
  /** 显示假数据 */
  showFakeDataSource?: boolean;
}

interface ITableActionRef {
  /** 主动查询 */
  getList: (data?: {page?: number, otherParams?: Record<string, unknown> | ((prevData: Record<string, unknown>) => Record<string, unknown>)}) => Promise<void>;
  /** 清空选择项 */
  clearSelected: () => void;
  /** 获取选中项key */
  getSelectedKeys: () => React.Key[];
  /** 设置选中项 */
  setSelectedKeys: (keys: React.Key[]) => void;
  /** 获取选中项 对象 */
  getSelectedItems: () => unknown[];
  /** 获取api结果 */
  getApiResult: () => TApiResult | null;
  /** 获取过滤条件 */
  getFilterValues: () => Record<string, unknown>;
}

/** 接口回调 */
type TApiResult = {
  items?: unknown[],
  page?: { current_page?: number, page_size?: number, total_items?: number, total_pages?: number },
  [key: string]: unknown,
}
