import {isRef, reactive, ref, toRefs, unref, watch, watchEffect} from "vue";
import {getCookieForName, setCookie, throttle} from "@/api/method";
import JSONBigInt from "json-bigint";
import router from "@/router";
import {message} from "ant-design-vue";
import {REFRESH_TOKEN, VALIDATE_TOKEN} from "@/api/apis";
import {REFRESH_TOKEN_API} from "@/api/ThirdApi";

const JSONBigIntStr = JSONBigInt({ storeAsString: true });

export function useBoeApiAuditPage(_url, params = {}) {
  return useBoeApiPage(_url, params, {
    init: true,
    result: (res) => res.result.audienceList.map((e) => ({ ...e, id: e.id + "" })),
    totalPage: (res) => res.result.totalPage,
    total: (res) => res.result.totalElement,
  });
}

export function useBoeApiUserInfoPage(_url, params = {}) {
  return useBoeApiPage(_url, params, {
    init: false,
    result: (res) => res.result.userInfoList,
    totalPage: (res) => res.result.totalPage,
    total: (res) => res.result.totalElement,
  });
}

export function useBoeApiPage(_url, params = {}, config = {
  init: true,
  result: res => res.result,
  totalPage: res => res.result.totalPage,
  total: res => res.result.totalElement
}) {

  const state = reactive({
    data: [],
    loading: false,
    page: 1,
    pageSize: 10,
    totalPage: 0,
    total: 0
  });

  if (isRef(params)) {
    watch(params.value, () => {
      fetch();
    });
  }

  if (isRef(_url)) {
    watchEffect(fetch);
  } else {
    fetch();
  }

  function fetch() {
    state.loading = true;
    return boeRequest(unref(_url), unref(params)).then(r => {
      state.data = config.result(r);
      state.totalPage = config.totalPage(r);
      state.total = config.total(r);
      state.loading = false;
      state.page = params.page;
    });
  }

  function reset() {
    state.data = [];
    state.loading = false;
    state.page = 1;
    state.totalPage = 0;
    state.total = 0;
  }

  config.init && fetch();
  return {
    ...toRefs(state),
    fetch,
    reset
  };
}

// export function useBoeApi(_url, params = {}, config = {
//   init: true,
//   result: res => res.result,
// }) {

//   const state = reactive({
//     data: [],
//     loading: false,
//   });
//   watch(() => params, () => {
//     fetch();
//   });

//   function fetch() {
//     state.loading = true;
//     return boeRequest(_url, params).then(r => {
//       state.data = config.result(r);
//       state.loading = false;
//     });
//   }

//   config.init && fetch();
//   return {
//     ...toRefs(state),
//     fetch,
//   };
// }

// export function useBoeUserListPage(_url, params = {}, init = true) {

//   const state = reactive({
//     data: [],
//     loading: false,
//     total: 0,
//     totalPage: 0,
//     page: 1,
//     ...params
//   });

//   watch(() => params.keyword, throttle(fetch, 600));
//   watch(() => params.page, fetch);

//   function fetch() {
//     state.loading = true;
//     if (!params.keyword) {
//       state.loading = false;
//       return;
//     }
//     return boeRequest(_url, params).then(r => {
//       state.data = params.page === 1 ? r.result.userInfoList : [...state.data, ...r.result.userInfoList];
//       state.totalPage = r.result.totalPage;
//       state.total = r.result.totalElement;
//       state.loading = false;
//     });
//   }

//   init && fetch();
//   return {
//     ...toRefs(state),
//     fetch,
//   };
// }
export function useNewRowsPageNoInit(_url, params) {
  const state = reactive({
    data: [],
    total: 1,
    pageNo: 1,
    pages: 1,
    loading: false
  });

  function reset() {
    state.data = [];
    state.loading = false;
  }

  function fetch() {
    state.loading = true;
    return request(unref(_url), unref(params)).then(r => {
      state.data = r.data.list;
      state.total = r.data.total;
      state.loading = false;
    });
  }

  return {
    ...toRefs(state),
    fetch,
    reset,
  };
}
export function useRowsPageNoInit(_url, params) {
  const state = reactive({
    data: [],
    total: 1,
    current: 1,
    pages: 1,
    loading: false
  });

  function reset() {
    state.data = [];
    state.loading = false;
  }

  function fetch() {
    state.loading = true;
    return request(unref(_url), unref(params)).then(r => {
      state.data = r.data.rows || r.data.records;
      state.current = r.data.current || r.data.current;
      state.pages = r.data.pages;
      state.total = r.data.total;
      state.loading = false;
    });
  }

  return {
    ...toRefs(state),
    fetch,
    reset,
  };
}

export function useRowsPage(_url, params, init = true) {

  const state = reactive({
    data: [],
    total: 1,
    current: 1,
    pages: 1,
    loading: false
  });

  if (isRef(params)) {
    watch(params.value, () => {
      fetch();
    });
  }

  if (isRef(_url)) {
    watchEffect(fetch);
  } else {
    init && fetch();
  }

  function reset() {
    state.data = [];
    state.loading = false;
  }

  function fetch() {
    state.loading = true;
    return request(unref(_url), unref(params)).then(r => {
      state.data = r.data.rows;
      state.current = r.data.current;
      state.pages = r.data.pages;
      state.total = r.data.total;
      state.loading = false;
    });
  }

  return {
    ...toRefs(state),
    fetch,
    reset,
  };
}

/**
 * 分页只返回 total 无分页信息
 * @param _url
 * @param params
 * @param init
 * @param listing
 */
export function useTotalPage(_url, params, init = true,listing = false) {

  const state = reactive({
    data: [],
    total: 1,
    current: 1,
    pages: 1,
    pageNo: 1,
    pageSize: 10,
    loading: false
  });

  if (isRef(params) && listing) {
    watch(params.value, () => {
      fetch();
    });
  }

  if (isRef(_url)) {
    watchEffect(fetch);
  } else {
    init && fetch();
  }

  function reset() {
    state.data = [];
    state.loading = false;
  }

  function fetch() {
    state.loading = true;
    return request(unref(_url), unref(params)).then(r => {
      state.data = r.data.list;
      state.total = r.data.total;
      state.loading = false;
    });
  }

  return {
    ...toRefs(state),
    fetch,
    reset,
  };
}
export function usePage(_url, params, init = true,listing = false) {

  const state = reactive({
    data: [],
    total: 1,
    current: 1,
    pages: 1,
    loading: false
  });

  if (isRef(params) && listing) {
    watch(params.value, () => {
      fetch();
    });
  }

  if (isRef(_url)) {
    watchEffect(fetch);
  } else {
    init && fetch();
  }

  function reset() {
    state.data = [];
    state.loading = false;
  }

  function fetch() {
    state.loading = true;
    return request(unref(_url), unref(params)).then(r => {
      state.data = r.data.records;
      state.current = r.data.current;
      state.pages = r.data.pages;
      state.total = r.data.total;
      state.loading = false;
    });
  }

  return {
    ...toRefs(state),
    fetch,
    reset,
  };
}
  export function useThrottlePage(_url, params = {}, init = true) {

  const state = reactive({
    data: [],
    loading: false,
    total: 0,
    totalPage: 0,
    page: 1,
    pageNo: 1,
    ...params
  });

  watch(() => params.keyword, throttle(fetch, 600));
  watch(() => params.page, fetch);

  function fetch() {
    state.loading = true;
    if (!params.keyword) {
      state.loading = false;
      return;
    }
    return request(_url, params).then(r => {
      state.data = params.pageNo === 1 ? r.data.list : [...state.data, ...r.data.list];
      state.totalPage = r.data.total/10 || 1;
      state.total = r.data.total;
      state.loading = false;
    });
  }

  init && fetch();
  return {
    ...toRefs(state),
    fetch,
  };
}


export function useRequest(_url, params, init = true) {

  const data = ref({});
  const loading = ref(false);

  if (isRef(params)) {
    watch(params.value, () => {
      fetchData();
    });
  }

  function fetchData() {
    loading.value = true;
    request(_url, unref(params)).then(r => {
      data.value = r.data;
      loading.value = false;
    });
  }

  init && fetchData();
  return {
    data,
    loading,
    fetchData,
  };
}
export function useArrayRequest(_url, params, init = true) {

  const data = ref([]);
  const loading = ref(false);

  if (isRef(params)) {
    watch(params.value, () => {
      fetchData();
    });
  }

  function fetchData() {
    loading.value = true;
    request(_url, unref(params)).then(r => {
      data.value = r.data;
      loading.value = false;
    });
  }

  init && fetchData();
  return {
    data,
    loading,
    fetchData,
  };
}
export async function boeRequest(_url, params = {}) {
  const s = _url.split(" ");
  let url = s[0];
  const method = s[1]?.toLowerCase() || "get";
  if (method === "get") {
    url.includes("?") ? (url.endsWith("&") || (url += "&")) : (url += "?");
    url += Object.keys(params).map(key => key + "=" + params[key]).join("&");
  }
  const body = method !== "get" ? s[2] === "formData" ? formatFormData(params) : params : {};
  url = process.env.NODE_ENV === "development" ? url : window.location.protocol + process.env.VUE_APP_BOE_API_URL + url;
  return fetch(url, {
    method,
    headers: {
      token: getCookieForName("token"),
      ...method !== "get" && s[2] !== "formData" ? { "Content-Type": "application/json" } : {}
    },
    ...method !== "get" ? { body: s[2] === "formData" ? body : JSON.stringify(body) } : {}
  }).then(res => {
    return res.text();
  }).then(res => {
    return JSONBigIntStr.parse(res);
  });
}

function formatFormData(data) {
  const formData = new FormData();
  Object.keys(data).forEach(k => formData.append(k, data[k]));
  return formData;
}

export async function request(_url, params) {
  const s = _url.split(" ");
  let url = s[0];
  const method = s[1]?.toLowerCase() || "get";
  if (method === "get") {
    let paramsArray = [];
    if (params) {
      Object.keys(params).forEach(key => paramsArray.push(key + "=" + params[key]));
      if (url.search(/\?/) === -1) {
        url += "?" + paramsArray.join("&");
      } else {
        url += "&" + paramsArray.join("&");
      }
    }
  }
  const body = method !== "get" ? params || {} : {};
  return fetch(process.env.VUE_APP_BASE_API + url, {
    method,
    headers: {
      token: getCookieForName("token"),
      ...method !== "get" ? { "Content-Type": "application/json" } : {}
    },
    ...method !== "get" ? { body: JSON.stringify(body) } : {}
  }).then(res => {
    return res.text();
  }).then(res => {
    return JSONBigIntStr.parse(res);
  }).then(res => {
    if (res.code === 0 || res.code === 200) {
      return res;
    }
    if (res.code === 1000 || res.code === 1002) {
      (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'alpine') ?
        router.push({path: 'login', query: { returnUrl: router.currentRoute.value.fullPath }}) :
        (window.location.href = process.env.VUE_APP_LOGIN_URL + encodeURIComponent(window.location.protocol + process.env.VUE_APP_BOE_API_URL + process.env.VUE_APP_BASE + router.currentRoute.value.fullPath))
      localStorage.removeItem('refreshPage')
      return Promise.reject(res);
    }else if(res.code=== 1001){
      return boeRequest(REFRESH_TOKEN_API).then((res)=>{
        if(res.code===0 || res.code === 200){
          return request(_url, params)
        }
      })
    }
    //刷新token
    res.show ? message.error(res.msg):message.error('系统接口数据异常，请联系管理员');
    return Promise.reject(res);
  });
}