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

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

export function useResponseHandle() {
  const { logout } = useNav();

  function responseHandle({ code, message, handler }: Params) {
    const c = Number(code);
    if (c === 0) {
      handler();
    } else if (c >= 100 && c <= 140) {
      logout();
    } else {
      ElMessage.error(message);
    }
  }

  return responseHandle;
}

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

export function useAsync<D>({
  initalData,
  initalPagination,
  isList = false,
  success,
  fall
}: {
  initalData?: D;
  isList?: boolean;
  initalPagination?: any;
  success?: () => void;
  fall?: () => void;
}) {
  const data = ref<D>(initalData);
  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, message, data } = response;

        responseHandle({
          code,
          message,
          handler: () => {
            setData(isList ? (data as any).list : data);
            pagination.total = (data as any).count;
            success && success();
          }
        });
      })
      .catch(() => {
        fall && fall();
      });
  }

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