/**
 * 注：“成功输出”指的是接口执行成功回调函数的入参，“失败输出”指的是接口执行失败回调函数的入参
 *      失败输出统一为：
 *          {"msg":"失败信息"}
 * Created by chaozhong on 2015/11/25.
 * */

/*
 * JS API最终执行函数，JavaScript和原生功能交互桥梁
 *
 * @param apiName:字符串，接口名
 * @param param:字符串或JSON，调用接口需要传递的参数
 * @param success:字符串，接口调用成功回调函数名
 * @param fail:字符串，接口调用失败回调函数名
 * */
function _execute(
  invokeID,
  apiName,
  param,
  success,
  fail
) {
  try {
    if (param && typeof param !== 'string') {
      param = JSON.stringify(param);
    }
  } catch (e) {
    throw new Error(e.message);
  }
  const src =
    'xm-services://?action=jsFun' +
    '&invokeID=' +
    (invokeID || '') +
    '&apiName=' +
    (apiName || '') +
    '&param=' +
    encodeURIComponent(param || '') +
    '&success=' +
    (success || '') +
    '&fail=' +
    (fail || '');
  const element = document.createElement('iframe');
  element.setAttribute('src', src);
  element.setAttribute('style', 'display:none');
  element.setAttribute('width', '0px');
  element.setAttribute('height', '0px');
  element.setAttribute('frameborder', '0px');
  document.body.appendChild(element);
  element.parentNode.removeChild(element);

  console.info('success', success);
  console.info('fail', fail);
  console.info('invokeID', invokeID);
}

/*
 * 定义全局变量，接口回调函数的引用皆保存于此
 * */
window.XMAPICallBack = {
  callBackObjects: {},
  // 接口执行成功回调
  success: function (invokeID, data) {
    this.callBackObjects[invokeID].success(data);
    delete this.callBackObjects[invokeID];
  },
  // 接口执行失败回调
  fail: function (invokeID, data) {
    this.callBackObjects[invokeID].fail(data);
    delete this.callBackObjects[invokeID];
  }
};

/*
 * JS API创建工厂，JS API每被调用一次，创建一个实例，该实例保存API回调函数的引用
 * */
function XMAPIFactory(
  invokeID,
  apiName,
  param,
  success,
  fail
) {
  if (
    typeof success !== 'function' ||
    typeof fail !== 'function'
  ) {
    throw new Error('callback must be a function.');
  }
  this.success = success;
  this.fail = fail;
  _execute(
    invokeID,
    apiName,
    param,
    'XMAPICallBack.success',
    'XMAPICallBack.fail'
  );
}

window.xm = function (name, extraParams) {
  if (!name) {
    console.log('输入方法名');
    return;
  }
  extraParams = extraParams || {};
  const param = extraParams.param || '';
  const success = extraParams.success || function () {
  };
  const fail = extraParams.fail || function (msg) {
    throw new Error(msg);
  };
  const invokeID = name + new Date().getTime();
  window.XMAPICallBack.callBackObjects[invokeID] = new XMAPIFactory(invokeID, name, param, success, fail);
};

export default window.xm;
