const $ = global.$;
// Plain InfiniteScroll without jquery plugin to avoid overhead
// If needed plase see https://v3.infinite-scroll.com/extras.html
// $(elem).infiniteScroll does not work
// For API Reference See Vanila js Section of docs
const InfiniteScroll = require('infinite-scroll');



import {EtrackerUtils} from "./EtrackerUtils";

export class SearchUtils {
  static loadResults() {
    this.shouldPreloadSearchEnteries = false;
    this.initEventsScrollPreservance();
    this.initialSearchRequest();
  }

  static initialSearchRequest(){
    const query = $('#query').val();
    const querySource = $('#querySource').val();
    const infiniteScrollInstance = InfiniteScroll.data(".search-results #dummy-wrapper");
    $(".results-wrapper").detach();
    $(".search-hits").empty();
    if(infiniteScrollInstance instanceof InfiniteScroll){
      infiniteScrollInstance.destroy();
    }
    // ETracker-Event asynchron absetzen:
    if (query.length > 0) {
      const searchCategory = $("#query").data('search-category'), hasCategory = typeof searchCategory !== "undefined";
      if (!window.isPbe) {
        window.setTimeout(EtrackerUtils.fireETrackerEvent, 250,
          (hasCategory ? searchCategory : 'Kombi-Suche'), query,
          'Suche', '');
      }
    }

    $('#infscr-initial-loading').show();

    const ajaxUrl = $('.search-results').data("initialsearch-url")
      + "?preSearch=oidSearch&querySource=" + encodeURIComponent(querySource) + "&query="
      + encodeURIComponent(query) + SearchUtils.getQueryParameter();
    const resultWrapper = $("#dummy-wrapper");


    $.ajax({
      url: ajaxUrl,
      success: function (result) {
        $(resultWrapper).append(result);
        // oidSearch redirect:
        var rUrl = $("#oidmatch").data("redirect-url");
        if (rUrl !== undefined && rUrl.trim().length > 0) {
          location.href = rUrl;
        } else {
          SearchUtils.initInfiniteScroll();
          SearchUtils.initFeedbackToggle();
          SearchUtils.fillSearchCategoryAddition(query);
          $('#infscr-initial-loading').hide();

        }
      }
    });
  }

  /**
   * Dient zum Ein/Ausblenden der Feedback Funktion von Einschub-Suchen.
   * (insbesondere dem Wegweiser)
   */
  static initFeedbackToggle() {
    $('#feedbackToggle').click(function () {
      var feedbackBlock = $('#feedbackBlock');
      if (feedbackBlock.is(':hidden')) {
        $.ajax({
          url: $(this).data("feedback-url"),
          success: function (result) {
            // TODO: Feedback form prüfen
            $(feedbackBlock).append($(result));
            console.log($(result).find("#feedbackBlock"));
            $(this).show('slow');
            SearchUtils.initFeedback();
          }
        });

      } else {
        feedbackBlock.hide('slow');
      }
      return false;
    });
  }

  /**
   * Feedback Formular für Einschub-Suchen.
   */
  static initFeedback() {
    $('#feedbackBlock').find('form').submit(
      function () {
        $
          .post($('#feedbackToggle').data('feedback-url'), $(
            '#feedbackBlock').find('form').serialize(),
            function (msg) {
              $('#feedbackBlock').html(msg);
              if ($('#feedbackBlock').find('form')
                .size() > 0) {
                SearchUtils.initFeedback();
              } else {
                $('#feedbackToggle').hide();
              }

            });
        return false;
      });
  }

  static fillSearchCategoryAddition(queryP) {
    const buttonWrapper = $('#searchcategoryaddition');
    const firstWrapper = $('.results-wrapper').first();
    const btnAll = $('<a class="btn-small" />');
    const isZeroResults = $('.search-results .results-wrapper').length === 0;
    const isKombiWrapper =  $('.search-results').hasClass("kombi-wrapper");
    const searchCategoryAdditionLink = buttonWrapper.attr('data-searchcategoryaddition-link');
    // const searchCategoryAdditionTitle = buttonWrapper.attr('data-searchcategoryaddition-title');
    const defaultSearchText = "Allgemeine Suche";

    buttonWrapper.children().remove();
    buttonWrapper.append(btnAll);

    // btnAll.text(searchCategoryAdditionTitle);
    btnAll.attr('href', searchCategoryAdditionLink + "?query=" + encodeURIComponent(queryP));

    if (isKombiWrapper && !isZeroResults) {

      const defaultSearchTextAll = "Alle ";
      const ephasizedText = $('<strong/>').text(`${firstWrapper.attr('data-totalresults')} Treffer`);

      btnAll.addClass('active').text(defaultSearchTextAll).append(ephasizedText);
      $('.results-wrapper').not('.no-border').each(function () {
        const rw = $(this);

        const btn = $('<a />').addClass('btn-small').attr('href', rw.attr('data-searchcategoryaddition-link')).appendTo(buttonWrapper);
        let txt = rw.attr('data-searchcategoryaddition-title');
        if (rw.attr('data-result-count') !== undefined) {
          txt = txt + ' (' + rw.attr('data-result-count') + ')';
        }
        btn.text(txt);
      })

    } else if(!isKombiWrapper){
      buttonWrapper.insertAfter('.search-filter-form');
      btnAll.text(defaultSearchText);
      btnAll.attr('href', buttonWrapper.attr('data-searchcategoryaddition-link') + "?query=" + encodeURIComponent(queryP));

    } else {
      buttonWrapper.children().remove();
    }


  }

  /**
   * Berechnet die Url-Parameter für die Suchfilter.
   */
  static getQueryParameter() {
    var queryFields = $('#ev-search-filter-form').find('[data-queryparam]');
    var queryParams = "";
    if (queryFields.length) {
      var input = queryFields.filter('input[type!="checkbox"]');
      if (input.length) {
        queryParams = queryParams + "&" + $.param(input);
      }
      var select = queryFields.filter('select');
      if (select.length) {
        queryParams = queryParams + "&" + $.param(select);
      }
      var check = queryFields.filter('input[type="checkbox"]:checked');
      if (check.length) {
        queryParams = queryParams + "&" + $.param(check);
      }
    }
    return queryParams;
  }


  /**
   * Berechnet die Url-Parameter für die Seitenpaginierung.
   */
  static getPagingParameter() {
    var params = "";

    var resultWrapper = $('.results-wrapper');
    if (resultWrapper.length) {
      var total = resultWrapper.data("totalresults");
      var itemsPerPage = resultWrapper.data("resultsperpage");
      var numPages = resultWrapper.data("numpages");

      if (!(total === undefined)) {
        params = params + "&totalResults=" + total;
      }
      if (!(itemsPerPage === undefined)) {
        params = params + "&resultsPerPage=" + itemsPerPage;
      }
      if (!(numPages === undefined)) {
        params = params + "&numPages=" + numPages;
      }
    }
    return params;
  }

  static initEventsScrollPreservance(){
    $(document).on("click", "#search-results .results-wrapper .event-component",function(event){
      const originalHistoryState =   history.state ||{};
      originalHistoryState.lastScrollPosition =  $(window).scrollTop();
      history.replaceState(originalHistoryState, document.title);

    });
  }

  static scrollToLastViewedEvent(){
    if(history.state && history.state.lastScrollPosition){
      requestAnimationFrame(()=>{
        $('html, body').animate(
          {
            scrollTop : history.state.lastScrollPosition
          }, 500);
      });

    }

  }

  static updateSearchHistoryState(lastScrolledPage){
    try{
      const originalHistoryState = {};
      originalHistoryState.lastScrolledSearchPage =  lastScrolledPage;
      history.replaceState(originalHistoryState, document.title);
    } catch(e) {
      console.warn("Could not update history state", e);
    }
  }

  /**
   * Initialisiert das Endlosscrolling für Trefferlisten.
   */
  static initInfiniteScroll() {
    ihk.resources = ihk.resources || {loadSpinner: ""};
    const $infiniteScrollContainer = $('.search-results #dummy-wrapper');
    if ($infiniteScrollContainer.length > 0) {
      const  $pagingNav = $('.paging-nav');
      $pagingNav.hide();
      SearchUtils.updateSearchResultsMessage();
      SearchUtils.highlightSearchTerm();
      const infiniteScrollObj = new InfiniteScroll($infiniteScrollContainer[0],{
        onInit: function(){
          if(history.state && history.state.lastScrolledSearchPage ){
            const lastScrolledPageFromHistory =  history.state.lastScrolledSearchPage;
            // load the last scrolled page after leaving the page and returning
            if((lastScrolledPageFromHistory > 1) && (lastScrolledPageFromHistory >= this.pageIndex)){
              SearchUtils.shouldPreloadSearchEnteries = true;
              requestAnimationFrame(()=>{
                this.loadNextPage();
              });
            }
          }

        },
        path: function () {
          // Load the second page because we do presearch
            const index = this.pageIndex + 1;
            const resultWrapper = $('.results-wrapper');
            if (resultWrapper.length) {
              const numPages = resultWrapper
                .data("numpages");
              if ((numPages === undefined)
                || (index <= numPages)) {
                return $('.search-results')
                    .data(
                      "infinitescroll-normal-return-url")
                  + "?query="
                  + encodeURIComponent($(
                    '#query').val())
                  + "&currentPage="
                  + index
                  + SearchUtils.getQueryParameter()
                  + SearchUtils.getPagingParameter();
              }
            }
            return "";// damit nicht stumpf wiederholt
          // das letzte Ergebnis
          // angehangen wird!
        },
        append: ".results-wrapper",
        responseBody: "html",
        history: false,
        // debug: true -> for developement
      });

      infiniteScrollObj.on( 'append', function( response, path, items ) {
       if($(items).is(".results-wrapper")){
         const pageIndex = this.pageIndex;
         if(SearchUtils.shouldPreloadSearchEnteries){
           if(history.state && history.state.lastScrolledSearchPage >   pageIndex){
             this.loadNextPage();
           } else {
             SearchUtils.shouldPreloadSearchEnteries = false;
             SearchUtils.scrollToLastViewedEvent();
           }
         }else {
           SearchUtils.updateSearchHistoryState(pageIndex);
           SearchUtils.highlightSearchTerm();
         }

       }else {
         // Destroy falls keine results mehr
         infiniteScrollObj.destroy();
       }

      });

    }
  }

  /**
   * Markiert nach erfolgter Suche den Suchbegriff innerhalb der Trefferliste.
   */
  static highlightSearchTerm() {
    var $searchResults = $('.search-results .results-wrapper .result'), $searchField = $('#query');

    // highlight search term
    if ($searchResults.length > 0 && $searchField.length > 0) {
      var searchTerm = $searchField.val();
      if (typeof searchTerm !== 'undefined') {
        $searchResults.highlight(searchTerm);
      }
    }
  }

  /**
   * Liefert nach erfolgter Suche die korrekte Anzahl Treffer. und erzeugt
   * gegebenfalls für Etracker einen 0-Treffer Event.
   */
  static updateSearchResultsMessage() {
    var searchHits = $('.search-hits');
    var resultWrapper = $('.results-wrapper');
    var resultVal = 0;
    if (typeof resultWrapper.val() !== "undefined") {
      resultVal = resultWrapper.data("totalresults");
    }

    // IHK-2681: 0-Treffer-Suche
    if (resultVal === 0) {
      var searchCategoryE = $("#query").data('search-category'), hasCategoryE = typeof searchCategoryE !== "undefined";
      var queryE = $('#query').val();
      var actionE = '0-Treffer-Suche';
      var querySource = $('#querySource').val();

      if ('autocomplete' === querySource) {
        actionE = '0-Treffer-Vorschlag';
        $('#querySource').val('manual');
      }
      if (!window.isPbe) {
        //todo: etracker
        window.setTimeout(EtrackerUtils.fireETrackerEvent, 250,
          (hasCategoryE ? searchCategoryE : 'Kombi-Suche'),
          queryE, actionE, '');
      }
    }
    searchHits.text(resultVal + " Treffer");
  }

  static getAllUrlParams(url) {

    // get query string from url (optional) or window
    var queryString = url ? url.split('?')[1] : window.location.search.slice(1);

    // we'll store the parameters here
    var obj = {};

    // if query string exists
    if (queryString) {

      // stuff after # is not part of query string, so get rid of it
      queryString = queryString.split('#')[0];

      // split our query string into its component parts
      var arr = queryString.split('&');

      for (var i=0; i<arr.length; i++) {
        // separate the keys and the values
        var a = arr[i].split('=');

        // in case params look like: list[]=thing1&list[]=thing2
        var paramNum = undefined;
        var paramName = a[0].replace(/\[\d*\]/, function(v) {
          paramNum = v.slice(1,-1);
          return '';
        });

        // set parameter value (use 'true' if empty)
        var paramValue = typeof(a[1])==='undefined' ? true : a[1];

        // if parameter name already exists
        if (obj[paramName]) {
          // convert value to array (if still string)
          if (typeof obj[paramName] === 'string') {
            obj[paramName] = [obj[paramName]];
          }
          // if no array index number specified...
          if (typeof paramNum === 'undefined') {
            // put the value on the end of the array
            obj[paramName].push(paramValue);
          }
          // if array index number specified...
          else {
            // put the value at that index number
            obj[paramName][paramNum] = paramValue;
          }
        }
        // if param name doesn't exist yet, set it
        else {
          obj[paramName] = paramValue;
        }
      }
    }

    return obj;
  }


}

$(document).ready(function () {
// Submit-Event abfangen und stattdessen den Ajax-Call ausführen:
  $("#search-form").bind("submit", function () {
    SearchUtils.loadResults();
    SearchUtils.updateSearchHistoryState(1);
  });

// Click-Event abfangen und stattdessen den Ajax-Call ausführen:
  $("#search-submit, #search-submit-button").click(function () {
    SearchUtils.loadResults();
    SearchUtils.updateSearchHistoryState(1);
  });

  if ($('#query').val() != null) {
    SearchUtils.loadResults();
  }
});
