import _Object$keys from "@babel/runtime-corejs2/core-js/object/keys";
import "core-js/modules/web.dom.iterable";
import _Date$now from "@babel/runtime-corejs2/core-js/date/now";
import _Promise from "@babel/runtime-corejs2/core-js/promise";

/*
 * @Author: lijianzhang
 * @Date: 2018-10-28 20:31:24
 * @Last Modified by: lijianzhang
 * @Last Modified time: 2019-02-14 18:21:29
 */
import sha1 from 'crypto-js/sha1';
import Event from 'eventemitter3';
import merge from 'lodash/merge';
import isEqual from 'lodash/isEqual';
import debounce from 'lodash/debounce';
import { isSSR } from '../../utils/constant'; // udesk 配置信息

const imUserKey = '5f4ccb0eae5588fe36c8f8c797bd83fe';
const code = '2fc6j4ag';
const link = 'https://ttxsapp.udesk.cn/im_client/?web_plugin_id=52568&group_id=89541';
let windowloaded = false;
/**
 * 确保 udesk iframe 在 页面 load 之后加载
 *
 * @returns
 */

function onWindowLoad() {
  return new _Promise(resolve => {
    if (windowloaded) return resolve();

    function onLoad() {
      windowloaded = true;
      window.removeEventListener('load', onload);
      resolve();
    }

    if (window) {
      window.addEventListener('load', onLoad);
    }
  });
}

onWindowLoad();
/**
 * 封装了 udesk 的使用方式
 *
 * @class Udesk
 * @extends {Event}
 */

class Udesk extends Event {
  constructor() {
    super(); // 当前应该显示的文本, 会根据客服是否上线而变化

    this.label = ''; // 唯独消息的数目

    this.unread = 0;
    this.config = null;
    this.panelStyle = {};
    this.firstShow = true;
    this.isShow = false;
    this.lastConfig = null;
    this.setConfig = debounce(this._setConfig.bind(this), 1000, {
      trailing: true
    });
  }
  /**
   * 获取随机字符串
   */


  getNonce(num) {
    let s = '';

    while (s.length < num) {
      const n = Math.floor(Math.random() * 62);
      if (n < 10) s += n;else if (n < 36) s += String.fromCharCode(n + 55); // AZ
      else s += String.fromCharCode(n + 61); // az
    }

    return s;
  }
  /**
   *
   *
   * @param {} config
   * @param string config.code - udesk配置信息
   * @param string config.link - udesk配置信息
   * @param string config.onlineText - 客服在线显示文本，默认为 **udesk管理台配置文案**
   * @param string config.offlineText - 客服在线显示文本，默认为 **客服离线显示文本 **udesk管理台配置文案**
   * @param {[string]: string} config.css  style - 按钮样式
   * @param {}  config.panel - 聊天面板
   * @param {} config.customer  - 客户信息 [参考](http://www.udesk.cn/doc/thirdparty/webim/#_11)
   * @param {title: string; url: string; image: string, <自定义参数>: string}  config.product - 客户信息 [参考](http://www.udesk.cn/doc/thirdparty/webim/#_11)
   */


  _setConfig(config = {}) {
    if (isSSR()) return;
    if (isEqual(this.lastConfig, config)) return; // 避免重复修改

    this.lastConfig = config;
    const self = this;
    const finalConfig = merge({
      code,
      link,
      css: {
        display: 'none'
      },
      customer: {},
      panel: {
        css: this.panelStyle,

        onToggle({
          visible
        }) {
          // 不默认打开聊天面板
          if (visible && !self.isShow) {
            self.hide();
          }

          if (!visible) {
            self.isShow = false;
          }

          self.emit('toggle', visible);
        }

      },

      onUnread({
        count
      }) {
        self.unread = count;
        self.emit('onunread', count);
      }

    }, config);

    if (finalConfig.customer && finalConfig.customer.web_token) {
      const customer = { ...config.customer
      };

      const timestamp = _Date$now();

      const nonce = this.getNonce(14); // signature 固定格式

      const signature = sha1(`nonce=${nonce}&timestamp=${timestamp}&web_token=${customer.web_token}&${imUserKey}`).toString().toUpperCase();
      customer.nonce = nonce;
      customer.timestamp = timestamp;
      customer.signature = signature;
      finalConfig.customer = customer;
    }

    this.config = finalConfig;
    onWindowLoad().then(() => this.runUdeskScript());
  }

  runUdeskScript() {
    if (window.ud) {
      const udeskIframe = document.getElementById('udesk_iframe');

      if (udeskIframe && !this.__firstSetIframeSrc) {
        this.__firstSetIframeSrc = true;
        /**
         * 为什么特意对iframe.src处理
         * 原因： 重新修改udesk配置的时候，udesk内部会修改iframe的地址，会使浏览器的历史记录存入了udesk的更变地址，从而导致浏览器回退不正常
         * 要想要避免被存入浏览记录，那么在设置iframe的src的时候， iframe不能存在于dom树上， 而且udesk脚本，内部持有这个iframe
         * 所以不可以通过新建iframe的方式， 那么就让udesk在修改src前先让iframe脱离dom， 修改完后再插入dom中
         */

        Object.defineProperty(udeskIframe, 'src', {
          configurable: true,

          set(value) {
            const parentElement = udeskIframe.parentElement;
            udeskIframe.setAttribute('src', value);
            parentElement.appendChild(udeskIframe);
          },

          get() {
            return udeskIframe.attributes.src;
          }

        });
      }
    }

    if (!window.ud) {
      (function (a, h, c, b, f, g) {
        a['UdeskApiObject'] = f;

        a[f] = a[f] || function () {
          (a[f].d = a[f].d || []).push(arguments);
        };

        g = h.createElement(c);
        g.async = 1;
        g.charset = 'utf8';
        g.src = b;
        c = h.getElementsByTagName(c)[0];
        c.parentNode.insertBefore(g, c);
      })(window, document, 'script', '//assetscli.udesk.cn/im_client/js/udeskApi.js', 'ud');
    }

    window.ud(this.config);

    if (this.config.panel && this.config.panel.css) {
      this.setPanelStyle(this.config.panel.css);
    }

    this.wachUdeskLabel();
  }

  setPanelStyle(style) {
    const panel = document.getElementById('udesk_panel');

    if (panel) {
      _Object$keys(style).forEach(k => {
        panel.style[k] = style[k];
      });
    }
  }
  /**
   * 显示聊天面板
   *
   * @memberof Udesk
   */


  show() {
    if (!window.ud) return;

    if (this.firstShow) {
      if (!this.config) throw new Error('udesk 没有配置， 请执行 setConfig 配置');
      window.ud(this.config);
      this.firstShow = false;
    }

    this.isShow = true;
    this.unread = 0;
    this.emit('onunread', 0);
    window.ud.showPanel();
  }
  /**
   * 隐藏聊天面板
   */


  hide() {
    if (window.ud) window.ud.hidePanel();
  }
  /**
   * 开关切换
   */


  toggle() {
    this.isShow ? this.hide() : this.show();
  }

  getLabel() {
    this.btn = document.getElementById('udesk_btn');

    if (this.btn) {
      this.btn.style.display = 'none';
      const label = this.label;
      this.label = document.getElementById('udesk_btn_text').innerHTML;

      if (this.label !== label) {
        this.emit('onlabel', this.label);
      }
    }
  }

  wachUdeskLabel() {
    this.timer = setTimeout(() => {
      this.getLabel();
      this.wachUdeskLabel();
    }, 1000);
  }

  destroy() {
    clearTimeout(this.timer);
  }

}

export default new Udesk();