
import request from './request';
import { Loading } from 'element-ui';
import Qs from 'qs';
import Cookies from 'js-cookie';

// 兼容finally
if (!Promise.finally) {
  Promise.prototype.finally = function(callback) {
    const P = this.constructor;
    return this.then(
      value => P.resolve(callback()).then(() => value),
      reason =>
        P.resolve(callback()).then(() => {
          throw reason;
        })
    );
  };
}

const isSuccess = val => val === 200 || val === '200';

function showLoding(bool = false) {
  if (!bool) {
    return null;
  }
  return Loading.service({
    lock: true,
    spinner: 'el-icon-loading',
    background: 'rgba(0, 0, 0, 0.8)',
    fullscreen: true,
    text: '数据加载中...'
  });
}

function hideLoading(loading) {
  loading.close();
}

const axiosConfig = {
  headers: { 
      userToken: Cookies.get('_idp_session') || null
     }
};

const axios = {
  request(option = {}) {
    return new Promise((resolve, reject) => {
      const loading = showLoding(option.loading);
      request
        .request(option, { ...axiosConfig })
        .then(({ data = {} }) => {
          if (isSuccess(data.result)) {
            resolve(data.content);
          }
          reject(data.msg);
        })
        .catch(error => reject(error))
        .finally(() => {
          loading && hideLoading(loading);
        });
    });
  },
  getBu(url, params, option = {}) {
    return new Promise((resolve, reject) => {
      const loading = showLoding(option.loading);
      request
        .get(url, { params }, option, { ...axiosConfig })
        .then(({ data = {} }) => {
          resolve(data);
        })
        .catch(error => reject(error))
        .finally(() => {
          loading && hideLoading(loading);
        });
    });
  },
  get(url, params, option = {}) {
    return new Promise((resolve, reject) => {
      const loading = showLoding(option.loading);
      request
        .get(url, { params }, option, { ...axiosConfig })
        .then(({ data = {} }) => {
          if (isSuccess(data.result)) {
            resolve(data.content);
          }
          reject(data.msg);
        })
        .catch(error => reject(error))
        .finally(() => {
          loading && hideLoading(loading);
        });
    });
  },
  post(url, params, option = {}) {
    return new Promise((resolve, reject) => {
      const loading = showLoding(option.loading);
      request
        .post(url, params, option, { ...axiosConfig })
        .then(({ data = {} }) => {
          if (isSuccess(data.result)) {
            resolve(data.content);
          }
          reject(data.msg);
        })
        .catch(error => reject(error))
        .finally(() => {
          loading && hideLoading(loading);
        });
    });
  },
  put(url, params, option = {}) {
    return new Promise((resolve, reject) => {
      const loading = showLoding(option.loading);
      request
        .put(url, params, option, { ...axiosConfig })
        .then(({ data = {} }) => {
          if (isSuccess(data.result)) {
            resolve(data.content);
          }
          reject(data.msg);
        })
        .catch(error => reject(error))
        .finally(() => {
          loading && hideLoading(loading);
        });
    });
  },
  delete(url, params, option = {}) {
    option.params = params;
    return new Promise((resolve, reject) => {
      const loading = showLoding(option.loading);
      request
        .delete(url, option, { ...axiosConfig })
        .then(({ data = {} }) => {
          if (isSuccess(data.result)) {
            resolve(data.content);
          }
          reject(data.msg);
        })
        .catch(error => reject(error))
        .finally(() => {
          loading && hideLoading(loading);
        });
    });
  },
  arraybuffer(url, params, option = {}) {
    option.url = url;
    option.method = (option.method || 'get').toLocaleLowerCase();
    // option.headers = { 'Content-Type': 'application/json,charset=utf-8' };
    option.responseType = 'arraybuffer';
    switch (option.method) {
      case 'get':
      case 'delete':
        option.params = params;
        break;
      default:
        option.data = Qs.stringify(params);
        break;
    }
    return request.request(option);
  }
};

export default axios;

export const restApi = (base, option = {}) => ({
  base,
  table: `${base}s`,
  detail: id => axios.get(`${base}/${id}`, null, option, { ...axiosConfig }),
  save: data => axios.post(base, data, option, { ...axiosConfig }),
  update: data => axios.put(`${base}/${data.id}`, data, option, { ...axiosConfig }),
  del: id => axios.delete(`${base}/${id}`, null, option, { ...axiosConfig })
});
