import $ from 'jquery';

const maxTextLength = 48;

let lastReqId = "";

export class IHKSearchTiles {
  constructor(tileWrapper) {
    this.tileWrapper = tileWrapper.addClass("initiated");
    this.itemTitles = tileWrapper[0].getElementsByTagName('a');

    // eslint-disable-next-line no-control-regex
    const regex = new RegExp("^[a-zA-Z0-9äÄöÖüÜß._\b ]+$");

    this.shortenTileText(this.itemTitles);
    // find input element
    this.formAction = tileWrapper.siblings("form")[0];
    this.input = this.formAction.querySelector(".search-field");
    if (!this.input) {
      return;
    }
    this.objId = this.input.getAttribute("data-tile-search");
    this.searchButton = this.formAction.querySelector("button");
    // if we have no object id configured we do not want to perform a dynamic search
    if (this.objId == null || this.objId.trim().length === 0 || this.formAction == null) {
      return;
    }
    this.rateLimit = this.checkRateLimit(this.input.getAttribute("data-tile-search-rl"));
    // create the search button under the tiles
    this.allResultButton = document.createElement("span");
    this.allResultButton.classList.add("all-button-wrapper");
    this.buttonString = '<div class="btn has-icon icon-small-arrow-right-simple">Alle Suchergebnisse</div>';
    this.allResultButton.innerHTML = this.buttonString;
    this.allResultButton.addEventListener("click", (e) => {
      if(this.allResultButton.classList.contains("no-results")) {
        e.preventDefault();
        return;
      }
      this.searchButton.click();
    });

    const tiles = tileWrapper[0].innerHTML;
    let coolDown = false;
    let sendValue = "";
    let lastValue = "";
    let lastSend = null;
    this.doAjaxCall.bind(this);
    this.shortenTileText.bind(this);
    this.input.addEventListener("keyup", (event) => {
      if (!regex.test(event.key)) {
        return;
      }
      // read the current value from the input field
      let input = event.target;
      let currentText = input.value;
      let self = this;

      let delta = (lastSend === null) ? this.rateLimit + 1 : new Date().getTime() - lastSend.getTime();
      if (!coolDown && currentText.length > 1) {
        if (delta > this.rateLimit) {
          sendValue = currentText;
          // trigger the ajax call and the search action here
          this.doAjaxCall(input, sendValue, this.tileWrapper[0]);
          lastSend = new Date();
          coolDown = true;
        }
        setTimeout(() => {
          coolDown = false;

          if (lastValue !== sendValue && lastValue.length > 1) {
            self.doAjaxCall(input, lastValue, this.tileWrapper[0]);
            sendValue = lastValue;
            lastSend = new Date();
          }
        }, this.rateLimit);
      } else if (currentText.length < 2) {
        // show initial tiles here
        let span = this.tileWrapper.nextElementSibling;
        this.tileWrapper.innerHTML = tiles;
        if (span) {
          span.remove();
        }
      }
      lastValue = currentText;
    });
    // remove initial search input in case of the user uses the back function of the browser
    window.onload = () => {
      this.input.value = "";
    };
  }

  shortenTileText(tiles) {
    for (let tile of tiles) {
      if (tile.innerText.length > maxTextLength) {
        tile.innerText = tile.innerText.substring(0, maxTextLength) + '…';
      }
    }
  }

  doAjaxCall(ajaxObj, query, tiles) {
    const self = this;
    const objId = ajaxObj.getAttribute("data-tile-search");
    const url = "/blueprint/servlet/serviceport/search/" + objId;
    const urlAndQuery = url + "?query=" + query;
    const requestId = Math.floor(Math.random() * 100000);
    lastReqId = requestId;
    $.ajax({
      url: urlAndQuery,
      method: "GET",
      timeout: 0,
      success: function (result) {
        if (requestId === lastReqId) {
          // replace tiles here
          tiles.innerHTML = result;
          // find tile a and shorten the text if needed
          let itemTitles = tiles.getElementsByClassName('item-title');
          self.shortenTileText(itemTitles);

          const hasHits = tiles.querySelectorAll('.tile').length > 0;

          // Zustand je nach Ergebnis setzen
          if (!hasHits) {
            self.allResultButton.innerHTML = '<div class="btn disabled">Keine Inhalte gefunden</div>';
            self.allResultButton.classList.add('no-results');
            self.allResultButton.querySelector('.btn').setAttribute('disabled', 'true');

          } else {
            self.allResultButton.innerHTML = '<div class="btn has-icon icon-small-arrow-right-simple">Alle Suchergebnisse</div>';
            self.allResultButton.classList.remove('no-results');
            self.allResultButton.querySelector('.btn').removeAttribute('disabled');
          }

          // add the "all results" button
          const searchWrapper = tiles.closest('.search');
          if (searchWrapper) {
            searchWrapper.classList.add('has-button-wrapper');
          }

          tiles.insertAdjacentElement("afterend", self.allResultButton);
        }
      }
    });
  }

  checkRateLimit(rl) {
    if (rl.trim().length > 0) {
      let num = parseInt(rl);
      if (num >= 100) {
        return num;
      } else {
        return 300;
      }
    }
    return 300;
  }
}

class IHKExtendedSearch {
  constructor(section) {
    this.section = section.addClass('initiated');

    $('#search-expand-collapse').on('click', (e) => {
      e.preventDefault();
      $(e.currentTarget).toggleClass('open');
      this.section.stop().slideToggle(500, 'swing');
    });

    section.find('.ev-search-btn').on('click', (e) => {
      e.preventDefault();
      const target = $(e.currentTarget);
      target.next('.ev-filter').stop().slideToggle(400, 'easeOutQuad');
      window.requestAnimationFrame(() => {
        target.toggleClass('open variant-subtle-secondary');
      })
    });

    section.find('label.acc a').each((i, el) => {
      new FormAccordion($(el));
    });

    section.find('.reset').on('click', (e) => {
      e.preventDefault();

      const form = $(e.currentTarget).closest('form');

      form[0].reset();
      form.find('.half-checked').removeClass('half-checked');

      $('html, body').animate({
        scrollTop: form.offset().top - 120
      }, 500, 'easeOutQuad');
    });

    /*
    $('.datepicker').each((i, el) => {
      $(el).datepicker({ changeYear: true, changeMonth: true});
    });
    */
  }
}

class FormAccordion {
  constructor(toggle) {
    this.toggle = toggle;
    this.label = this.toggle.parent('label');
    this.checkbox = this.label.prev('input[type="checkbox"]');
    this.subs = this.label.next('.ev-filter');

    this.toggle.on('click', (e) => {
      e.preventDefault();
      e.stopPropagation();
      this.label.toggleClass('open');
      this.subs.stop().slideToggle(400, 'swing');
    })

    this.subs.find('input[type="checkbox"]').on('change', () => {
      this.checkSelection();
    })

    this.checkbox.on('change', (e) => {
      const isChecked = $(e.currentTarget).removeClass('half-checked').prop('checked');
      this.subs.find('input[type="checkbox"]').prop('checked', isChecked);
    })

    this.checkSelection();
  }

  checkSelection() {
    const checked = this.subs.find('input[type="checkbox"]:checked').length;
    const unchecked = this.subs.find('input[type="checkbox"]:not(:checked)').length;

    if (checked + unchecked === 0) {
      this.checkbox.removeClass('half-checked');
      return;
    }
    if (checked === 0) {
      this.checkbox.prop('checked', false).removeClass('half-checked');
    } else if (unchecked === 0) {
      this.checkbox.prop('checked', true).removeClass('half-checked');
    } else {
      this.checkbox.prop('checked', false).addClass('half-checked');
    }
  }
}

export default IHKExtendedSearch;

$('body').on('ihk-init dynamic-component-loaded', function () {
  $('.extended-search:not(.initiated)').each(function () {
    new IHKExtendedSearch($(this));
  });
});
