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

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

interface IResponse<T> {
  code: number;
  data: T;
  msg: 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",
    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',
        Authorization: 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) => {
          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 (res.code === 21005 || res.code === 21000) {
            clearToken();
            setTimeout(() => {
              uni.reLaunch({
                url: "/pages/map/index",
              });
            }, 1000);
            throw {
              errMsg: "请重新登录",
            };
            // Token过期 废弃
            // eslint-disable-next-line promise/no-nesting
            // return refresh().then((token) => {
            //   return WxRequest<IResponse<R>>({
            //     url: `${url}${query ? (urlHasParams ? '&' : '?') : ''}${query}`,
            //     method,
            //     data,
            //     header: {
            //       ...header,
            //       Authorization: token
            //     }
            //   })
            // })
          }
          return res;
        })
        .then((res) => {
          // eslint-disable-next-line no-console
          // console.log("接口返回", res);
          const { msg } = res || {
            msg: "出现错误",
          };
          if (res && msg === "OK") {
            resolve(res.data);
          } else {
            throw {
              errMsg: msg,
            };
          }
        })
        .catch((err) => {
          if (err && err.errMsg && 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);
  }
}

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();
