import axios from "axios";
import { download } from "@/utils/tool";
import { get, isEmpty } from "lodash-es";
import qs from "qs";
// import { h } from 'vue';
import { getAuthorization, getMD5 } from "./crypto";
import router from "@/router";
import { initSyncTime, fetchTime } from "./syncServerTime";
import { local } from "@/utils/tool";
import { useAppStore, useUserStore } from "@/store";
import { message } from "@qmth/ui";

function getDeviceId() {
  let deviceId = local.get("deviceId");
  if (deviceId) return deviceId;

  if (!deviceId) {
    deviceId = getMD5(Math.random() + "-" + Date.now());
    local.set("deviceId", deviceId);
    return deviceId;
  }
}

function setAuth(config: any) {
  let userSession = sessionStorage.getItem("user");
  if (userSession && !config.noAuth) {
    let user = JSON.parse(userSession).userInfo;
    if (!user) {
      return;
    }
    const timestamp = fetchTime();
    const authorization = getAuthorization(
      {
        method: config.method,
        uri: config.url.split("?")[0].trim(),
        timestamp,
        sessionId: user.sessionId,
        token: user.accessToken,
      },
      "token"
    );
    config.headers["Authorization"] = authorization;
    config.headers["time"] = timestamp;
  }
}

function createService() {
  // 创建一个 axios 实例
  const service = axios.create();

  // HTTP request 拦截器
  service.interceptors.request.use(
    (config: any) => {
      setAuth(config);
      const appStore = useAppStore();
      if (config.loading) {
        appStore.setLoading(true);
      }
      if (config.download) {
        config.responseType ??= "blob";
      }
      return config;
    },
    (error) => {
      // 失败
      return Promise.reject(error);
    }
  );
  const rejectWhiteList: string[] = [
    // 审核员图片检查任务获取
    "/api/auditor/batch/inspect/get",
    // 审核员实时审核任务获取
    "/api/auditor/batch/verify/get",
  ];
  // HTTP response 拦截器
  service.interceptors.response.use(
    (response: any) => {
      initSyncTime(new Date(response.headers.date).getTime());
      const appStore = useAppStore();
      if (response.config.loading) {
        appStore.setLoading(false);
      }
      // 以下代码看后端是否有统一在接口里增加外层code的规范
      if (response.data?.code && response.data?.code !== 200) {
        message.error(response.data?.message);
      }
      if (response.config.download && response.config.responseType === "blob") {
        download(response);
      }
      return response.data;
    },
    (error) => {
      if (error.response) {
        initSyncTime(new Date(error.response.headers.date).getTime());
      }
      const appStore = useAppStore();
      if (error.config?.loading) {
        appStore.setLoading(false);
      }
      const err = (text: string) => {
        !rejectWhiteList.includes(error.config?.url) &&
          message.error(
            error.response && error.response.data && error.response.data.message
              ? error.response.data.message
              : text
          );
      };
      const userStore = useUserStore();
      if (error.response) {
        switch (error.response.status) {
          case 404:
            err(`服务器资源不存在`);
            break;
          case 500:
            err(`服务器内部错误`);
            break;
          case 401:
            message.error("登录状态已过期");
            userStore.setUserInfo(null);
            router.replace({ name: "Login" });
            break;
          case 403:
            err(`没有权限访问该资源`);
            break;
          default:
            err(JSON.stringify(error?.response || "未知错误"));
        }
      } else {
        err("请求超时，服务器无响应！");
        local.remove("baseUrl");
        userStore.setUserInfo(null);
        router.replace({ name: "Login" });
      }
      return Promise.reject(
        error.response && error.response.data ? error.response.data : null
      );
    }
  );
  return service;
}

/**
 * @description 创建请求方法
 * @param {Object} service axios 实例
 */
function createRequest(service: any) {
  return function (config: any) {
    const env = process.env;
    let headers = {
      platform: "WEB",
      deviceId: getDeviceId(),
      ...(config.headers || {}),
      "Content-Type": get(
        config,
        "headers.Content-Type",
        // "application/json;charset=UTF-8"
        "application/x-www-form-urlencoded"
      ),
    };
    const configDefault = {
      method: "post",
      timeout: 120000,
      // baseURL: env.VITE_APP_PROXY_URL ? "" : env.VITE_APP_BASE_URL,
      baseURL: env.VITE_APP_PROXY_URL ? "" : local.get("baseUrl") || "/",
      data: {},
    };
    const option = Object.assign(configDefault, config, { headers: headers });

    return service(option);
  };
}

export function paramsSerializer(params: any) {
  return qs.stringify(params);
}

// 用于真实网络请求的实例和请求方法
export const service = createService();
export const request = createRequest(service);
