/*
 * @Author: 吴文洁
 * @Date: 2020-08-31 09:34:31
 * @LastEditors: 吴文洁
 * @LastEditTime: 2020-08-31 09:35:36
 * @Description: 
 * @Copyright: 杭州杰竞科技有限公司 版权所有
 */
import qs from 'qs';
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosPromise } 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类型
}

class Axios {

  static post(
    method: string,
    url: string,
    params: any,
    options: FetchOptions = { requestType: 'json' }
  ): Promise<any> {
    const _url = `${url}?p=w&v=v${VERSION}&userType=${USER_TYPE}&token=${User.getToken()}&uid=${User.getUid()}&tid=${User.getTid()}&aid=${User.getAid()}`;
    return new Promise((resolve, reject) => {
      const { NewVersion = "5.0", currentUserInstInfo } = window;
      // const { instId } =  currentUserInstInfo;

      const instance: AxiosInstance = axios.create({
        timeout: TIME_OUT,
        responseType: 'json',
        headers: {
          instId: '123',
          p: 'w',
          v: 'VERSION',
          vn: `v${VERSION}`,
          project: PROJECT,
          userType: USER_TYPE,
          cid: User.getCid(),
          uid: User.getUid(),
          tid: User.getTid(),
          token: User.getToken(),
          bizAccountId: User.getAid(),
          xmVersion: NewVersion ? '5.0' : '4.0',
          'Content-Type': options.requestType === 'json' ? 'application/json; charset=UTF-8' : 'application/x-www-form-urlencoded',
        }
      });
      
      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 } = response.data;
        if (success || resultCode === 0) {
          return response;
        }
        message.error(ResMessage || resultMsg);
        return Promise.reject(response.data);
      }, (error): AxiosPromise => {
        message.error(error.message)
        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;

/**
 * @method fetch
 * @description 封装get方法
 * @param params
 * @param url
 * @returns { Promise }
 */
export function fetch(url: string, params: any = {}, verify: boolean = true) {
  return new Promise((resolve, reject) => {
    axios.get(url, {
      params: verify ? getVerifyParams(params) : params,
    }).then((response) => {
      resolve(response.data);
    }).catch((err) => {
      reject(err);
    });
  });
}

/**
 * @method post
 * @description 封装post方法
 * @param data
 * @param url
 * @returns { Promise }
 */

export function post(url: string, data: any = {}, verify: boolean = true) {
  const params = verify ? getVerifyParams() : {};
  const stringifyData = qs.stringify(data);

  return new Promise((resolve, reject) => {
    axios.post(url, stringifyData, {
      params,
    }).then((response) => {
      resolve(response.data);
    }).catch((err) => {
      reject(err);
    });
  });
}

/**
 * @method getVerifyParams
 * @description 如果需要验证则在请求参数上带上token和uid等参数
 * @param data
 * @returns { void }
 */

const getVerifyParams = (data: any = {}) => {
  const params = {
    // aid: Storage.getAid(),
    // tid: Storage.getTid(),
    // token: Storage.getToken(),
    // uid: Storage.getUid(),
  };

  return Object.assign({}, data, params);
};

/**
 * @method postJSON
 * @description 封装postJSON方法
 * @param data
 * @param url
 * @returns { Promise }
 */

export function postJSON(url: string, data: any = {}, verify: boolean = true) {
  const params = verify ? getVerifyParams() : {};
  return new Promise((resolve, reject) => {
    Axios.post("post",url, data).then((response) => {
      resolve(response.data);
    }).catch((err) => {
      reject(err);
    });
  });
}

export function Apollo(url: string, data: any = {}, verify: boolean = true) {
  return postJSON(`apollo/${url}`, data, verify);
}