import { getDocument } from 'ssr-window';
import $ from '../../shared/dom7.js';
import { extend, nextTick, deleteProps } from '../../shared/utils.js';
import FrameworkClass from '../../shared/class.js';
import { getDevice } from '../../shared/get-device.js';
import removeDiacritics from './remove-diacritics.js';
class Searchbar extends FrameworkClass {
  constructor(app, params) {
    if (params === void 0) {
      params = {};
    }
    super(params, [app]);
    const sb = this;
    const defaults = {
      el: undefined,
      inputEl: undefined,
      inputEvents: 'change input compositionend',
      disableButton: true,
      disableButtonEl: undefined,
      backdropEl: undefined,
      searchContainer: undefined,
      // container to search, HTMLElement or CSS selector
      searchItem: 'li',
      // single item selector, CSS selector
      searchIn: undefined,
      // where to search in item, CSS selector
      searchGroup: '.list-group',
      searchGroupTitle: '.list-group-title',
      ignore: '.searchbar-ignore',
      foundEl: '.searchbar-found',
      notFoundEl: '.searchbar-not-found',
      hideOnEnableEl: '.searchbar-hide-on-enable',
      hideOnSearchEl: '.searchbar-hide-on-search',
      backdrop: true,
      removeDiacritics: true,
      customSearch: false,
      hideGroupTitles: true,
      hideGroups: true,
      disableOnBackdropClick: true,
      expandable: false,
      inline: false
    };

    // Extend defaults with modules params
    sb.useModulesParams(defaults);
    sb.params = extend(defaults, params);
    const $el = $(sb.params.el);
    if ($el.length === 0) return sb;
    if ($el[0].f7Searchbar) return $el[0].f7Searchbar;
    $el[0].f7Searchbar = sb;
    let $pageEl;
    const $navbarEl = $el.parents('.navbar');
    if ($el.parents('.page').length > 0) {
      $pageEl = $el.parents('.page');
    } else if ($navbarEl.length > 0) {
      $pageEl = $(app.navbar.getPageByEl($navbarEl[0]));
      if (!$pageEl.length) {
        const $currentPageEl = $el.parents('.view').find('.page-current');
        if ($currentPageEl[0] && $currentPageEl[0].f7Page && $currentPageEl[0].f7Page.navbarEl === $navbarEl[0]) {
          $pageEl = $currentPageEl;
        }
      }
    }
    let $foundEl;
    if (params.foundEl) {
      $foundEl = $(params.foundEl);
    } else if (typeof sb.params.foundEl === 'string' && $pageEl) {
      $foundEl = $pageEl.find(sb.params.foundEl);
    }
    let $notFoundEl;
    if (params.notFoundEl) {
      $notFoundEl = $(params.notFoundEl);
    } else if (typeof sb.params.notFoundEl === 'string' && $pageEl) {
      $notFoundEl = $pageEl.find(sb.params.notFoundEl);
    }
    let $hideOnEnableEl;
    if (params.hideOnEnableEl) {
      $hideOnEnableEl = $(params.hideOnEnableEl);
    } else if (typeof sb.params.hideOnEnableEl === 'string' && $pageEl) {
      $hideOnEnableEl = $pageEl.find(sb.params.hideOnEnableEl);
    }
    let $hideOnSearchEl;
    if (params.hideOnSearchEl) {
      $hideOnSearchEl = $(params.hideOnSearchEl);
    } else if (typeof sb.params.hideOnSearchEl === 'string' && $pageEl) {
      $hideOnSearchEl = $pageEl.find(sb.params.hideOnSearchEl);
    }
    const expandable = sb.params.expandable || $el.hasClass('searchbar-expandable');
    const inline = sb.params.inline || $el.hasClass('searchbar-inline');
    if (typeof sb.params.backdrop === 'undefined') {
      sb.params.backdrop = !inline;
    }
    let $backdropEl;
    if (sb.params.backdrop) {
      if (sb.params.backdropEl) {
        $backdropEl = $(sb.params.backdropEl);
      } else if ($pageEl && $pageEl.length > 0) {
        $backdropEl = $pageEl.find('.searchbar-backdrop');
      } else {
        $backdropEl = $el.siblings('.searchbar-backdrop');
      }
      if ($backdropEl.length === 0) {
        $backdropEl = $('<div class="searchbar-backdrop"></div>');
        if ($pageEl && $pageEl.length) {
          if ($el.parents($pageEl).length > 0 && $navbarEl && $el.parents($navbarEl).length === 0) {
            $backdropEl.insertBefore($el);
          } else {
            $backdropEl.insertBefore($pageEl.find('.page-content').eq(0));
          }
        } else {
          $backdropEl.insertBefore($el);
        }
      }
    }
    let $searchContainer;
    if (sb.params.searchContainer) {
      $searchContainer = $(sb.params.searchContainer);
    }
    let $inputEl;
    if (sb.params.inputEl) {
      $inputEl = $(sb.params.inputEl);
    } else {
      $inputEl = $el.find('input[type="search"]').eq(0);
    }
    let $disableButtonEl;
    if (sb.params.disableButton) {
      if (sb.params.disableButtonEl) {
        $disableButtonEl = $(sb.params.disableButtonEl);
      } else {
        $disableButtonEl = $el.find('.searchbar-disable-button');
      }
    }
    extend(sb, {
      app,
      view: app.views.get($el.parents('.view')),
      $el,
      el: $el[0],
      $backdropEl,
      backdropEl: $backdropEl && $backdropEl[0],
      $searchContainer,
      searchContainer: $searchContainer && $searchContainer[0],
      $inputEl,
      inputEl: $inputEl[0],
      $disableButtonEl,
      disableButtonEl: $disableButtonEl && $disableButtonEl[0],
      disableButtonHasMargin: false,
      $pageEl,
      pageEl: $pageEl && $pageEl[0],
      $navbarEl,
      navbarEl: $navbarEl && $navbarEl[0],
      $foundEl,
      foundEl: $foundEl && $foundEl[0],
      $notFoundEl,
      notFoundEl: $notFoundEl && $notFoundEl[0],
      $hideOnEnableEl,
      hideOnEnableEl: $hideOnEnableEl && $hideOnEnableEl[0],
      $hideOnSearchEl,
      hideOnSearchEl: $hideOnSearchEl && $hideOnSearchEl[0],
      previousQuery: '',
      query: '',
      isVirtualList: $searchContainer && $searchContainer.hasClass('virtual-list'),
      virtualList: undefined,
      enabled: false,
      expandable,
      inline
    });

    // Events
    function preventSubmit(e) {
      e.preventDefault();
    }
    function onInputFocus(e) {
      sb.enable(e);
      sb.$el.addClass('searchbar-focused');
    }
    function onInputBlur() {
      sb.$el.removeClass('searchbar-focused');
    }
    function onInputChange() {
      const value = sb.$inputEl.val().trim();
      if (sb.$searchContainer && sb.$searchContainer.length > 0 && (sb.params.searchIn || sb.isVirtualList || sb.params.searchIn === sb.params.searchItem) || sb.params.customSearch) {
        sb.search(value, true);
      }
    }
    function onInputClear(e, previousValue) {
      sb.$el.trigger('searchbar:clear', previousValue);
      sb.emit('local::clear searchbarClear', sb, previousValue);
    }
    function disableOnClick(e) {
      sb.disable(e);
    }
    function onPageBeforeOut() {
      if (!sb || sb && !sb.$el) return;
      if (sb.enabled) {
        sb.$el.removeClass('searchbar-enabled');
        if (sb.expandable) {
          sb.$el.parents('.navbar').removeClass('with-searchbar-expandable-enabled with-searchbar-expandable-enabled-no-transition');
        }
      }
    }
    function onPageBeforeIn() {
      if (!sb || sb && !sb.$el) return;
      if (sb.enabled) {
        sb.$el.addClass('searchbar-enabled');
        if (sb.expandable) {
          sb.$el.parents('.navbar').addClass('with-searchbar-expandable-enabled-no-transition');
        }
      }
    }
    sb.attachEvents = function attachEvents() {
      $el.on('submit', preventSubmit);
      if (sb.params.disableButton) {
        sb.$disableButtonEl.on('click', disableOnClick);
      }
      if (sb.params.disableOnBackdropClick && sb.$backdropEl) {
        sb.$backdropEl.on('click', disableOnClick);
      }
      if (sb.expandable && app.theme === 'ios' && sb.view && $navbarEl.length && sb.$pageEl) {
        sb.$pageEl.on('page:beforeout', onPageBeforeOut);
        sb.$pageEl.on('page:beforein', onPageBeforeIn);
      }
      sb.$inputEl.on('focus', onInputFocus);
      sb.$inputEl.on('blur', onInputBlur);
      sb.$inputEl.on(sb.params.inputEvents, onInputChange);
      sb.$inputEl.on('input:clear', onInputClear);
    };
    sb.detachEvents = function detachEvents() {
      $el.off('submit', preventSubmit);
      if (sb.params.disableButton) {
        sb.$disableButtonEl.off('click', disableOnClick);
      }
      if (sb.params.disableOnBackdropClick && sb.$backdropEl) {
        sb.$backdropEl.off('click', disableOnClick);
      }
      if (sb.expandable && app.theme === 'ios' && sb.view && $navbarEl.length && sb.$pageEl) {
        sb.$pageEl.off('page:beforeout', onPageBeforeOut);
        sb.$pageEl.off('page:beforein', onPageBeforeIn);
      }
      sb.$inputEl.off('focus', onInputFocus);
      sb.$inputEl.off('blur', onInputBlur);
      sb.$inputEl.off(sb.params.inputEvents, onInputChange);
      sb.$inputEl.off('input:clear', onInputClear);
    };

    // Install Modules
    sb.useModules();

    // Init
    sb.init();
    return sb;
  }
  clear(e) {
    const sb = this;
    if (!sb.query && e && $(e.target).hasClass('searchbar-clear')) {
      sb.disable();
      return sb;
    }
    const previousQuery = sb.value;
    sb.$inputEl.val('').trigger('change').focus();
    sb.$el.trigger('searchbar:clear', previousQuery);
    sb.emit('local::clear searchbarClear', sb, previousQuery);
    return sb;
  }
  setDisableButtonMargin() {
    const sb = this;
    if (sb.expandable) return;
    const app = sb.app;
    sb.$disableButtonEl.transition(0).show();
    sb.$disableButtonEl.css(`margin-${app.rtl ? 'left' : 'right'}`, `${-sb.disableButtonEl.offsetWidth}px`);
    /* eslint no-underscore-dangle: ["error", { "allow": ["_clientLeft"] }] */
    sb._clientLeft = sb.$disableButtonEl[0].clientLeft;
    sb.$disableButtonEl.transition('');
    sb.disableButtonHasMargin = true;
  }
  enable(setFocus) {
    const sb = this;
    if (sb.enabled) return sb;
    const app = sb.app;
    const document = getDocument();
    const device = getDevice();
    sb.enabled = true;
    function enable() {
      if (sb.$backdropEl && (sb.$searchContainer && sb.$searchContainer.length || sb.params.customSearch) && !sb.$el.hasClass('searchbar-enabled') && !sb.query) {
        sb.backdropShow();
      }
      sb.$el.addClass('searchbar-enabled');
      if (!sb.$disableButtonEl || sb.$disableButtonEl && sb.$disableButtonEl.length === 0) {
        sb.$el.addClass('searchbar-enabled-no-disable-button');
      }
      if (!sb.expandable && sb.$disableButtonEl && sb.$disableButtonEl.length > 0 && app.theme !== 'md') {
        if (!sb.disableButtonHasMargin) {
          sb.setDisableButtonMargin();
        }
        sb.$disableButtonEl.css(`margin-${app.rtl ? 'left' : 'right'}`, '0px');
      }
      if (sb.expandable) {
        const $navbarEl = sb.$el.parents('.navbar');
        if ($navbarEl.hasClass('navbar-large') && sb.$pageEl) {
          const $pageContentEl = sb.$pageEl.find('.page-content');
          const $titleLargeEl = $navbarEl.find('.title-large');
          $pageContentEl.addClass('with-searchbar-expandable-enabled');
          if ($navbarEl.hasClass('navbar-large') && $navbarEl.hasClass('navbar-large-collapsed') && $titleLargeEl.length && $pageContentEl.length) {
            $pageContentEl.transition(0);
            $pageContentEl[0].scrollTop -= $titleLargeEl[0].offsetHeight;
            setTimeout(() => {
              $pageContentEl.transition('');
            }, 200);
          }
        }
        if (app.theme === 'md' && $navbarEl.length) {
          $navbarEl.addClass('with-searchbar-expandable-enabled');
        } else {
          $navbarEl.addClass('with-searchbar-expandable-enabled');
          if ($navbarEl.hasClass('navbar-large')) {
            $navbarEl.addClass('navbar-large-collapsed');
          }
        }
      }
      if (sb.$hideOnEnableEl) sb.$hideOnEnableEl.addClass('hidden-by-searchbar');
      sb.$el.trigger('searchbar:enable');
      sb.emit('local::enable searchbarEnable', sb);
    }
    let needsFocus = false;
    if (setFocus === true) {
      if (document.activeElement !== sb.inputEl) {
        needsFocus = true;
      }
    }
    const isIos = device.ios && app.theme === 'ios';
    if (isIos) {
      if (sb.expandable) {
        if (needsFocus) sb.$inputEl.focus();
        enable();
      } else {
        if (needsFocus) sb.$inputEl.focus();
        if (setFocus && (setFocus.type === 'focus' || setFocus === true)) {
          nextTick(() => {
            enable();
          }, 400);
        } else {
          enable();
        }
      }
    } else {
      if (needsFocus) sb.$inputEl.focus();
      if (app.theme === 'md' && sb.expandable) {
        sb.$el.parents('.page, .view, .navbar-inner, .navbar').scrollLeft(app.rtl ? 100 : 0);
      }
      enable();
    }
    return sb;
  }
  disable() {
    const sb = this;
    if (!sb.enabled) return sb;
    const app = sb.app;
    sb.$inputEl.val('').trigger('change');
    sb.$el.removeClass('searchbar-enabled searchbar-focused searchbar-enabled-no-disable-button');
    if (sb.expandable) {
      const $navbarEl = sb.$el.parents('.navbar');
      const $pageContentEl = sb.$pageEl && sb.$pageEl.find('.page-content');
      if ($navbarEl.hasClass('navbar-large') && $pageContentEl.length) {
        const $titleLargeEl = $navbarEl.find('.title-large');
        sb.$el.transitionEnd(() => {
          $pageContentEl.removeClass('with-searchbar-expandable-closing');
        });
        if ($navbarEl.hasClass('navbar-large') && $navbarEl.hasClass('navbar-large-collapsed') && $titleLargeEl.length) {
          const scrollTop = $pageContentEl[0].scrollTop;
          const titleLargeHeight = $titleLargeEl[0].offsetHeight;
          if (scrollTop > titleLargeHeight) {
            $pageContentEl.transition(0);
            $pageContentEl[0].scrollTop = scrollTop + titleLargeHeight;
            setTimeout(() => {
              $pageContentEl.transition('');
            }, 200);
          }
        }
        $pageContentEl.removeClass('with-searchbar-expandable-enabled').addClass('with-searchbar-expandable-closing');
      }
      if (app.theme === 'md' && $navbarEl.length) {
        $navbarEl.removeClass('with-searchbar-expandable-enabled with-searchbar-expandable-enabled-no-transition').addClass('with-searchbar-expandable-closing');
        sb.$el.transitionEnd(() => {
          $navbarEl.removeClass('with-searchbar-expandable-closing');
        });
      } else {
        $navbarEl.removeClass('with-searchbar-expandable-enabled with-searchbar-expandable-enabled-no-transition').addClass('with-searchbar-expandable-closing');
        sb.$el.transitionEnd(() => {
          $navbarEl.removeClass('with-searchbar-expandable-closing');
        });
        if (sb.$pageEl) {
          sb.$pageEl.find('.page-content').trigger('scroll');
        }
      }
    }
    if (!sb.expandable && sb.$disableButtonEl && sb.$disableButtonEl.length > 0 && app.theme !== 'md') {
      sb.$disableButtonEl.css(`margin-${app.rtl ? 'left' : 'right'}`, `${-sb.disableButtonEl.offsetWidth}px`);
    }
    if (sb.$backdropEl && (sb.$searchContainer && sb.$searchContainer.length || sb.params.customSearch)) {
      sb.backdropHide();
    }
    sb.enabled = false;
    sb.$inputEl.blur();
    if (sb.$hideOnEnableEl) sb.$hideOnEnableEl.removeClass('hidden-by-searchbar');
    sb.$el.trigger('searchbar:disable');
    sb.emit('local::disable searchbarDisable', sb);
    return sb;
  }
  toggle() {
    const sb = this;
    if (sb.enabled) sb.disable();else sb.enable(true);
    return sb;
  }
  backdropShow() {
    const sb = this;
    if (sb.$backdropEl) {
      sb.$backdropEl.addClass('searchbar-backdrop-in');
    }
    return sb;
  }
  backdropHide() {
    const sb = this;
    if (sb.$backdropEl) {
      sb.$backdropEl.removeClass('searchbar-backdrop-in');
    }
    return sb;
  }
  search(query, internal) {
    const sb = this;
    sb.previousQuery = sb.query || '';
    if (query === sb.previousQuery) return sb;
    if (!internal) {
      if (!sb.enabled) {
        sb.enable();
      }
      sb.$inputEl.val(query);
      sb.$inputEl.trigger('input');
    }
    sb.query = query;
    sb.value = query;
    const {
      $searchContainer,
      $el,
      $foundEl,
      $notFoundEl,
      $hideOnSearchEl,
      isVirtualList
    } = sb;

    // Hide on search element
    if (query.length > 0 && $hideOnSearchEl) {
      $hideOnSearchEl.addClass('hidden-by-searchbar');
    } else if ($hideOnSearchEl) {
      $hideOnSearchEl.removeClass('hidden-by-searchbar');
    }
    // Add active/inactive classes on overlay
    if ($searchContainer && $searchContainer.length && $el.hasClass('searchbar-enabled') || sb.params.customSearch && $el.hasClass('searchbar-enabled')) {
      if (query.length === 0) {
        sb.backdropShow();
      } else {
        sb.backdropHide();
      }
    }
    if (sb.params.customSearch) {
      $el.trigger('searchbar:search', {
        query,
        previousQuery: sb.previousQuery
      });
      sb.emit('local::search searchbarSearch', sb, query, sb.previousQuery);
      return sb;
    }
    let foundItems = [];
    let vlQuery;
    if (isVirtualList) {
      sb.virtualList = $searchContainer[0].f7VirtualList;
      if (query.trim() === '') {
        sb.virtualList.resetFilter();
        if ($notFoundEl) $notFoundEl.hide();
        if ($foundEl) $foundEl.show();
        $el.trigger('searchbar:search', {
          query,
          previousQuery: sb.previousQuery
        });
        sb.emit('local::search searchbarSearch', sb, query, sb.previousQuery);
        return sb;
      }
      vlQuery = sb.params.removeDiacritics ? removeDiacritics(query) : query;
      if (sb.virtualList.params.searchAll) {
        foundItems = sb.virtualList.params.searchAll(vlQuery, sb.virtualList.items) || [];
      } else if (sb.virtualList.params.searchByItem) {
        for (let i = 0; i < sb.virtualList.items.length; i += 1) {
          if (sb.virtualList.params.searchByItem(vlQuery, sb.virtualList.items[i], i)) {
            foundItems.push(i);
          }
        }
      }
    } else {
      let values;
      if (sb.params.removeDiacritics) values = removeDiacritics(query.trim().toLowerCase()).split(' ');else {
        values = query.trim().toLowerCase().split(' ');
      }
      $searchContainer.find(sb.params.searchItem).removeClass('hidden-by-searchbar').each(itemEl => {
        const $itemEl = $(itemEl);
        let compareWithText = [];
        let $searchIn = sb.params.searchIn ? $itemEl.find(sb.params.searchIn) : $itemEl;
        if (sb.params.searchIn === sb.params.searchItem) {
          $searchIn = $itemEl;
        }
        $searchIn.each(searchInEl => {
          let itemText = $(searchInEl).text().trim().toLowerCase();
          if (sb.params.removeDiacritics) itemText = removeDiacritics(itemText);
          compareWithText.push(itemText);
        });
        compareWithText = compareWithText.join(' ');
        let wordsMatch = 0;
        for (let i = 0; i < values.length; i += 1) {
          if (compareWithText.indexOf(values[i]) >= 0) wordsMatch += 1;
        }
        if (wordsMatch !== values.length && !(sb.params.ignore && $itemEl.is(sb.params.ignore))) {
          $itemEl.addClass('hidden-by-searchbar');
        } else {
          foundItems.push($itemEl[0]);
        }
      });
      if (sb.params.hideGroupTitles) {
        $searchContainer.find(sb.params.searchGroupTitle).each(titleEl => {
          const $titleEl = $(titleEl);
          const $nextElements = $titleEl.nextAll(sb.params.searchItem);
          let hide = true;
          for (let i = 0; i < $nextElements.length; i += 1) {
            const $nextEl = $nextElements.eq(i);
            if ($nextEl.is(sb.params.searchGroupTitle)) break;
            if (!$nextEl.hasClass('hidden-by-searchbar')) {
              hide = false;
            }
          }
          const ignore = sb.params.ignore && $titleEl.is(sb.params.ignore);
          if (hide && !ignore) $titleEl.addClass('hidden-by-searchbar');else $titleEl.removeClass('hidden-by-searchbar');
        });
      }
      if (sb.params.hideGroups) {
        $searchContainer.find(sb.params.searchGroup).each(groupEl => {
          const $groupEl = $(groupEl);
          const ignore = sb.params.ignore && $groupEl.is(sb.params.ignore);
          // eslint-disable-next-line
          const notHidden = $groupEl.find(sb.params.searchItem).filter(el => {
            return !$(el).hasClass('hidden-by-searchbar');
          });
          if (notHidden.length === 0 && !ignore) {
            $groupEl.addClass('hidden-by-searchbar');
          } else {
            $groupEl.removeClass('hidden-by-searchbar');
          }
        });
      }
    }
    if (foundItems.length === 0) {
      if ($notFoundEl) $notFoundEl.show();
      if ($foundEl) $foundEl.hide();
    } else {
      if ($notFoundEl) $notFoundEl.hide();
      if ($foundEl) $foundEl.show();
    }
    if (isVirtualList && sb.virtualList) {
      sb.virtualList.filterItems(foundItems);
    }
    $el.trigger('searchbar:search', {
      query,
      previousQuery: sb.previousQuery,
      foundItems
    });
    sb.emit('local::search searchbarSearch', sb, query, sb.previousQuery, foundItems);
    return sb;
  }
  init() {
    const sb = this;
    if (sb.expandable && sb.$el) sb.$el.addClass('searchbar-expandable');
    if (sb.inline && sb.$el) sb.$el.addClass('searchbar-inline');
    sb.attachEvents();
  }
  destroy() {
    const sb = this;
    sb.emit('local::beforeDestroy searchbarBeforeDestroy', sb);
    sb.$el.trigger('searchbar:beforedestroy');
    sb.detachEvents();
    if (sb.$el[0]) {
      sb.$el[0].f7Searchbar = null;
      delete sb.$el[0].f7Searchbar;
    }
    deleteProps(sb);
  }
}
export default Searchbar;