import { ElMessage } from 'element-plus';


type ReactiveOrRef<T> = T | Ref<T>;

interface PagerConfig {
  total: number;
  page: number;
  limit: number;
}

interface DataStructure {
  data?: any[];
  pagerConfig?: PagerConfig;
  loading?: boolean;
}

export async function useTableData(
    apiFunction: Function,
    query: any,
    options: ReactiveOrRef<DataStructure | any>
) {
  const getReactiveValue = <T>(obj: ReactiveOrRef<T>, key: keyof T): T[keyof T] => {
    if (isRef(obj)) {
      return obj.value[key];
    }
    return obj[key];
  };

  const setReactiveValue = <T>(obj: ReactiveOrRef<T>, key: keyof T, value: any) => {
    if (isRef(obj)) {
      obj.value[key] = value;
    } else {
      obj[key] = value;
    }
  };

  const getPagerConfig = (): any => {
    if (getReactiveValue(options, 'pagerConfig')) {
      return getReactiveValue(options, 'pagerConfig');
    } else {
      return {
        total: getReactiveValue(options, 'total') || 0,
        page: getReactiveValue(options, 'page') || 1,
        limit: getReactiveValue(options, 'limit') || 15
      };
    }
  };

  const setTotal = (total: number) => {
    if (getReactiveValue(options, 'pagerConfig')) {
      const pagerConfig = getPagerConfig();
      setReactiveValue(options, 'pagerConfig', { ...pagerConfig, total });
    } else {
      setReactiveValue(options, 'total', total);
    }
  };

  const setLoading = (value: boolean) => {
    if (getReactiveValue(options, 'loading') !== undefined) {
      setReactiveValue(options, 'loading', value);
    }
  };

  // 更新查询参数
  const pagerConfig = getPagerConfig();
  query = {
    ...query,
    page: pagerConfig.page,
    limit: pagerConfig.limit
  };

  try {
    setLoading(true);
    const response = await apiFunction(query);

    let responseData = Array.isArray(response.data) ? response.data : [ response.data ];
    setReactiveValue(options, 'data', responseData);
    setTotal(response.total);

    return { success: true, data: responseData, code: response.code, msg: response.msg };
  } catch (error) {
    ElMessage.error('Table Error');
    return { success: false, error };
  } finally {
    setLoading(false);
    await nextTick();
    window.dispatchEvent(new Event('resize'));
  }
}
