import { onMounted, reactive, toRef, toRefs } from 'vue';
import { getPathValue, setDefault } from './utils';
import { GlobalOptions, UseTableOptions } from './types';

/**
 * useTable
 */

// 全局配置，可被覆盖
const _config: GlobalOptions = {
  currentKey: 'pageNo',
  pageSizeKey: 'pageSize',
  dataSourceKey: ['data', 'list'],
  totalKey: ['data', 'total'],
  pageSize: 10
};

export const setGlobalOptions = (config: GlobalOptions) => {
  Object.assign<GlobalOptions, GlobalOptions>(_config, config);
};

/**
 * useTable
 * @param service 服务
 * @param options 必须是通过 Vue3 响应式 api 创建
 */
export const hook = (
  service: (p?: any) => Promise<any>,
  options: UseTableOptions
) => {
  // 可选参数，设置默认值，开放全局配置
  const currentKey = setDefault<string>(
    toRef(options, 'currentKey'),
    _config.currentKey
  );
  const pageSizeKey = setDefault<string>(
    toRef(options, 'pageSizeKey'),
    _config.pageSizeKey
  );
  const current = setDefault<number>(toRef(options, 'current'), 1);
  const pageSize = setDefault<number>(
    toRef(options, 'pageSize'),
    _config.pageSize
  );
  const dataSourceKey = setDefault<string | string[]>(
    toRef(options, 'dataSourceKey'),
    _config.dataSourceKey
  );
  const totalKey = setDefault<string | string[]>(
    toRef(options, 'totalKey'),
    _config.totalKey
  );
  const immediate = setDefault<boolean>(toRef(options, 'immediate'), true);

  // 必填参数，直接获取
  const { columns } = toRefs(options);

  const state = reactive({
    loading: false,
    dataSource: [] as any[],
    pagination: {
      total: 0,
      current,
      pageSize
    }
  });

  const run = async () => {
    options.beforeRun?.();
    const { current, pageSize } = state.pagination;
    state.loading = true;
    const postData = {
      ...options.inParams,
      ...{ [currentKey.value!]: current, [pageSizeKey.value!]: pageSize }
    };
    console.log('✨【useTable】in-params :>> ', postData);
    const res = await service(postData);
    state.loading = false;
    state.pagination.total = getPathValue(res, totalKey.value!) || 0;
    // 可对数据进行格式化
    let dataSource = getPathValue(res, dataSourceKey.value!) || [];
    if (options.afterRun) dataSource = options.afterRun(dataSource);
    state.dataSource = dataSource;
  };

  onMounted(() => {
    immediate.value && run();
  });

  const handleTableChange = (
    pagination: any,
    filters: any,
    sorter: any,
    { action, currentDataSource }: any
  ) => {
    state.pagination = pagination;
    options.beforeChange?.(pagination, filters, sorter, {
      action,
      currentDataSource
    });
    run();
  };

  const handleSearch = () => {
    state.pagination.current = 1;
    run();
  };

  return {
    ...toRefs(state),
    columns,
    change: handleTableChange,

    /**
     * table 头部点击搜索的时候调用，重置 pageNo = 1，刷新数据
     */
    search: handleSearch,

    /**
     * 执行请求获取 table 数据
     */
    run,

    // 让 vue template 直接使用 v-bind="VBind" v-on="VOn"
    VBind: reactive({
      ...toRefs(state),
      columns
    }),
    VOn: {
      change: handleTableChange
    }
  };
};
