import ToastContainer from './ToastContainer.vue';

const instances = [];
let count = 1;
const containers = {};
const instancesIds = {};

const Message = function (options) {
  const userOnClose = options.onClose;
  const position = options.position || 'top-center';
  const hasMask = options.hasMask || false;
  const containerKey = position + (hasMask ? '-mask' : '');
  let containerEl = containers[containerKey];

  if (!containerEl) {
    containerEl = containers[containerKey] = document.createElement('div');
    containerEl.className = [
      'itf-toast-container toast-container',
      'is-' + position,
      hasMask ? 'has-mask' : ''
    ].filter(Boolean).join(' ');
    document.body.appendChild(containerEl);
  }

  if (options.zIndex) {
    containerEl.style.zIndex = options.zIndex;
  }

  if (options.Id && options.closeById) {
    Message.closeById(options.Id);
    return;
  }

  const id = count++;
  options.onClose = function () {
    Message.close(id, userOnClose);
  };
  const parent = document.getElementById('itf-app');

  const instance = new ToastContainer({
    parent: $nuxt.$el.__vue__,
    el: document.createElement('itf-toast-container'),
    data: options
  });

  instance.id = id;
  instance.containerKey = containerKey;

  // for position of bottom-*
  if (position.indexOf('bottom') === 0 && containerEl.firstChild) {
    containerEl.insertBefore(instance.$el, containerEl.firstChild);
  } else {
    containerEl.appendChild(instance.$el);
  }
  instance.show = true;

  instances.push(instance);
  instancesIds[options.Id] = instance;

  return instance;
};

Message.close = function (id, userOnClose) {
  for (let i = 0, len = instances.length; i < len; i++) {
    if (id === instances[i].id) {
      const { containerKey, hasMask } = instances[i];
      // 响应options.onClose
      if (typeof userOnClose === 'function') {
        userOnClose(instances[i]);
      }
      instances[i] = null;
      instances.splice(i, 1);

      const index = instances.findIndex(function (e) {
        return e.containerKey === containerKey;
      });
      if (hasMask && index === -1) {
        setTimeout(function () {
          containers[containerKey].remove();
          containers[containerKey] = null;
        }, 300);
      }
      break;
    }
  }

  setTimeout(function () {
    if (instances.length === 0) {
      for (const type in containers) {
        if (containers[type]) {
          containers[type].remove();
          containers[type] = null;
        }
      }
    }
  }, 3000);
};

Message.closeAll = function () {
  for (let i = instances.length - 1; i >= 0; i--) {
    instances[i].close();
  }
};

Message.closeById = function (id) {
  if (instancesIds[id]) {
    instancesIds[id].close();
    delete instancesIds.id;
  }
}

const types = ['info', 'success', 'error', 'warning', 'loading'];

types.forEach((type) => {
  Message[type] = function (options) {
    options = typeof options === 'string' ? { message: options } : options;
    return Message({ ...options, type });
  };
});
Message.toast = (options) => {
  return Message(options);
};

export default Message;
