import bowser from 'bowser';

import Event from '../Event';
import MainHelper from '../helpers/MainHelper';
import {addCssClass, addDomElement, getPlatformNotificationIcon, once, removeDomElement} from '../utils';
import { SlidedownPermissionMessageOptions } from '../models/AppConfig';

export default class Popover {
  public options: SlidedownPermissionMessageOptions;
  public notificationIcons: NotificationIcons | null;

  static get EVENTS() {
    return {
      ALLOW_CLICK: 'popoverAllowClick',
      CANCEL_CLICK: 'popoverCancelClick',
      SHOWN: 'popoverShown',
      CLOSED: 'popoverClosed',
    };
  }

  constructor(options?: SlidedownPermissionMessageOptions) {
    if (!options) {
        options = MainHelper.getSlidedownPermissionMessageOptions(OneSignal.config.userConfig.promptOptions);
    }
    this.options = options;
    this.options.actionMessage = options.actionMessage.substring(0, 90);
    this.options.acceptButtonText = options.acceptButtonText.substring(0, 15);
    this.options.cancelButtonText = options.cancelButtonText.substring(0, 15);

    this.notificationIcons = null;
  }

  async create() {
    if (this.notificationIcons === null) {
      const icons = await MainHelper.getNotificationIcons();

      this.notificationIcons = icons;

      // Remove any existing container
      if (this.container) {
          removeDomElement('#onesignal-popover-container');
      }

      let icon = this.getPlatformNotificationIcon();
      let defaultIcon = `data:image/svg+xml;charset=utf-8,%3Csvg%20width%3D%2239.5%22%20height%3D%2240.5%22%20viewBox%3D%220%200%2079%2081%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Ctitle%3EOneSignal-Bell%3C%2Ftitle%3E%3Cg%20fill%3D%22%23BBB%22%20fill-rule%3D%22evenodd%22%3E%3Cpath%20d%3D%22M39.96%2067.12H4.12s-3.2-.32-3.2-3.36%202.72-3.2%202.72-3.2%2010.72-5.12%2010.72-8.8c0-3.68-1.76-6.24-1.76-21.28%200-15.04%209.6-26.56%2021.12-26.56%200%200%201.6-3.84%206.24-3.84%204.48%200%206.08%203.84%206.08%203.84%2011.52%200%2021.12%2011.52%2021.12%2026.56s-1.6%2017.6-1.6%2021.28c0%203.68%2010.72%208.8%2010.72%208.8s2.72.16%202.72%203.2c0%202.88-3.36%203.36-3.36%203.36H39.96zM27%2070.8h24s-1.655%2010.08-11.917%2010.08S27%2070.8%2027%2070.8z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E`;
      let dialogHtml = `<div id="normal-popover"><div class="popover-body"><div class="popover-body-icon"><img alt="notification icon" class="${icon === 'default-icon' ? 'default-icon' : ''}" src="${icon === 'default-icon' ? defaultIcon : icon}"></div><div class="popover-body-message">${this.options['actionMessage']}</div><div class="clearfix"></div></div><div class="popover-footer"><button id="onesignal-popover-allow-button" class="align-right primary popover-button">${this.options['acceptButtonText']}</button><button id="onesignal-popover-cancel-button" class="align-right secondary popover-button">${this.options['cancelButtonText']}</button><div class="clearfix"></div></div></div>`;

      // Insert the container
      addDomElement('body', 'beforeend',
          '<div id="onesignal-popover-container" class="onesignal-popover-container onesignal-reset"></div>');
      // Insert the dialog
      addDomElement(this.container, 'beforeend',
          `<div id="onesignal-popover-dialog" class="onesignal-popover-dialog">${dialogHtml}</div>`);
      // Animate it in depending on environment
      addCssClass(this.container, bowser.mobile ? 'slide-up' : 'slide-down');
      // Add click event handlers
      this.allowButton.addEventListener('click', this.onPopoverAllowed.bind(this));
      this.cancelButton.addEventListener('click', this.onPopoverCanceled.bind(this));
      Event.trigger(Popover.EVENTS.SHOWN);
    }
  }

  async onPopoverAllowed(_: any) {
    await Event.trigger(Popover.EVENTS.ALLOW_CLICK);
  }

  onPopoverCanceled(_: any) {
    Event.trigger(Popover.EVENTS.CANCEL_CLICK);
    this.close();
  }

  close() {
    addCssClass(this.container, 'close-popover');
    once(this.dialog, 'animationend', (event, destroyListenerFn) => {
      if (event.target === this.dialog &&
          (event.animationName === 'slideDownExit' || event.animationName === 'slideUpExit')) {
          // Uninstall the event listener for animationend
          removeDomElement('#onesignal-popover-container');
          destroyListenerFn();
          Event.trigger(Popover.EVENTS.CLOSED);
      }
    }, true);
  }

  getPlatformNotificationIcon(): string {
    return getPlatformNotificationIcon(this.notificationIcons);
  }

  get container() {
    return document.querySelector('#onesignal-popover-container');
  }

  get dialog() {
    return document.querySelector('#onesignal-popover-dialog');
  }

  get allowButton() {
    return document.querySelector('#onesignal-popover-allow-button');
  }

  get cancelButton() {
    return document.querySelector('#onesignal-popover-cancel-button');
  }
}

export function manageNotifyButtonStateWhilePopoverShows() {
  const notifyButton = OneSignal.notifyButton;
  if (notifyButton &&
    notifyButton.options.enable &&
    OneSignal.notifyButton.launcher.state !== 'hidden') {
    OneSignal.notifyButton.launcher.waitUntilShown()
      .then(() => {
        OneSignal.notifyButton.launcher.hide();
      });
  }
  OneSignal.emitter.once(Popover.EVENTS.CLOSED, () => {
    if (OneSignal.notifyButton &&
      OneSignal.notifyButton.options.enable) {
      OneSignal.notifyButton.launcher.show();
    }
  });
}
