type RequestConfig = UniApp.RequestOptions;
type IInterceptors = {
  request?: {
    onFulfilled?: (config: RequestConfig) => RequestConfig;
    onRejected?: (error: any) => any;
  };
  response?: {
    onFulfilled?: (result: UniApp.RequestSuccessCallbackResult) => any;
    onRejected?: (error: any) => any;
  };
};

class Request {
  // 拦截器
  private readonly interceptors?: IInterceptors;

  constructor(config: { interceptors?: IInterceptors } = {}) {
    this.interceptors = config.interceptors;
  }

  /**
   * @description 统一结果处理
   */
  private resultHandle(res: Promise<any>) {
    return res.then((r) => [r, null]).catch((e) => [null, e]);
  }

  http(_config: RequestConfig): Promise<any> {
    const requestOnFulfilled = this.interceptors?.request?.onFulfilled;
    const requestOnRejected = this.interceptors?.request?.onRejected;
    const responseOnFulfilled = this.interceptors?.response?.onFulfilled;
    const responseOnRejected = this.interceptors?.response?.onRejected;

    let config: RequestConfig = { ..._config, header: _config.header || {} };
    if (requestOnFulfilled) {
      try {
        config = requestOnFulfilled(config);
      } catch (e) {
        requestOnRejected?.(e);
      }
    }
    return new Promise((resolve, reject) => {
      xma.request({
        ...config,
        success: (result) => {
          if (`${result.statusCode}`.startsWith('2')) {
            resolve(responseOnFulfilled?.(result) || result);
          } else {
            reject(responseOnRejected?.(result) || result);
          }
        },
        fail: (error) => {
          reject(responseOnRejected?.(error) || error);
        },
      });
    });
  }

  post(url: string, data: any = {}, config?: RequestConfig) {
    return this.resultHandle(
      this.http({
        method: 'POST',
        url,
        data,
        ...config,
      }),
    );
  }

  get(url: string, data: any = {}, config?: RequestConfig) {
    return this.resultHandle(
      this.http({
        method: 'GET',
        url,
        data,
        ...config,
      }),
    );
  }
}

const request = new Request({
  interceptors: {
    request: {
      onFulfilled(config) {
        return config;
      },
    },
    response: {
      onFulfilled(result) {
        return result.data;
      },
      onRejected(error) {
        return error;
      },
    },
  },
});

export default request;
