text: /**
   * Copyright since 2007 PrestaShop SA and Contributors
   * PrestaShop is an International Registered Trademark & Property of PrestaShop SA
   *
   * NOTICE OF LICENSE
   *
   * This source file is subject to the Open Software License (OSL 3.0)
   * that is bundled with this package in the file LICENSE.md.
   * It is also available through the world-wide-web at this URL:
   * https://opensource.org/licenses/OSL-3.0
   * If you did not receive a copy of the license and are unable to
   * obtain it through the world-wide-web, please send an email
   * to license@prestashop.com so we can send you a copy immediately.
   *
   * DISCLAIMER
   *
   * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
   * versions in the future. If you wish to customize PrestaShop for your
   * needs please refer to https://devdocs.prestashop.com/ for more information.
   *
   * @author    PrestaShop SA and Contributors <contact@prestashop.com>
   * @copyright Since 2007 PrestaShop SA and Contributors
   * @license   https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
   */
  
  /**
   * This component is an overlay of typeahead it allows to have a single config input (since
   * typeahead weirdly uses two different configs). It also provides some default rendering
   * functions which are, of course, overridable.
   */
  export default class AutoCompleteSearch {
    constructor($searchInput, config) {
      this.$searchInput = $searchInput;
      this.searchInputId = this.$searchInput.prop('id');
  
      const inputConfig = config || {};
      // Merge default and input config
      this.config = {
        minLength: 2,
        highlight: true,
        cache: false,
        hint: false,
        ...inputConfig,
      };
  
      // Merge default and input dataSetConfig
      this.dataSetConfig = {
        display: 'name', // Which field of the object from the list is used for display (can be a string or a callback)
        value: 'id', // Which field of the object from the list is used for value (can be a string or a callback)
        limit: 20, // Limit the number of displayed suggestion
        dataLimit: 0, // How many elements can be selected max
        /* eslint-disable-next-line no-unused-vars */
        onSelect(selectedItem, event) {
          return true;
        },
        /* eslint-disable-next-line no-unused-vars */
        onClose(event) {
        },
        ...inputConfig,
      };
  
      // Merging object works fine on one level, but on two it erases sub elements even if not present, so
      // we handle templates separately, these are the default rendering functions which can be overridden
      const defaultTemplates = {
        // Be careful that your rendering function must return HTML node not pure text so always include the
        // content in a div at least
        suggestion: (item) => {
          let displaySuggestion = item;
  
          if (typeof this.dataSetConfig.display === 'function') {
            this.dataSetConfig.display(item);
          } else if (Object.prototype.hasOwnProperty.call(item, this.dataSetConfig.display)) {
            displaySuggestion = item[this.dataSetConfig.display];
          }
  
          return `<div class="px-2">${displaySuggestion}</div>`;
        },
        pending(query) {
          return `<div class="px-2">Searching for "${query.query}"</div>`;
        },
        notFound(query) {
          return `<div class="px-2">No results found for "${query.query}"</div>`;
        },
      };
  
      if (Object.prototype.hasOwnProperty.call(inputConfig, 'templates')) {
        this.dataSetConfig.templates = {...defaultTemplates, ...inputConfig.templates};
      } else {
        this.dataSetConfig.templates = defaultTemplates;
      }
  
      this.buildTypeahead();
    }
  
    /**
     * Build the typeahead component based on provided configuration.
     */
    buildTypeahead() {
      this.$searchInput.typeahead(this.config, this.dataSetConfig)
        .bind('typeahead:select', (e, selectedItem) => this.config.onSelect(selectedItem, e, this.$searchInput))
        .bind('typeahead:close', (e) => {
          this.config.onClose(e, this.$searchInput);
        });
    }
  }
  