import $ from '../../shared/dom7.js';
import { extend, now, nextTick } from '../../shared/utils.js';
import Modal from '../modal/modal-class.js';
/** @jsx $jsx */
import $jsx from '../../shared/$jsx.js';
class Notification extends Modal {
  constructor(app, params) {
    const extendedParams = extend({
      on: {}
    }, app.params.notification, params);

    // Extends with open/close Modal methods;
    super(app, extendedParams);
    const notification = this;
    notification.app = app;
    notification.params = extendedParams;
    const {
      icon,
      title,
      titleRightText,
      subtitle,
      text,
      closeButton,
      closeTimeout,
      cssClass,
      closeOnClick
    } = notification.params;
    let $el;
    if (!notification.params.el) {
      // Find Element
      const notificationHtml = notification.render({
        icon,
        title,
        titleRightText,
        subtitle,
        text,
        closeButton,
        cssClass
      });
      $el = $(notificationHtml);
    } else {
      $el = $(notification.params.el);
    }
    if ($el && $el.length > 0 && $el[0].f7Modal) {
      return $el[0].f7Modal;
    }
    if ($el.length === 0) {
      return notification.destroy();
    }
    extend(notification, {
      $el,
      el: $el[0],
      type: 'notification'
    });
    $el[0].f7Modal = notification;
    if (closeButton) {
      $el.find('.notification-close-button').on('click', () => {
        notification.close();
      });
    }
    $el.on('click', e => {
      if (closeButton && $(e.target).closest('.notification-close-button').length) {
        return;
      }
      notification.emit('local::click notificationClick', notification);
      if (closeOnClick) notification.close();
    });
    notification.on('beforeDestroy', () => {
      $el.off('click');
    });

    /* Touch Events */
    let isTouched;
    let isMoved;
    let isScrolling;
    let touchesDiff;
    let touchStartTime;
    let notificationHeight;
    const touchesStart = {};
    function handleTouchStart(e) {
      if (isTouched) return;
      isTouched = true;
      isMoved = false;
      isScrolling = undefined;
      touchStartTime = now();
      touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
      touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
    }
    function handleTouchMove(e) {
      if (!isTouched) return;
      const pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
      const pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
      if (typeof isScrolling === 'undefined') {
        isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) < Math.abs(pageX - touchesStart.x));
      }
      if (isScrolling) {
        isTouched = false;
        return;
      }
      e.preventDefault();
      if (!isMoved) {
        notification.$el.removeClass('notification-transitioning');
        notification.$el.transition(0);
        notificationHeight = notification.$el[0].offsetHeight / 2;
      }
      isMoved = true;
      touchesDiff = pageY - touchesStart.y;
      let newTranslate = touchesDiff;
      if (touchesDiff > 0) {
        newTranslate = touchesDiff ** 0.8;
      }
      notification.$el.transform(`translate3d(0, ${newTranslate}px, 0)`);
    }
    function handleTouchEnd() {
      if (!isTouched || !isMoved) {
        isTouched = false;
        isMoved = false;
        return;
      }
      isTouched = false;
      isMoved = false;
      if (touchesDiff === 0) {
        return;
      }
      const timeDiff = now() - touchStartTime;
      notification.$el.transition('');
      notification.$el.addClass('notification-transitioning');
      notification.$el.transform('');
      if (touchesDiff < -10 && timeDiff < 300 || -touchesDiff >= notificationHeight / 1) {
        notification.close();
      }
    }
    function attachTouchEvents() {
      notification.$el.on(app.touchEvents.start, handleTouchStart, {
        passive: true
      });
      app.on('touchmove:active', handleTouchMove);
      app.on('touchend:passive', handleTouchEnd);
    }
    function detachTouchEvents() {
      notification.$el.off(app.touchEvents.start, handleTouchStart, {
        passive: true
      });
      app.off('touchmove:active', handleTouchMove);
      app.off('touchend:passive', handleTouchEnd);
    }
    let timeoutId;
    function closeOnTimeout() {
      timeoutId = nextTick(() => {
        if (isTouched && isMoved) {
          closeOnTimeout();
          return;
        }
        notification.close();
      }, closeTimeout);
    }
    notification.on('open', () => {
      if (notification.params.swipeToClose) {
        attachTouchEvents();
      }
      $('.notification.modal-in').each(openedEl => {
        const notificationInstance = app.notification.get(openedEl);
        if (openedEl !== notification.el && notificationInstance) {
          notificationInstance.close();
        }
      });
      if (closeTimeout) {
        closeOnTimeout();
      }
    });
    notification.on('close beforeDestroy', () => {
      if (notification.params.swipeToClose) {
        detachTouchEvents();
      }
      clearTimeout(timeoutId);
    });
    return notification;
  }
  render() {
    const notification = this;
    if (notification.params.render) return notification.params.render.call(notification, notification);
    const {
      icon,
      title,
      titleRightText,
      subtitle,
      text,
      closeButton,
      cssClass
    } = notification.params;
    return $jsx("div", {
      class: `notification ${icon ? 'notification-with-icon' : ''} ${cssClass || ''}`
    }, $jsx("div", {
      class: "notification-header"
    }, icon && $jsx("div", {
      class: "notification-icon"
    }, icon), title && $jsx("div", {
      class: "notification-title"
    }, title), titleRightText && $jsx("div", {
      class: "notification-title-right-text"
    }, titleRightText), closeButton && $jsx("span", {
      class: "notification-close-button"
    })), $jsx("div", {
      class: "notification-content"
    }, subtitle && $jsx("div", {
      class: "notification-subtitle"
    }, subtitle), text && $jsx("div", {
      class: "notification-text"
    }, text)));
  }
}
export default Notification;