/**
 * 接口请求封装
 *
 * 1、需要成功提示的，带 additional.successMessage ，如果值为'msg'，提示内容为返回的msg
 * 2、默认loading，不需要的传 additional.needLoading = false。
 */

import { URL } from "./requestUrl";
import { stringify } from 'qs';

const BASE_URL = `http://${URL}`;
let AllRequestNum = 0; // 存放请求数，以保证有请求未返回就持续loading

/**
 *
 * @param obj 接口配置数据{url,method,successMessage,needLoading}
 * @param data 接口请求数据
 */
function creatRequest(obj, data) {
  if (obj) {
    let additional = {}, url = obj.url;
    if (obj.successMessage !== undefined) additional.successMessage = obj.successMessage;
    if (obj.needLoading !== undefined) additional.needLoading = obj.needLoading;
    // DELETE 参数以问号形式拼接到url
    if (obj.method === 'DELETE') {
      url = data ? `${url}?${stringify(data)}` : url;
      data = null;
    }
    return request(url, { method: obj.method, data }, additional);
  } else {
    uni.showModal({
      title: '错误提示',
      content: '请求的接口未定义！',
      showCancel: false
    });
  }
}

/**
 * url: 请求的url
 * options: uni.request的一系列参数,常用的method和data
 * additional: { successMessage、needLoading }
 */
function request(url, options, additional) {
  if (additional.needLoading === undefined) additional.needLoading = true;
  // 加载中提示打开
  // console.log({url, options, additional});
  openCloseLoading(additional, true);
  // 模拟token,做登录的同学将这行代码移到登录成功函数中.

  const token = uni.getStorageSync('token');
  return uni.request({
    url: `${BASE_URL}${url}`,
    ...options,
    header: {
      token: token ? token : null,
      'Content-Type': 'application/json',
    }
  }).then((res) => notifyException(res, additional))
    .catch((error) => {
      if ('stack' in error && 'message' in error) {
        uni.showModal({
          title: '错误提示',
          content: '服务器异常，请稍后重试！',
          showCancel: false
        });
        console.error(`请求错误: ${url} ${error.message}`);
      }
      return error;
    });
}

// 加载中提示打开/关闭
function openCloseLoading(additional, isOpen) {
  if (additional.needLoading) {
    if (isOpen) { // 打开（如果已经打开不必重复打开）
      if (AllRequestNum === 0)
        uni.showLoading();
      AllRequestNum++;
    } else { // 关闭
      if (AllRequestNum > 0) { // 防止数值错乱
        AllRequestNum--;
        if (AllRequestNum === 0)
          uni.hideLoading();
      } else {
        AllRequestNum = 0;
      }
    }
  }
}

// 登录过期，重置请求计数，强制关闭loading
function LoginExpired(msg) {
  AllRequestNum = 0;
  uni.showModal({
    title: '提示',
    content: '登录过期,请重新登录!',
    success: function (_res) {
      if (_res.confirm) {
        uni.navigateTo({
          url: '/pages/login/login'
        });
      } else if (_res.cancel) {
        console.log('用户点击取消');
      }
    }
  });
}

//广播弹窗关闭
function dispatchEventGloal(type){
	// console.log({type,uni});
	uni.$emit(type,{});
}

function notifyException(resArr, additional) {
  openCloseLoading(additional, false);
  const [error, res] = resArr;
  if (error) {
    uni.showModal({
      title: '错误提示',
      content: JSON.stringify(error),
      showCancel: false,
	  success: function (res) {
	          if (res.confirm) {
	              dispatchEventGloal(JSON.stringify(error));
	          }
	  }
    });
    console.error(`请求错误: ${error.errMsg}`);
    return false;
  } else if (res.data.code !== 'SUCCESS') {
    const { code, msg } = res.data;
    if (code === '410' || code === '401'||code === '403') {
		
	  // 当页面被嵌套告诉主页面，token过期
	  if(window.parent){
		   console.log('window.parent',window.parent);
		   window.parent.postMessage('tokenExpired','*');
	  }
	  
      LoginExpired(msg);
    } else {
      uni.showModal({
        title: '错误提示',
        content: msg,
        showCancel: false,
		success: function (res) {
		        if (res.confirm) {
		             dispatchEventGloal(msg);
		        }
		},
      });
    }
    console.error(`错误信息: ${msg}`);
    return false;
  } else if (additional.successMessage) {
    let msg = additional.successMessage;
    uni.showToast({
      title: msg === 'msg' ? res.data.msg : msg,
			icon:'none',
			duration:1000
    });
  }
  return res.data.data ? res.data.data : true;
}

export {
  request,
  creatRequest
}
