import { clearToken } from "../api/auth";

interface IOptions {
  data?: any;
  params?: any;
  header?: any;
  statusCodeHandle?: boolean;
}

interface IResponse<T> {
  code: number;
  data: T;
  message: string;
}

class Http {
  private baseUrl: string;
  private header?: any;

  constructor(baseUrl?: string, header?: any) {
    this.baseUrl = baseUrl || "";
    if (header) {
      this.header = header;
    }
  }

  request<R = any>(
    method: "GET" | "POST" | "PUT",
    api: string,
    options?: IOptions
  ): Promise<R> {
    return new Promise((resolve, reject) => {
      if (!options) {
        options = {
          statusCodeHandle: true,
        };
      }
      const url = this.baseUrl + api;
      const urlHasParams = url.indexOf("?") >= 0;
      const header = {
        // 'content-type': 'application/json',
        satoken: getApp<any>().globalData.token || "",
        accessToken: getApp<any>().globalData.token || "",
        ...(this.header || {}),
        ...(options.header || {}),
      };
      const data = options.data || {};
      const params = options.params || {};
      const query = Object.keys(params)
        .map(
          (key) =>
            `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
        )
        .join("&");

      WxRequest<IResponse<R>>({
        url: `${url}${query ? (urlHasParams ? "&" : "?") : ""}${query}`,
        method,
        data,
        header,
      })
        .then((res) => {
          // console.log(res)
          // 刷新token 已废弃
          // if (res.code === 888) {
          //   // eslint-disable-next-line promise/no-nesting
          //   return WxRequest<IResponse<R>>({
          //     url: `${url}${query ? (urlHasParams ? "&" : "?") : ""}${query}`,
          //     method,
          //     data,
          //     header: {
          //       ...header,
          //       Authorization: getApp<any>().globalData.token || "",
          //     },
          //   });
          // }
          if ([21005, 21000, 10001].includes(Number(res.code))) {
            const hasToken = getApp<any>().globalData.token;
            clearToken();
            if (hasToken) {
              setTimeout(() => {
                uni.reLaunch({
                  url: "/pages/map/map",
                });
              }, 1500);
            }
            throw {
              errMsg: hasToken ? "请重新登录" : "",
              _suppressToast: !hasToken,
            };
          }
          return res;
        })
        .then((res) => {
          // eslint-disable-next-line no-console
          // console.log("接口返回", res);
          const { message = '' } = res || {
            msg: "出现错误",
          };
          if (res && message === "ok") {
            resolve(res.data);
          } else {
            throw {
              errMsg: message,
            };
          }
        })
        .catch((err) => {
          const suppressToast = err && err._suppressToast;
          if (err) {
            delete err._suppressToast;
          }
          if (err && err.errMsg && !suppressToast && options && options.statusCodeHandle) {
            uni.showToast({
              title: `${err.errMsg}`,
              icon: "none",
            });
          }
          reject(err);
        });
    });
  }

  get<R = any>(api: string, options?: IOptions) {
    return this.request<R>("GET", api, options);
  }

  post<R = any>(api: string, options?: IOptions) {
    return this.request<R>("POST", api, options);
  }

  put<R = any>(api: string, options?: IOptions) {
    return this.request<R>("PUT", api, options);
  }
}

export function WxRequest<T = any>(
  option: UniNamespace.RequestOptions
): Promise<T> {
  return new Promise((resolve, reject) => {
    uni.request({
      ...option,
      success(res: any) {
        // console.log('微信返回', res)
        const { statusCode, header } = res;
        // if (header["Authorization"]) {
        //   setToken(header["Authorization"]);
        //   resolve({
        //     ...res.data,
        //     code: 888,
        //   });
        //   return;
        // }
        if (statusCode > 200) {
          reject({
            errMsg: `${option.url}：${statusCode}`,
          });
        }
        resolve(res.data);
      },
      fail: reject,
    });
  });
}

export default Http;

export const http = new Http();
