/**
 * @note    公共工具类
 * @author  miaokefu <miaokefu@duiba.com.cn>
 * @create  2018-06-01
 * @des
 */
import Promise from 'promise-polyfill';
// import { get, post } from '@apis/common';
require('@lib/cookie/1.0.0/index');
import { get, post } from '@service/http';

const fixed = (num, frac) => {
  var str = num.toString();
  var arr = str.split('.');
  var integer = arr[0],
    tail = arr[1];
  if (!tail) tail = '';
  if (tail.length < frac) {
    for (var i = 0, j = frac - tail.length; i < j; i++) {
      tail += '0';
    }
  } else {
    tail = tail.substr(0, frac);
  }
  return integer + '.' + tail;
};

const trimZero = str => {
  if (str.substr(-1) == '0') {
    str = str.substr(0, str.length - 1);
    return trimZero(str);
  } else {
    return str;
  }
};

const tostring = num => {
  var wan = num / 10000;
  if (!Math.floor(wan)) return Math.floor(num) + '';
  var yi = num / 100000000;
  var orig = fixed(wan, 1);
  var unit = '万';
  if (!!Math.floor(yi)) {
    // 超过亿
    unit = '亿';
    orig = fixed(yi, 1);
  }
  var arr = orig.split('.');
  var integer = arr[0],
    tail = arr[1];
  tail = trimZero(tail);
  return integer + (!!tail ? '.' + tail : '') + unit;
};

/**
 * GET接口请求
 * @param url
 * @param data
 * @param success
 * @param error
 */
const httpGet = ({ url, data, success, error }) => {
  $.ajax({
    url: url,
    type: 'GET',
    data: {
      sessionKey: getUrlParameter('sessionKey'),
      sourceToken: getUrlParameter('sourceToken'),
      sourceUserId: getUrlParameter('sourceUserId'),
      ...data
    },
    timeout: 3000,
    dataType: 'json',
    success: function(data) {
      success && success(data);
    },
    error: function(xhr) {
      error && error();
    }
  });
};

/**
 * POST接口请求
 * @param url
 * @param data
 * @param success
 * @param error
 * @param type
 * @param contentType
 */
const httpPost = ({
  url,
  data,
  success,
  error,
  type = 'json',
  contentType = 'application/x-www-form-urlencoded'
}) => {
  $.ajax({
    url: url,
    type: 'POST',
    data: {
      sessionKey: getUrlParameter('sessionKey'),
      sourceToken: getUrlParameter('sourceToken'),
      sourceUserId: getUrlParameter('sourceUserId'),
      ...data
    },
    timeout: 3000,
    dataType: type,
    contentType: contentType,
    success: function(data) {
      success && success(data);
    },
    error: function(xhr) {
      error && error();
    }
  });
};

const httpGetPromise = ({ url, data }) =>
  new Promise((resolve, reject) => {
    httpGet({
      url: url,
      data: {
        sessionKey: getUrlParameter('sessionKey'),
        sourceToken: getUrlParameter('sourceToken'),
        sourceUserId: getUrlParameter('sourceUserId'),
        ...data
      },
      success: data => {
        resolve(data);
      },
      error: err => {
        reject(err);
      }
    });
  });

/**
 * POST接口请求promise
 * @param url
 * @param data
 * @param type
 * @param contentType
 */
const httpPostPromise = ({
  url,
  data,
  type = 'json',
  contentType = 'application/x-www-form-urlencoded'
}) =>
  new Promise((resolve, reject) => {
    httpPost({
      url: url,
      data: {
        sessionKey: getUrlParameter('sessionKey'),
        sourceToken: getUrlParameter('sourceToken'),
        sourceUserId: getUrlParameter('sourceUserId'),
        ...data
      },
      success: data => {
        resolve(data);
      },
      error: err => {
        reject(err);
      }
    });
  });

String.prototype.getLength = function() {
  return this.replace(/[^\x00-\xff]/gi, 'aa').length;
};

/**
 * 公用缓存set方法
 * @param {*} key
 * @param {*} value
 */
const setStorage = (key, value) => {
  // 支持localStorage
  if (window.localStorage) {
    if (value == null) {
      localStorage.removeItem(key);
    } else {
      localStorage.setItem(key, value);
    }
  }
  // 支持sessionStorage
  // else if (window.sessionStorage){
  //   if (value == null) {
  //     sessionStorage.removeItem(key);
  //   } else {
  //     value && sessionStorage.setItem(key, value);
  //   }
  // }
  // 支持cookie
  // 默认一天失效
  else if (document.cookie) {
    $.cookie(key, value, { expires: 1, path: '/' });
  }
  // 都不支持
  else {
  }
};

/**
 * 公用缓存get方法
 * @param {*} key
 */
const getStorage = key => {
  // 支持localStorage
  if (window.localStorage) {
    return window.localStorage.getItem(key);
  }
  // 支持sessionStorage
  // else if (window.sessionStorage){
  //   return sessionStorage.getItem(key);
  // }
  // 支持cookie
  else if (document.cookie) {
    return $.cookie(key);
  }
  // 都不支持
  else {
    return null;
  }
};

/**
 * 获取url中特定字符串的值
 * @param {*} name 字符串key
 * @param {*} path 默认为页面链接地址，也可自己传某段string
 */
const getUrlParameter = (name, path = window.location.href) => {
  const result =
    decodeURIComponent(
      (new RegExp('[?|&]' + name + '=([^&;]+?)(&|#|;|$)').exec(path) || [
        undefined,
        ''
      ])[1].replace(/\+/g, '%20')
    ) || null;
  return result ? result : '';
};

const replaceUrlParameter = (url, params) => {
  if (!url) {
    return url;
  }
  let base = url.split('?')[0];
  url = url.replace(base, ''); // 获取search部分
  let _params = parseUrlParams(url);
  _params = Object.assign({}, _params, params);
  return formatUrl(base, _params);
};

/**
 * 是否为android机
 * @returns {boolean}
 */
const isAndroid = () => {
  return (
    navigator.userAgent.indexOf('Android') > -1 ||
    navigator.userAgent.indexOf('Linux') > -1 ||
    navigator.userAgent.indexOf('Adr') > -1
  ); // android??;
};

const isWeiXin = () => {
  var ua = window.navigator.userAgent.toLowerCase();
  console.log(ua); //mozilla/5.0 (iphone; cpu iphone os 9_1 like mac os x) applewebkit/601.1.46 (khtml, like gecko)version/9.0 mobile/13b143 safari/601.1
  if (
    ua.match(/MicroMessenger/i) == 'micromessenger' ||
    getUrlParameter('wxdebug')
  ) {
    return true;
  } else {
    return false;
  }
};

const embedClick = (item, cb) => {
  if (item && typeof item === 'object') {
    item = JSON.stringify(item);
  }
  window.DB.exposure.singleClk({ data: item, callback: cb });
};

const embedExposure = item => {
  if (item && typeof item === 'object') {
    item = JSON.stringify(item);
  }
  window.DB.exposure.singleExp(item);
};

const sendCustomAdvertLog = (data, sessionKey) => {
  let dsm = getUrlParameter('dsm');
  let dpm = getUrlParameter('dpm');
  let dcm = getUrlParameter('dcm');

  httpPost({
    url: '/puzzle/clickPuzzleAdvert',
    data: JSON.stringify({
      sessionKey: sessionKey,
      dsm: dsm,
      dpm: dpm,
      dcm: dcm,
      gameId: getUrlParameter('id'),

      advertId: data.advertId,
      actOrderId: data.orderId,
      packageId: data.packageId
    }),
    contentType: 'application/json;charset=UTF-8',
    success: data => {}
  });
};

/**
 * @param sessionKey
 * @param data 券数据
 * @returns {string}
 */
const getAdvertClickUrl = (data, sessionKey = CFG.sessionKey) => {
  let dsm = getUrlParameter('dsm');
  let dpm = getUrlParameter('dpm');
  let dcm = getUrlParameter('dcm');

  if (data.customAd) {
    sendCustomAdvertLog(data, sessionKey);
  }

  return (
    data.clickUrl +
    `${
      data.clickUrl.indexOf('?') > -1 ? '&' : '?'
    }dpm=${dpm}&dcm=${dcm}&dsm=${dsm}`
  );
};

const isObjectEmpty = obj => {
  let sum = 0;
  for (let x in obj) {
    sum++;
  }

  return sum === 0;
};

/**
 *
 * 精确解析url，包括协议头，host，port，path等
 * @param {*} url
 * @returns
 * {
 * url:'',
 * scheme:'',
 * slash:'',
 * host:'',
 * path:'',
 * query:'',
 * hash:''
 * }
 */
function exactParseUrl(url) {
  // 解析url
  let parse_url = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^f?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
  let tamp = parse_url.exec(url),
    result = {},
    fields = [
      'ur1',
      'scheme',
      'slash',
      'host',
      'port',
      'path',
      'query',
      'hash'
    ];

  fields.forEach(function(key, index) {
    result[key] = tamp[index] ? tamp[index] : '';
  });

  return result;
}

/**
 *解析全部的参数，返回一个Object
 *
 * @returns
 */
function parseUrlParams(url = location.search) {
  var paramsArr = decodeURIComponent(url)
      .replace(/amp;/g, '')
      .split('&'),
    result = {};
  // 删除？
  paramsArr[0] = paramsArr[0].substr(1);
  for (var i = 0, j = paramsArr.length; i < j; i++) {
    var valArr = paramsArr[i].split('=');
    result[valArr[0]] = decodeURIComponent(valArr[1]);
  }

  return result;
}

/**
 * 格式化url，添加参数
 *
 * @param {*} url
 * @param {*} params
 * @returns
 */
const formatUrl = (url, params) => {
  if (!url) {
    return '';
  }
  let keys = Object.keys(params);
  if (keys.length === 0) {
    return url;
  }
  let base = url.indexOf('?') > -1 ? `${url}&` : `${url}?`;
  return keys.reduce((acc, v, i) => {
    if (i === 0) {
      return (acc += `${v}=${params[v]}`);
    } else {
      return (acc += `&${v}=${params[v]}`);
    }
  }, base);
};

// requestAnimationFrame 兼容
const requestAnimFrame = (function() {
  return function(callback) {
    window.setTimeout(callback, 1000 / 60);
  };
})();

const appendUrlParameter = (url, k, v) => {
  if (url.indexOf('?') > -1) {
    return `${url}&${k}=${v}`;
  } else {
    return `${url}?${k}=${v}`;
  }
};

const isAppDownload = () => {
  return isAndroid() && !isWeiXin() && !getUrlParameter('appPreview');
};

const toDownloadUrl = url => {
  if (url) {
    setTimeout(() => {
      window.location.href = url;
    }, 120);
  } else {
    console.error('重定向url为空');
  }
};

const deleteInvalidKey = object => {
  Object.keys(object).forEach(v => {
    //过滤掉 undefined,null,NaN
    if (
      object[v] === 'undefined' ||
      object[v] === undefined ||
      object[v] === null ||
      object[v] === 'null'
    ) {
      delete object[v];
    }
  }, {});
  return object;
};

/**
 *  设置第三方图片链接的协议和当前页面的访问协议相同
 */
const wxHeadUrlFix = url => {
  if (!url) {
    return '';
  }
  let currentProtocol = location.protocol;

  url = url.replace(/^http(s)?:/, currentProtocol);
  return url;
};

/**
 *检查环境，启动下载
 *
 * @param {*} { channel:渠道, beforeJump(cb):跳转前回调，会传入一个cb，用于控制在beforeJump中控制跳转 }
 * @returns
 */
const checkToDownload = ({
  downloadUrl,
  channel,
  beforeJump,
  noDownloadCallback,
  iosCallback = () => {
    window.location.href = '/youtui/ab/getIosDownload';
  }
}) => {
  if (!isWeiXin() && !getUrlParameter('appPreview')) {
    // 当前页面在安卓的其他浏览器中并且不在趣晒app中 自动发起下载
    if (isAndroid()) {
      if (downloadUrl) {
        if (beforeJump) {
          beforeJump(() => {
            toDownloadUrl(downloadUrl);
          });
        } else {
          toDownloadUrl(downloadUrl);
        }
      } else {
        getDownloadUrl(channel || 'yysc-cc').then(data => {
          if (beforeJump) {
            beforeJump(() => {
              toDownloadUrl(data);
            });
          } else {
            toDownloadUrl(data);
          }
        });
      }
    } else {
      iosCallback && iosCallback();
    }
  } else {
    noDownloadCallback && noDownloadCallback();
  }
};

/**
 * 保留字符数 + 省略号，字符串：游客12345678，如保留六位，则取前十个字符
 * @param str
 * @param n
 */
const reserveStr = (str, n, type = true) => {
  /**
   * 保留字符数
   * @param str
   * @param n
   */

  //  区分汉字
  if (type) {
    const subTextStr = (str, n) => {
      if (str.getLength() > n) {
        str = str.substring(0, str.length - 1);
        return subTextStr(str, n);
      }
      return str;
    };

    if (!str) {
      return '';
    }
    str = subTextStr(str, 2 * (n + 1));

    if (str.getLength() > 2 * n) {
      str = subTextStr(str, 2 * (n - 1)) + '...';
    }

    return str;
  } else {
    if (str.length <= n) {
      return str;
    }
    return str.substring(0, n) + '...';
  }
};

/**
 * 分转元，服务端统一返回分
 */
const fen2yuan = fen => {
  try {
    return parseFloat(fen / 100).toFixed(2);
  } catch (err) {
    console.error('fen2yuan=>>amount error');
    return '';
  }
};

/**
 * 获取元素到文档顶部的距离
 * @param el
 * @returns {*}
 */
const getElPositionY = el => {
  if (!el) {
    console.error('getElPositionY el must be a value');
    return 0;
  }
  let t;
  // For scrollY
  var scrollY = getScrollY();
  return scrollY + el.getBoundingClientRect().top;
};

const getScrollY = () => {
  return (
    document.documentElement.scrollTop ||
    document.body.parentNode.scrollTop ||
    document.body.scrollTop
  );
};

const scrollTo = y => {
  document.body.scrollTop = document.documentElement.scrollTop = y;
};
const turnToAppStore = (url) => {
  toDownloadUrl(
    url||'http://a.app.qq.com/o/simple.jsp?pkgname=com.youtui&ckey=CK1407435916851'
  );
};

/**
 * 节流
 * @param {Function} func
 * @param {Number} wait
 */
const throttle = (func, wait) => {
  let context, args;
  let previous = 0;

  return () => {
    let now = +new Date();
    context = this;
    args = arguments;
    if (now - previous > wait) {
      func.apply(context, args);
      previous = now;
    }
  };
};

/**
 * 防抖
 * @param {*} func
 * @param {*} wait
 */
const bounce = (func, wait) => {
  let context, args;
  let timer = 0;

  return () => {
    context = this;
    args = arguments;
    timer && clearTimeout(timer);
    timer = setTimeout(() => {
      func.apply(context, args);
    }, wait);
  };
};

/**
 * 获取网络类型
 */
const getNetworkType = () => {
  var ua = navigator.userAgent;
  var networkStr = ua.match(/NetType\/\w+/)
    ? ua.match(/NetType\/\w+/)[0]
    : 'NetType/other';
  networkStr = networkStr.toLowerCase().replace('nettype/', '');
  var networkType;
  switch (networkStr) {
    case 'wifi':
      networkType = 'wifi';
      break;
    case '4g':
      networkType = '4G';
      break;
    case '3g':
      networkType = '3G';
      break;
    case '3gnet':
      networkType = '3G';
      break;
    case '2g':
      networkType = '2G';
      break;
    default:
      networkType = 'other';
  }
  return networkType;
};

/**
 * 判断元素是否可见
 * @param {*} el 要判断的元素
 * @param {*} onVisible  元素可见时执行
 * @param {*} enable 开启判断 为false，直接跳出函数
 */
const isVisible = (el, onVisible, enable = true) => {
  if (!enable) {
    return;
  }
  if (!el) {
    return;
  }
  // 元素宽高为0，直接返回
  if (el.offsetWidth * el.offsetHeight <= 0) {
    return;
  }

  let style = window.getComputedStyle(el, null);

  // visibility隐藏情况
  if (style.visibility === 'hidden') {
    return;
  }

  let isTrack = el.getAttribute('data-istrack');
 
  if (!isTrack) {
    var brtop = getScrollY();

    var offsetTop = getElPositionY(el);

    if (
      offsetTop >= brtop &&
      offsetTop < brtop + document.documentElement.clientHeight
    ) {
      el.setAttribute('data-istrack', 1);
      onVisible && onVisible(el);
    }
  }
};

/**
 * 数组去重
 * @param {*} arr
 */
const arrayUnique = arr => {
  let obj = {};
  let result = [];
  for (let i = 0, len = arr.length; i < len; i++) {
    if (!obj[arr[i]]) {
      obj[arr[i]] = 1;
      result.push(arr[i]);
    }
  }

  return result;
};

/**
 * 安全取值函数  用于替代 object&&object.data&&object.data.clickUrl 这种深层次对象取值的语法
 *
 * @param {*} key 路径,支持 'a.b.c'和['a','b','c']
 * @param {*} obj 源数据
 * @param {*} def 默认值，取不到值时返回的默认值
 */
const delve = (obj, key, def, p) => {
  p = 0;
  key = key.split ? key.split('.') : key;
  while (obj && p < key.length) obj = obj[key[p++]];
  return obj === undefined || p < key.length ? def : obj;
};

const setBodyBgColor =  (color) => {
  document.getElementsByTagName('body')[0].style.backgroundColor = color;

}

/**
 * 为落地页添加对应的直投页参数
 * @param {*} base 落地页基础链接 带上id,type
 */
const transformLandingUrl = (base) => {
  const {
    sessionKey,
    sourceToken,
    sourceUserId,
    share_way,
    appPreview,
    shareContentIndex,
    isPic,
    version
  } = parseUrlParams();

  //  添加其他用户参数
  let ext = {
    sessionKey,
    sourceToken,
    sourceUserId,
    share_way,
    appPreview,
    shareContentIndex,
    isPic,
    version
  };

  base = formatUrl(base, deleteInvalidKey(ext));

  return base;
}
//获取落地页id。并跳转到相应的落地页
const toLandingPage = (params) => {
  get('/youtui/content/landPageId', {
    contentId: getUrlParameter("id"),
    contentType: getUrlParameter("type")
  }).then(res => {
    const {
        sessionKey,
        sourceToken,
        sourceUserId,
        share_way,
        appPreview,
        shareContentIndex,
        isPic,
        version,
      } = parseUrlParams();
      let _params = Object.assign({}, params, {sessionKey,sourceToken,sourceUserId,share_way,appPreview,shareContentIndex,isPic,version});
      let arr = '/youtui/land/index?id=' + res + "&type=7&";
      for(let key in _params) {
        arr += `${key}=` + _params[key] + '&';
      };

      window.location.href = `${location.origin}${arr}`;
  })
};

let clickTimer = 0;
const debounce = (spaceTimer, callback) => {
  clearTimeout(clickTimer);
  clickTimer = setTimeout(() => {
    callback();
  }, spaceTimer);
}
export {
  fixed,
  trimZero,
  debounce,
  tostring,
  httpGet,
  httpPost,
  httpGetPromise,
  httpPostPromise,
  reserveStr,
  setStorage,
  getStorage,
  getUrlParameter,
  replaceUrlParameter,
  isAndroid,
  isWeiXin,
  embedClick,
  embedExposure,
  getAdvertClickUrl,
  isObjectEmpty,
  exactParseUrl,
  parseUrlParams,
  formatUrl,
  requestAnimFrame,
  appendUrlParameter,
  isAppDownload,
  toDownloadUrl,
  deleteInvalidKey,
  wxHeadUrlFix,
  checkToDownload,
  fen2yuan,
  getElPositionY,
  getScrollY,
  scrollTo,
  turnToAppStore,
  throttle,
  bounce,
  getNetworkType,
  isVisible,
  arrayUnique,
  delve,
  setBodyBgColor,
  toLandingPage
};
