/*
 * @Author: 吴文洁
 * @Date: 2020-08-31 09:34:31
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2021-06-24 19:34:21
 * @Description: 
 * @Copyright: 杭州杰竞科技有限公司 版权所有
 */
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosPromise, AxiosError } from 'axios';
import { message } from 'antd';

import { BASIC_HOST, TIME_OUT, USER_TYPE, VERSION, PROJECT } from '@/domains/basic-domain/constants';

import User from './user';

interface FetchParams {
  url: string,
  data: any,
  options?: FetchOptions
}

interface FetchOptions {
  requestType: string,   // 请求类型  form为表单类型   json为json类型，默认json类型
  reject: boolean,
}
interface HeadersType{
  storeId?:any,
  storeUserId?:any,
  userId?:any,
  xmtoken?:any
}
class Axios {
  static post(
    method: string,
    url: string,
    params: any,
    options: FetchOptions = { requestType: 'json', reject: false }
  ): Promise<any> {
    const _url = `${url}?storeId=${User.getStoreId()}&token=${User.getToken()}&storeUserId=${User.getStoreUserId()}&userId=${User.getUserId()}`;
    return new Promise((resolve, reject) => {
      let headerObject:HeadersType={};
      if(User.getStoreId()){
        headerObject.storeId =  User.getStoreId();
      }
      if(User.getStoreUserId()){
        headerObject.storeUserId =  User.getStoreUserId();
      }
      if(User.getUserId()){
        headerObject.userId =  User.getUserId();
      }
      if(User.getToken()){
        headerObject.xmtoken =  User.getToken();
      }
      const instance: AxiosInstance = axios.create({
        timeout: TIME_OUT,
        responseType: 'json',
        headers: {
          ...headerObject,
          product: "xmCloudClass",
          'Content-Type': options.requestType === 'form' ? 'application/x-www-form-urlencoded' : 'application/json; charset=UTF-8',
        }
      });
      
      if (method !== 'GET' && options.requestType === 'form') {
        instance.defaults.transformRequest = [(queryParam): string => {
          let ret: string = '';
          const queryKeys = Object.keys(queryParam);
          queryKeys.forEach((item: string, index: number): void => {
            if (index < queryKeys.length - 1) {
              ret += `${encodeURIComponent(item)}=${encodeURIComponent(queryParam[item])}&`;
            } else {
              ret += `${encodeURIComponent(item)}=${encodeURIComponent(queryParam[item])}`;
            }
          });
          ret.replace(/&$/, '');
          return ret;
        }]
      }

      instance.interceptors.request.use((config: AxiosRequestConfig): AxiosRequestConfig => {
        return config;
      }, (error: Error): Promise<any> => {
        return Promise.reject(error);
      })

      instance.interceptors.response.use((response: AxiosResponse): AxiosResponse | AxiosPromise => {
        const { message: ResMessage, success, resultMsg, resultCode,code} = response.data;
        if (success || resultCode === 0) {
          return response;
        } else if (!options.reject) {
          message.error(ResMessage || resultMsg);
        }
        return Promise.reject(response.data);
      }, (error): AxiosPromise => {
        const requestStatus = error.request.status
        switch (requestStatus){
          case 401:
            User.removeUserId();
            User.removeToken();
            window.RCHistory.replace('/login');
          break;
          case 403:
            message.error('暂无查看权限');
            window.RCHistory.replace('/login');
            return Promise.reject();
          break;
          default:
            message.error(error.message);
          break;
        }
        return Promise.reject(error.message);
      });

      let config: any;
      if (method === 'GET') {
        config = Object.assign({ params, url: `${BASIC_HOST}${_url}`, method });
      } else {
        config = Object.assign({ data: params, url: `${BASIC_HOST}${_url}`, method });
      }

      instance(config).then((res: AxiosResponse): void => {
        resolve(res.data);
      }).catch((error: Error) => {
        reject(error);
      })
    })
  }
}

export default Axios;




