class Tracking {
   /*
    * To start tracking
    * add attribute data-tracking-click="{event:name}"
    * on target element (link, button, etc)
    * or on target area of links (topmenu, category list, etc)
    * data are merging from target to parent
    */

   constructor() {
      window.wpj.tracking = this;
      this.setDefaults();
      this.clearState();
      this.setListeners();
   }
   setDefaults(){
      //ugly hack, webpack doesnt support props on classes
      this.defaultState = {
         event: undefined,
         action: undefined,
         data: {
            target: undefined,
            event: undefined,
            action: undefined,
            idincart:undefined,
            id:undefined,
            sku:undefined,
            active:undefined,
            value:undefined,
            once: false
         }
      }
      this.state = undefined;
   }
   setListeners() {
      $("body").click(function(e){
         if ($(e.target).data('tracking-filter')) {
            window.wpj.tracking.handleFilter(e, 'click', false);
         } else {
            window.wpj.tracking.handleEvent(e, 'click');
         }
      });

      $('body').on("beforeAddToCart", function (e, button) {
         window.wpj.tracking.handleAddToCart(button, 'click');
      });

      $('body').on('change', 'select[data-filter-input][name="order"]', e => {
         const selectedOpinion = $(e.target).find('option:selected');
         if (selectedOpinion.length) {
            e.target = selectedOpinion[0];
            window.wpj.tracking.handleFilter(e, 'click', false);
         }
      });
      $(document)
         .on('change', '.filter-param-float [name^="dynamic_filter"], .filter-price [name^="dynamic_filter"]', e => {
         const input = $(e.target);
         if (input?.data('tracking-filter')) {
            e.target = input[0];
            window.wpj.tracking.handleFilter(e, 'click', true);
         }
      });
      $(document).on("mousedown", function (e1) {
        if (e1.which === 2) {
          $(document).one("mouseup", function (e2) {
            if (e1.target === e2.target) {
              var e3 = $.event.fix(e2);
              e3.type = "middleclick";
              $(e2.target).trigger(e3);
            }
          });
        }
      });
      $(document).on("middleclick", function (e) {
         window.wpj.tracking.handleEvent(e, 'click');
      });

      window.wpj.tracking.handleDeliveryTypeChange('cartdeliverychange', 'deliveryChange');
      window.wpj.tracking.handleDeliveryTypeChange('cartpaymentchange', 'paymentChange');

      window.wpj.tracking.handleImpressions();
   }
   clearState() {
      this.state = this.defaultState;
   }

   handleEvent(event, action) {
      this.clearState();
      const clickedElement = event.target;
      const target = this.findUrl(clickedElement);
      this.state.event = event;
      this.state.action = action;
      this.state.data = this.findData(clickedElement);
      if (this.isEmpty(this.state.data.target)) {
         this.state.data.target = target;
      }
      if (this.isEmpty(this.state.data.event)) {
         this.state.data.event = 'default';
      }
      if (this.isEmpty(this.state.data.action)) {
         this.state.data.action = action;
      }

      // if (!this.state.data.target) {
      //    return; //click without target
      // }
      this.callEvents();
   }

   handleAddToCart(event, action) {
      this.clearState();
      const clickedElement = event.target.get(0);
      this.state.event = event;
      this.state.action = action;
      this.state.data = this.findAttribute(clickedElement,'data-tracking-clickAddToCart', true);

      this.handleDefault();
   }

   handleFilter(event, action, isPrice) {
      this.clearState();
      const clickedElement = event.target;
      const target = this.findUrl(clickedElement);
      this.state.event = event;
      this.state.action = action;
      this.state.data = this.findAttribute(clickedElement,'data-tracking-filter', true);
      if (this.isEmpty(this.state.data.target)) {
         this.state.data.target = target;
      }
      if (this.isEmpty(this.state.data.event)) {
         this.state.data.event = 'default';
      }
      if (this.isEmpty(this.state.data.action)) {
         this.state.data.action = action;
      }

      if (!this.state.data.filtrValue) {
         this.state.data.filtrValue = {};
      }
      if (isPrice) {
         this.state.data.filtrValue.value = clickedElement.value;
      } else {
         this.state.data.filtrValue.active = clickedElement.checked;
      }
      this.callPush(this.state.data);
   }
   callEvents() {
      switch (this.state.action) {
         case 'click':
            switch(this.state.data.event){
               default: this.handleDefault();
            }
            break;
         case 'cancel':
            switch(this.state.data.event){
               default: this.handleDefault();
            }
            break;
         case 'cartQty':
               this.handleCartQty();
            break;
      }
   }

   //events
   handleDefault() {
      if (this.state.data.event !== 'default') {
         this.callPush(this.state.data);
      } else {
         // this.callPush({
         //    "event":"behavior",
         //    "behavior":{...this.state.data}
         // });
      }
   }
   handleCartQty(){
      const idincart = this.state.data.idincart;
      const qty = parseInt($(".order-products-cart").find('input[name="products['+idincart+'][pieces]"]input[data-cart="pieces"]').val());

      let data = {
         "sku": this.state.data.sku,
         "qty": qty+1,
         "old_qty": qty
      };
      if (this.state.data.target === "-1") {
         data.qty = qty-1;
      }
      this.callPush({
         "event":"changeInCart",
         "behavior": data
      });
   }

   //analytics caller
   callPush(data) {
      const once = data.once;
      delete data.once;

      if (once) {
         if(data.hasOwnProperty('event')) {
            for (let item of window.dataLayer) {
               if (item.hasOwnProperty('event') && item.event === data.event) {
                  return;
               }
            }
         }
      }

      var uid = wpj.storage.cookies.getItem('gtm_event_uid') || 1;
      data.eventId = ++uid;

      wpj.storage.cookies.setItem('gtm_event_uid', uid, 2592000, '/');

      dataLayer.push(data);
   }
   //helpers
   findData(element) {
      return this.findAttribute(element,'data-tracking-click', true);
   }
   findUrl(element) {
      return this.findAttribute(element, 'href', false);
   }
   findAttribute(element, attribute, merge){
      const e = this.event;
      let ret = false;
      if (!element) {
         element = e.target;
      }
      if (merge) {
         ret = {};
         if (element.hasAttribute(attribute)) {
            ret = JSON.parse(element.getAttribute(attribute));

            if (element.parentElement) {
               const quantity = element.parentElement.querySelector('[name="No"]')?.value;
               if (quantity && ret?.add?.products[0]) {
                  ret.add.products[0].quantity = parseFloat(quantity);
               }
            }
         }
         if (element.parentElement) {
            ret = {...this.findAttribute(element.parentElement,attribute,merge), ...ret};
         }
      } else {
         if (element.hasAttribute(attribute)) {
            ret = element.getAttribute(attribute);
         } else if (element.parentElement) {
            ret = this.findAttribute(element.parentElement,attribute,merge);
         }
      }
      return ret;
   }
   isEmpty(obj) {
     for (let n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false
     return true
   }
   handleImpressions() {
      const trackingViewItems = document.querySelectorAll('[data-tracking-view]');
      const observer = new IntersectionObserver(
         function(entries) {
            entries.forEach(entry => {
               if (entry.intersectionRatio > 0 && entry.target.getAttribute('data-tracking-view')) {
                  window.wpj.tracking.callPush(window.wpj.tracking.findAttribute(entry.target, 'data-tracking-view', true));
                  entry.target.removeAttribute('data-tracking-view');
               }
            })
         },
         { rootMargin: '0px 0px 0px 0px', threshold: 0.01 } // threshold 0.01 je kvuli tomu, ze 0.2 nefunguje u dlouhého katalogu a 0 nefunguje u sliderů (carouselů)
      );
      trackingViewItems.forEach(trackingViewItem => {
         observer.observe(trackingViewItem);
      });
   }
   handleDeliveryTypeChange($eventName, $timeoutName) {
     $('#cart').on($eventName, function(e) {
           clearTimeout(window.wpj.tracking[$timeoutName]);
           window.wpj.tracking[$timeoutName] = setTimeout(function() {
              if (!e.originalEvent) {
                 return;
              }
              window.wpj.tracking.callPush(window.wpj.tracking.findAttribute(e.originalEvent.target, 'data-tracking-click-delivery-type', true))
           }, 100);
     });
   }
}
new Tracking();
