import { wpjEvent } from '@assets/components/util.event';

function emitProductsLoaded(target: EventTarget = document) {
   const event = new CustomEvent('wpj-products-loaded', {
      detail: { type: 'modal:loaded' },
      bubbles: true,
   });

   target.dispatchEvent(event);
}

export class WpjModal {
   modal: HTMLElement;
   closeOnBgClick: boolean;
   mouseDownHandler: any;
   keyDownHandler: any;
   modalCloseHandler: any;

   constructor(modal: HTMLElement = null, closeOnBgClick: boolean = true) {
      this.modal = modal;
      this.closeOnBgClick = closeOnBgClick;
   }

   init() {
      const me = this;

      let page = window.location.href.substring(window.location.href.lastIndexOf('/') + 1);
      if (page !== "2fa_login") {
         wpjEvent.on('click', '[data-wpj-modal]', function(e) {
            e.preventDefault();
            me.create({
               endpoint: this.dataset['wpjModal'],
               type: this.dataset['wpjModalType'] ?? null
            });
         });

         wpjEvent.on('click', '[data-modal-close]', function(e) {
            e.preventDefault();
            me.hide(this.closest('.wpj-modal-overlay'));
         });
      }
   }

   getModals() {
      let wpjModals: HTMLElement = document.querySelector('[data-wpj-modals]');
      if (!wpjModals) {
         document.body.insertAdjacentHTML('beforeend', '<div data-wpj-modals></div>');
         wpjModals = document.querySelector('[data-wpj-modals]');
      }

      return wpjModals;
   }

   create(options: { endpoint: string, type?: string }) {
      const me = this;
      const wpjModals = this.getModals();
      const existingModal: HTMLElement = wpjModals.querySelector(`.wpj-modal-overlay[data-modal-endpoint="${options.endpoint}"]`);
      if (existingModal) {
         me.modal = existingModal;
         me.show();
         return;
      }

      wpjModals.insertAdjacentHTML('beforeend', this.getModalLoadingTemplate(options));
      me.modal = wpjModals.querySelector(`.wpj-modal-overlay[data-modal-endpoint="${options.endpoint}"]`);
      this.show();

      fetch(options.endpoint)
         .then((response) => response.text())
         .then((response) => {
            me.modal.innerHTML = response;
            emitProductsLoaded(me.modal);
            const breadcrumbs = this.getBreadcrumbs(me.modal.ownerDocument?.activeElement);
            me.modal.setAttribute('data-gtm-placeholders', JSON.stringify({breadcrumbs: breadcrumbs ?? []}));
         });
   }

   getBreadcrumbs(activeElement: Element|null) {
      while (activeElement && (activeElement = activeElement.closest('[data-gtm-placeholders]'))) {
         const placeholders = JSON.parse(activeElement.getAttribute('data-gtm-placeholders'));
         if (placeholders.hasOwnProperty('breadcrumbs') && (placeholders['breadcrumbs'] != '@breadcrumbs')) {
            return placeholders['breadcrumbs'];
         }
         activeElement = activeElement.parentElement;
      }

      return null;
   }

   show() {
      const me = this;

      if (me.getScrollbarWidth()) {
         document.body.style.paddingRight = `${me.getScrollbarWidth()}px`;
      }
      document.body.classList.add('modal-opened');
      me.modal.classList.add('active');

      document.body.addEventListener('keydown', me.keyDownHandler = function(e: KeyboardEvent) {
         if (e.key === 'Escape') {
            me.hide(me.modal);
         }
      });

      if (me.closeOnBgClick) {
         me.modal.addEventListener('mousedown', me.mouseDownHandler = function(e: MouseEvent) {
            if (me.modal.contains(e.target as Node) && e.target === me.modal) {
               me.hide(me.modal);
            }
         });
      }

      me.modal.addEventListener('modal:close', me.modalCloseHandler = function() {
         me.hide(me.modal);
      });
   }

   hide(modal: HTMLElement) {
      const me = this;
      document.body.classList.remove('modal-opened');
      modal.classList.remove('active');
      document.body.style.paddingRight = null;

      if (modal) {
         modal.removeEventListener('mousedown', me.mouseDownHandler);
         modal.removeEventListener('modal:close', me.modalCloseHandler);
         document.body.removeEventListener('mousedown', me.keyDownHandler);
      }
   }

   getModalLoadingTemplate(options: { endpoint: string, type?: string }) {
      if (options.endpoint) {
         return `<div data-modal-endpoint="${options.endpoint}" class="wpj-modal-overlay"><div class="wpj-modal-loading wpj-modal-loading-${options.type}"></div></div>`;
      }
      return `<div class="wpj-modal-overlay"><div class="wpj-modal-loading wpj-modal-loading-${options.type}""></div></div>`;
   }

   getScrollbarWidth() {
      return window.innerWidth - document.body.clientWidth;
   }
}

const wpjModal = new WpjModal();
wpjModal.init();
