
import { INtvCallbackResult } from '../types/INtvDtoProtocol';
import { isArray, get, parse, deepParseJson, stringify } from 'para-utils';
import { hasQueryString, getQueryString, modifyQueryString } from 'para-utils';
import { INtvCallbackParam, INtvInvokeParam, IUrlNtvThird } from '../types/INtvDtoProtocol';

/**
 * NTV URL封装判断是否存在(ntv_third)参数
 * @param url 待拼接的URL地址可选，如果没有则使用当前H5地址
 * @returns boolean true:存在, false:不存在
 */
export const hasUrlNtvThird = (url?: string) => {
  return hasQueryString('ntv_third', url);
};

/**
 * NTV URL封装获取参数对象的值: (ntv_third)参数
 * @param url 待拼接的URL地址可选，如果没有则使用当前H5地址
 * @returns object as IUrlNtvThird
 */
export const getUrlNtvThird = (url?: string) => {
  return parse(getQueryString('ntv_third', url) || {}) as IUrlNtvThird;
};

/**
 * NTV URL封装设置参数对象的值:  (ntv_third)参数
 * @param url 待拼接的URL地址
 * @param ntvThird 待拼接URL的NTV参数对象
 * @returns string 拼接好的URL
 */
export const setUrlNtvThird = (url: string, ntvThird: IUrlNtvThird) => {
  return modifyQueryString(url, {
    ntv_third: stringify({ cbPluginName: ntvThird.cbPluginName, cbData: ntvThird.cbData } as IUrlNtvThird),
  });
};

/**
 * 解析从native端获取的字符串
 * @returns result 
 *    @returns {String} tagName 标识字符串，如标识用户点击事件:'click_navbar_left'
 *    @returns {Object} cbData 数据字符串CBData的结果，解析方法：deepParse(CBData),需注意parse可能导致的报错
 */
export function parseCallBackDataFromNative<K>(args?: string | string[]): INtvCallbackResult<K> {
  const result: INtvCallbackResult<K> = { tagName: '', cbData: {} as K };
  const arg: string = isArray(args) ? (args as any[])[0] : args;
  if (arg) {
    console.log('parseCallBackDataFromNative args: ', arg);
    const parseCallBackDataResult = parse(decodeURIComponent(arg)) as INtvCallbackParam;
    console.log('parsedNativeCallbackResult:', parseCallBackDataResult);
    result.tagName = get(parseCallBackDataResult, 'param.tagName', '');
    result.cbData = deepParseJson(get(parseCallBackDataResult, 'param.CBData', JSON.stringify({})) || {});
  }
  return result;
}

/**
 * 拼接native端bridge方法的JSON字符串参数
 * @param param bridge 调用的方法的参数对象
 * @param pluginName 可选参数 回调h5方法名 window.pluginName()
 */
export function buildBridgeParameter(param?: any, pluginName?: string) {
  const ntvParam: INtvInvokeParam = {
    // ios 解析null时会报错，所以这里默认为空对象
    param: param || {}
  };
  if (pluginName) {
    ntvParam.CBPluginName = pluginName;
  }
  return encodeURIComponent(stringify(ntvParam));
}