import { reactive, toRefs, computed } from 'vue';

export function useProTable(
  api,
  initParam = {},
  isPageable,
  dataCallBack,
  requestError,
  paramCallback,
  config
) {
  const state = reactive({
    loading: false,
    // 表格数据
    tableData: [],
    // 分页数据
    pageable: {
      // 当前页数
      current: 1,
      // 每页显示条数
      size: 10,
      // 总条数
      total: 0,
    },
    // 查询参数(只包括查询)
    searchParam: {},
    // 初始化默认的查询参数
    searchInitParam: {},
    // 总参数(包含分页和查询参数)
    totalParam: {},
    gridConfig: {
      align: 'center',
      toolbarConfig: {
        slots: {
          buttons: 'toolbar_buttons',
          tools: 'toolbar_tools',
        },
        zoom: {
          iconIn: 'vxe-icon-fullscreen',
          iconOut: 'vxe-icon-minimize',
        },
        custom: {
          icon: 'vxe-icon-menu',
        },
      },
      showHeaderOverflow: 'tooltip',
      rowConfig: {
        height: 40,
      },
      cellConfig: {
        height: 40,
      },
    },
  });

  /**
   * @description 分页查询参数(只包括分页和表格字段排序,其他排序方式可自行配置)
   * */
  const pageParam = computed({
    get: () => {
      return {
        current: state.pageable.current,
        size: state.pageable.size,
      };
    },
    set: (newVal) => {
      console.log('我是分页更新之后的值', newVal);
    },
  });

  /**
   * @description 获取表格数据
   * @return void
   * */
  const getTableList = async () => {
    if (!api) return;
    try {
      state.loading = true;
      // 先把初始化参数和分页参数放到总参数里面
      Object.assign(state.totalParam, initParam, isPageable ? pageParam.value : {});
      let param = { ...state.searchInitParam, ...state.totalParam };
      paramCallback && (param = paramCallback(param));
      let { result } = await api(param);
      dataCallBack && (result = dataCallBack(result));

      state.tableData = isPageable ? result.content : result;
      // 解构后台返回的分页数据 (如果有分页更新分页信息)
      if (isPageable) {
        state.pageable.total = +result.page.totalElements;
      }
    } catch (error) {
      requestError && requestError(error);
    }
    state.loading = false;
  };

  /**
   * @description 更新查询参数
   * @return void
   * */
  const updatedTotalParam = () => {
    state.totalParam = {};
    // 处理查询参数，可以给查询参数加自定义前缀操作
    let nowSearchParam = {};
    // 防止手动清空输入框携带参数（这里可以自定义查询参数前缀）
    for (let key in state.searchParam) {
      // 某些情况下参数为 false/0 也应该携带参数
      if (
        state.searchParam[key] ||
        state.searchParam[key] === false ||
        state.searchParam[key] === 0
      ) {
        nowSearchParam[key] = state.searchParam[key];
      }
    }
    Object.assign(state.totalParam, nowSearchParam);
  };

  /**
   * @description 表格数据查询
   * @return void
   * */
  const search = () => {
    state.pageable.current = 1;
    if (config && config.onCheckboxAll) {
      config.onCheckboxAll({ checked: false, records: [] });
    }
    updatedTotalParam();
    getTableList();
  };

  /**
   * @description 表格数据重置
   * @return void
   * */
  const reset = () => {
    state.pageable.current = 1;
    // 重置搜索表单的时，如果有默认搜索参数，则重置默认的搜索参数
    state.searchParam = { ...state.searchInitParam };
    updatedTotalParam();
    getTableList();
  };

  /**
   * @description 每页条数改变
   * @param {Number} val 当前条数
   * @return void
   * */
  const handleSizeChange = (val) => {
    state.pageable.current = 1;
    state.pageable.size = val;
    getTableList();
  };

  /**
   * @description 当前页改变
   * @param {Number} val 当前页
   * @return void
   * */
  const handleCurrentChange = (val) => {
    state.pageable.current = val;
    getTableList();
  };

  return {
    ...toRefs(state),
    getTableList,
    search,
    reset,
    handleSizeChange,
    handleCurrentChange,
    updatedTotalParam,
  };
}
