'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _pathExtra = require('path-extra');

var _pathExtra2 = _interopRequireDefault(_pathExtra);

var _electron = require('electron');

var _lodash = require('lodash');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const { config, ROOT } = window;
const NOTIFY_DEFAULT_ICON = _pathExtra2.default.join(ROOT, 'assets', 'icons', 'icon.png');

function maybeFunctionString(func, args) {
  if (typeof func === 'function') return func(args);
  return func;
}

function defaultAs(val, defaultVal, typeofReq) {
  if (val == null) return defaultVal;
  if (typeofReq && typeof val !== typeofReq) return defaultVal;
  return val;
}

function _ref(v) {
  return v != null;
}

function nonNull(a) {
  return (0, _lodash.pickBy)(a, _ref);
}

const THROTTLE_TIME = 1000;
const VOLUME_ZERO = 0.0001;
const defaultNotifOptions = {
  title: 'poi',
  icon: NOTIFY_DEFAULT_ICON,
  audio: `file://${ROOT}/assets/audio/poi.mp3`,
  type: 'others'

  /* Options:
   * [Basic]
   *   type: string. Configs will be fetched from ''
   *   title: string or (([args]) => string)
   *   message: string or (([args]) => string)
   *   args: anything, will be passed to message function and title function
   *   groupKey: anything, when true and ===, will be grouped when called
   *     multiple times in a short time
   * [Read from config, but you can specify]
   *   enabled:
   *   volume: [0.0, 1.0]
   *   silent: Boolean, make volume always 0
   *   audio: file path (with file://)
   *   icon: file path
   */

};
function _ref2(info) {
  return o => {
    if (!o) return;
    info.options = _extends({}, info.options, nonNull(o));
    info.buffer = (info.buffer || []).concat([o.args]);
    info.notify();
  };
}

function _ref3() {
  return _electron.remote.getCurrentWindow().focus();
}

function _ref4(sound) {
  return sound.play();
}

function _ref5(type) {
  return (0, _lodash.throttle)(_ref4, THROTTLE_TIME, { leading: true, trailing: false });
}

class NotificationCenter {
  constructor() {
    this.notify = o => {
      if (!('groupKey' in o) && 'type' in o) o = _extends({}, o, { groupKey: o.type });
      const notifyFunc = o.groupKey ? this._buildGroupedNotify(o.groupKey) : this._doNotify;
      notifyFunc(o);
    };

    this._buildGroupedNotify = (0, _lodash.memoize)(groupKey => {
      const groupInfo = {};
      groupInfo.notify = (0, _lodash.debounce)(this._groupedNotifyRun(groupInfo), THROTTLE_TIME);
      return this._groupedNotify(groupInfo);
    });
    this._groupedNotify = _ref2;

    this._groupedNotifyRun = info => () => {
      const { title: titleFunc, message: messageFunc } = info.options;
      const title = maybeFunctionString(titleFunc, info.buffer);
      const message = maybeFunctionString(messageFunc, info.buffer);

      const options = info.options;
      if (title) options.title = title;
      if (message) options.message = message;
      this._doNotify(options);
      info.buffer = [];
      info.options = {};
    };

    this._doNotify = o => {
      const globalConfig = config.get(`poi.notify`, {});
      if (!(0, _lodash.get)(globalConfig, 'enabled', true)) return;
      const type = o.type || 'others';
      const typeConfig = o.type ? defaultAs(globalConfig[type], {}, 'object') : {};
      if (!(0, _lodash.get)(typeConfig, 'enabled', true)) return;
      const mergedConfig = _extends({}, defaultNotifOptions, nonNull(globalConfig), nonNull(typeConfig), nonNull(o));
      const volume = (0, _lodash.get)(globalConfig, 'volume', 1) * (0, _lodash.get)(typeConfig, 'volume', 1) * ((0, _lodash.get)(mergedConfig, 'silent', false) ? 0 : 1);
      const title = mergedConfig.title;
      const message = mergedConfig.message;
      if (message) {
        const currentNotif = new Notification(title, {
          icon: mergedConfig.icon,
          body: message,
          silent: true
        });
        currentNotif.onclick = _ref3;
      }
      if (volume > VOLUME_ZERO) {
        const sound = new Audio(mergedConfig.audio);
        sound.volume = volume;
        this._throttlePlaySound(type)(sound);
      }
    };

    this._throttlePlaySound = (0, _lodash.memoize)(_ref5);
  }

  // o: options
}

const notifCenter = new NotificationCenter();

exports.default = notifCenter;

// Backward compatibility

window.notify = (msg, options) => {
  options = _extends({}, options, {
    message: msg,
    volume: config.get('poi.notify.volume', 0.8),
    type: options ? options.type || "others" : undefined
  });
  notifCenter.notify(options);
};
module.exports = exports['default'];