/**
 * @description: HTTP请求方法枚举
 */
export const HttpMethod = {
  GET: "GET",
  POST: "POST",
  OPTIONS: "OPTIONS",
  PUT: "PUT",
  DELETE: "DELETE",
};

/**
 * @description: HTTP请求配置
 * @typedef {Object} RequestConfig
 * @property {string} [url] - API路径
 * @property {HttpMethod} [method] - Method类型
 * @property {any} [data] - 接口返回数据
 * @property {boolean} [needToken] - 无TOKEN触发异常捕获时，是否执行异常逻辑
 * @property {object} [header] - Header头部
 * @property {string} [dataType] - 返回的数据格式
 * @property {boolean} [noShowMsg] - 请求报错时，是否弹出message提示（默认弹出）
 */

class HttpRequest {
  static instance = null;
  constructor() {}
  static getInstance() {
    if (!this.instance) {
      this.instance = new HttpRequest();
    }
    return this.instance;
  }

  // 处理请求异常状态码
  handerErrorStatus(statusCode, requestConfig) {
    let msg = "服务找不到";
    if (statusCode === 502 || statusCode === 503) {
      msg = "服务器开小差了~";
    }
    !requestConfig.noShowMsg &&
      uni.showToast({
        title: `${msg}，错误码：${statusCode}`,
        icon: "none",
      });
    return msg;
  }

  // 处理请求异常
  handerError(err, requestConfig) {
    let msg = `请求异常`;
    if (/timeout/.test(err.errMsg)) {
      msg = "请求超时";
    }
    !requestConfig.noShowMsg &&
      uni.showToast({
        title: msg,
        icon: "none",
      });
    return msg;
  }

  // 服务器接口请求
  request(requestConfig) {
    const _this = this;
    // 兼容H5（字符串）和微信小程序（对象）场景
    let user_info = uni.getStorageSync("user_info") || {};
    if (typeof user_info === "string") {
      try {
        user_info = JSON.parse(user_info) || {};
      } catch (e) {
        user_info = {};
      }
    }
    const reqData = Object.assign(requestConfig.data, {
      buyerId: user_info.buyerId,
      flag: user_info.flag,
    });
    return new Promise((resolve, reject) => {
      uni.request({
        method: requestConfig.method,
        url: `${requestConfig.url}`,
        data: reqData,
        header: { ...(requestConfig?.header || {}), token: user_info.token },
        dataType: "json",
        success(res) {
          const code = res.statusCode || -404;
          const data = res.data;
          /** 接口请求成功*/
          if (code == 200) {
            if (["1003", "1004", "1005", "1006"].includes(data.code)) {
              uni.showModal({
                content: data.msg,
                success(res) {
                  if (res.confirm) {
                    uni.removeStorageSync("user_info");
                    uni.navigateTo({ url: "/pages/login/index" });
                  } else if (res.cancel) {
                    try {
                      uni.removeStorageSync("user_info");
                    } catch (e) {
                      console.log("登录失效catch：", e);
                    }
                    uni.reLaunch({ url: "/pages/index/index" });
                    uni.hideLoading();
                  }
                },
              });
            } else {
              resolve(data);
            }
          } else if (code === 401) {
            // 未授权
            !requestConfig.noShowMsg &&
              uni.showModal({
                title: "登录失效",
                content: "登录失效，请重新登录",
                success: (resModa) => {
                  if (resModa.confirm) {
                    uni.removeStorageSync("user_info");
                    uni.navigateTo({ url: "/pages/login/index" });
                  } else if (resModa.cancel) {
                    try {
                      uni.removeStorageSync("user_info");
                      uni.reLaunch({ url: "/pages/index/index" });
                    } catch (e) {
                      console.log("登录失效catch：", e);
                    }
                  }
                },
              });
            reject({ code, msg: "未登录", data: data });
          } else {
            //非200及401状态码-数据处理
            const errMsg = _this.handerErrorStatus(code, requestConfig);
            reject({ code, msg: errMsg, data });
          }
        },
        fail: (err) => {
          console.log("失败了", err);

          let msg = _this.handerError(err, requestConfig);
          reject({ msg });
        },
      });
    });
  }

  /**
   * @description: get请求函数
   * @param {string} url 请求地址
   * @param {Object} data 请求参数
   * @param {RequestConfig} OtherConfig request其他配置
   * @return {*}
   */
  get(url, data, OtherConfig) {
    return this.request({
      method: HttpMethod.GET,
      url,
      data,
      ...OtherConfig,
    });
  }

  /**
   * @description: post请求函数
   * @param {string} url 请求地址
   * @param {Object} data 请求参数
   * @param {Object} thrid 三方接口
   * @param {RequestConfig} OtherConfig request其他配置
   * @return {*}
   */
  post(url, data, OtherConfig) {
    return this.request({
      method: HttpMethod.POST,
      url,
      data,
      ...OtherConfig,
    });
  }

  /**
   * @description: delete请求函数
   * @param {string} url 请求地址
   * @param {Object} data 请求参数
   * @param {RequestConfig} OtherConfig request其他配置
   * @return {*}
   */
  delete(url, data, OtherConfig) {
    return this.request({
      method: HttpMethod.DELETE,
      url,
      data,
      ...OtherConfig,
    });
  }

  /**
   * @description: put请求函数
   * @param {string} url 请求地址
   * @param {Object} data 请求参数
   * @param {RequestConfig} OtherConfig request其他配置
   * @return {*}
   */
  put(url, data, OtherConfig) {
    return this.request({
      method: HttpMethod.PUT,
      url,
      data,
      ...OtherConfig,
    });
  }
}

export const httpRequest = HttpRequest.getInstance();

