import { ref, reactive, unref } from "vue";
import { ElMessage } from "element-plus";
import { useNav } from "/@/layout/hooks/nav";

type Params = {
  code: number;
  message: string;
  noMessage?: boolean;
  handler: () => void;
  onError?: () => void
};

export function useResponseHandle() {
  const { logout } = useNav();
  function responseHandle({ code, message, handler, noMessage = false, onError }: Params) {
    const c = Number(code);
    if (c === 0) {
      handler();
    } else if (c >= 100 && c <= 140) {
      logout();
    } else {
      if (onError) { onError(); } else { !noMessage && ElMessage.error(message); }
    }
  }
  return responseHandle;
}

interface ResponseType<D> {
  data: D;
  code: number;
  message: string;
}

export function useAsync<D = any>({
  initalData,
  initalPagination,
  isList = false,
  success,
  noMessage = false
}: { initalData?: D; isList?: boolean; initalPagination?: any; success?: (data?: D) => void; noMessage?: boolean; } = {}) {
  const data = ref<D>(initalData);
  const isError = ref(false);
  const loading = ref(false);
  const pagination = reactive(initalPagination || {});
  const responseHandle = useResponseHandle();

  const setData = (_data: D) => (data.value = _data as any);
  const setloading = (_state: boolean) => (loading.value = _state);

  function getPaginationParams() {
    const { pageSize: size, currentPage: page } = pagination;
    return { size, page };
  }

  function run(promise: Promise<ResponseType<D>>) {
    setloading(true);

    return promise.then(response => {
      setloading(false);
      const { code: _code, message, data } = response;
      if (String(_code) !== "0") isError.value = true;
      responseHandle({
        code: _code,
        message,
        noMessage,
        handler: () => {
          setData(isList ? (data as any).list : data);
          isError.value = false;
          if (pagination) pagination.total = data ? (data as any).count : 0;
          success && success(unref(data));
        }
      });
    });
  }

  return {
    run,
    data,
    isError,
    loading,
    pagination,
    setData,
    getPaginationParams
  };
}
