import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
import { d as debounce } from './utils.js';
import { K as KlevuInit } from './klevu-init2.js';
import { d as defineCustomElement$4 } from './klevu-button2.js';
import { d as defineCustomElement$3 } from './klevu-icon2.js';
import { d as defineCustomElement$2 } from './klevu-textfield2.js';
import { d as defineCustomElement$1 } from './klevu-typography2.js';
import { c as cleanSearchQuery, s as search, a as sendSearchEvent } from './search.js';
import { c as KlevuTypeOfRequest, f as KlevuTypeOfRecord, K as KlevuFetch } from './klevuFetch.js';
import './KlevuApiRawResponse.js';
import './KlevuSearchSorting.js';

var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
/**
 * If original query doesn't return enough results then fallback query is run added to results
 *
 * @category Modifier
 * @param func
 * @returns
 */
function fallback(func, options) {
    var _a;
    if (((_a = func.queries) === null || _a === void 0 ? void 0 : _a.length) !== 1) {
        throw new Error("Fallback modifier can only be applied to single query");
    }
    const fallbackQuery = func.queries[0];
    fallbackQuery.isFallbackQuery = true;
    return {
        klevuModifierId: "fallback",
        modifyAfter: (queries) => __awaiter(this, void 0, void 0, function* () {
            const copy = Array.from(queries);
            for (const query of copy) {
                if (!query.id || query.isFallbackQuery === true) {
                    continue;
                }
                fallbackQuery.id = `${query.id}-fallback`;
                if (!query.settings) {
                    query.settings = {};
                }
                query.settings.fallbackQueryId = fallbackQuery.id;
                query.settings.fallbackWhenCountLessThan =
                    options === null || options === void 0 ? void 0 : options.runWhenLessThanResults;
                copy.push(fallbackQuery);
            }
            return copy;
        }),
    };
}

const defaults = {
    id: "suggestions",
    limit: 5,
};
/**
 * Return suggestion on given search term
 *
 * @category Query
 * @param term search term
 * @param options
 * @returns
 */
function suggestions(term, options) {
    const params = Object.assign(Object.assign({}, defaults), options);
    const query = Object.assign({ typeOfRequest: KlevuTypeOfRequest.Suggestion, query: cleanSearchQuery(term) }, params);
    return {
        klevuFunctionId: "suggestions",
        suggestions: [query],
    };
}

const klevuSearchFieldCss = ":host{display:flex}klevu-textfield{width:100%}klevu-button{margin-left:var(--klevu-spacing-04)}";

var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
  if (kind === "m")
    throw new TypeError("Private method is not writable");
  if (kind === "a" && !f)
    throw new TypeError("Private accessor was defined without a setter");
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
    throw new TypeError("Cannot write private member to an object whose class did not declare it");
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
  if (kind === "a" && !f)
    throw new TypeError("Private accessor was defined without a getter");
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
    throw new TypeError("Cannot read private member from an object whose class did not declare it");
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _KlevuSearchField_lastQueryResult, _KlevuSearchField_doSearch, _KlevuSearchField_handleChange, _KlevuSearchField_handleSearchClick;
const KlevuSearchField = /*@__PURE__*/ proxyCustomElement(class KlevuSearchField extends HTMLElement {
  constructor() {
    super();
    this.__registerHost();
    this.__attachShadow();
    this.klevuSearchResults = createEvent(this, "klevuSearchResults", 7);
    this.klevuSearchSuggestions = createEvent(this, "klevuSearchSuggestions", 7);
    this.klevuSearchClick = createEvent(this, "klevuSearchClick", 7);
    _KlevuSearchField_lastQueryResult.set(this, void 0);
    _KlevuSearchField_doSearch.set(this, debounce(async (term) => {
      if (term.length < 3) {
        return;
      }
      const searchModifiers = [];
      // if fallback term is defined use it to search
      if (this.fallbackTerm && this.searchProducts) {
        searchModifiers.push(fallback(search(this.fallbackTerm, {
          limit: this.limit,
        })));
      }
      if (this.sendAnalytics) {
        searchModifiers.push(sendSearchEvent());
      }
      const allSearchQueries = [];
      if (this.searchProducts) {
        allSearchQueries.push(search(term, { limit: this.limit, typeOfRecords: [KlevuTypeOfRecord.Product], sort: this.sort }, ...searchModifiers));
      }
      if (this.searchCmsPages) {
        allSearchQueries.push(search(term, { id: "cmsSearch", limit: this.limit, typeOfRecords: [KlevuTypeOfRecord.Cms], sort: this.sort }));
      }
      if (this.searchCategories) {
        allSearchQueries.push(search(term, {
          id: "categorySearch",
          limit: this.limit,
          typeOfRecords: [KlevuTypeOfRecord.Category],
          sort: this.sort,
        }));
      }
      if (this.searchSuggestions) {
        allSearchQueries.push(suggestions(term));
      }
      if (allSearchQueries.length === 0) {
        throw new Error("You need specify at least one thing to search");
      }
      const result = await KlevuFetch(...allSearchQueries);
      __classPrivateFieldSet(this, _KlevuSearchField_lastQueryResult, {
        fallback: result.queryExists("search-fallback") ? result.queriesById("search-fallback") : undefined,
        search: result.queryExists("search") ? result.queriesById("search") : undefined,
        category: result.queryExists("categorySearch") ? result.queriesById("categorySearch") : undefined,
        cms: result.queryExists("cmsSearch") ? result.queriesById("cmsSearch") : undefined,
      }, "f");
      this.klevuSearchResults.emit(__classPrivateFieldGet(this, _KlevuSearchField_lastQueryResult, "f"));
      const suggestionsResult = result.suggestionsById("suggestions");
      if (suggestionsResult) {
        this.klevuSearchSuggestions.emit(suggestionsResult.suggestions.map((s) => s.suggest));
      }
    }, 500)
    /**
     * Fetch next page of results from previous query
     *
     * @param type what type of content to get page from
     * @param pageIndex from what page. If empty next page is fetched
     */
    );
    _KlevuSearchField_handleChange.set(this, (event) => {
      this.term = event.detail;
      __classPrivateFieldGet(this, _KlevuSearchField_doSearch, "f").call(this, event.detail);
    });
    _KlevuSearchField_handleSearchClick.set(this, () => {
      this.klevuSearchClick.emit(this.term);
    });
    this.term = "";
    this.placeholder = "Search for products";
    this.searchText = "Search";
    this.limit = 10;
    this.fallbackTerm = undefined;
    this.searchProducts = undefined;
    this.searchSuggestions = undefined;
    this.searchCategories = undefined;
    this.searchCmsPages = undefined;
    this.sendAnalytics = undefined;
    this.sort = undefined;
    this.variant = "default";
  }
  async connectedCallback() {
    await KlevuInit.ready();
  }
  /**
   * Programmatically trigger search
   *
   * @param term What to search
   */
  async makeSearch(term) {
    this.term = term;
    await __classPrivateFieldGet(this, _KlevuSearchField_doSearch, "f").call(this, term);
  }
  /**
   * Fetch next page of results from previous query
   *
   * @param type what type of content to get page from
   * @param pageIndex from what page. If empty next page is fetched
   */
  async getPage(type, pageIndex) {
    if (!__classPrivateFieldGet(this, _KlevuSearchField_lastQueryResult, "f")) {
      throw new Error("No search results to get page from");
    }
    switch (type) {
      case "search": {
        const res = __classPrivateFieldGet(this, _KlevuSearchField_lastQueryResult, "f").search;
        if (res && res.getPage) {
          const result = await res.getPage({ pageIndex });
          __classPrivateFieldGet(this, _KlevuSearchField_lastQueryResult, "f").search = result === null || result === void 0 ? void 0 : result.queriesById("search");
          this.klevuSearchResults.emit({
            search: result === null || result === void 0 ? void 0 : result.queriesById("search"),
          });
        }
      }
      case "category": {
        const res = __classPrivateFieldGet(this, _KlevuSearchField_lastQueryResult, "f").category;
        if (res && res.getPage) {
          const result = await res.getPage({ pageIndex });
          __classPrivateFieldGet(this, _KlevuSearchField_lastQueryResult, "f").category = result === null || result === void 0 ? void 0 : result.queriesById("categorySearch");
          this.klevuSearchResults.emit({
            category: result === null || result === void 0 ? void 0 : result.queriesById("categorySearch"),
          });
        }
      }
      case "cms": {
        const res = __classPrivateFieldGet(this, _KlevuSearchField_lastQueryResult, "f").cms;
        if (res && res.getPage) {
          const result = await res.getPage({ pageIndex });
          __classPrivateFieldGet(this, _KlevuSearchField_lastQueryResult, "f").cms = result === null || result === void 0 ? void 0 : result.queriesById("cmsSearch");
          this.klevuSearchResults.emit({
            cms: result === null || result === void 0 ? void 0 : result.queriesById("cmsSearch"),
          });
        }
      }
    }
  }
  /**
   * Fetches query result from last request
   *
   * @param type type of query result
   * @returns
   */
  async getQueryResult(type) {
    if (!__classPrivateFieldGet(this, _KlevuSearchField_lastQueryResult, "f")) {
      throw new Error("No search results to get query results");
    }
    return __classPrivateFieldGet(this, _KlevuSearchField_lastQueryResult, "f")[type];
  }
  async propsChanged() {
    __classPrivateFieldGet(this, _KlevuSearchField_doSearch, "f").call(this, this.term);
  }
  render() {
    return (h(Host, null, h("klevu-textfield", { value: this.term, placeholder: this.placeholder, onKlevuTextChanged: __classPrivateFieldGet(this, _KlevuSearchField_handleChange, "f").bind(this), onKlevuTextEnterPressed: __classPrivateFieldGet(this, _KlevuSearchField_handleSearchClick, "f").bind(this), "aria-role": "search", variant: this.variant, icon: "search" }), this.variant !== "pill" && (h("klevu-button", { onClick: __classPrivateFieldGet(this, _KlevuSearchField_handleSearchClick, "f").bind(this) }, this.searchText))));
  }
  static get watchers() { return {
    "sort": ["propsChanged"]
  }; }
  static get style() { return klevuSearchFieldCss; }
}, [1, "klevu-search-field", {
    "placeholder": [1],
    "searchText": [1, "search-text"],
    "limit": [2],
    "fallbackTerm": [1, "fallback-term"],
    "searchProducts": [4, "search-products"],
    "searchSuggestions": [4, "search-suggestions"],
    "searchCategories": [4, "search-categories"],
    "searchCmsPages": [4, "search-cms-pages"],
    "sendAnalytics": [4, "send-analytics"],
    "sort": [1],
    "variant": [1],
    "term": [32],
    "makeSearch": [64],
    "getPage": [64],
    "getQueryResult": [64]
  }]);
_KlevuSearchField_lastQueryResult = new WeakMap(), _KlevuSearchField_doSearch = new WeakMap(), _KlevuSearchField_handleChange = new WeakMap(), _KlevuSearchField_handleSearchClick = new WeakMap();
function defineCustomElement() {
  if (typeof customElements === "undefined") {
    return;
  }
  const components = ["klevu-search-field", "klevu-button", "klevu-icon", "klevu-textfield", "klevu-typography"];
  components.forEach(tagName => { switch (tagName) {
    case "klevu-search-field":
      if (!customElements.get(tagName)) {
        customElements.define(tagName, KlevuSearchField);
      }
      break;
    case "klevu-button":
      if (!customElements.get(tagName)) {
        defineCustomElement$4();
      }
      break;
    case "klevu-icon":
      if (!customElements.get(tagName)) {
        defineCustomElement$3();
      }
      break;
    case "klevu-textfield":
      if (!customElements.get(tagName)) {
        defineCustomElement$2();
      }
      break;
    case "klevu-typography":
      if (!customElements.get(tagName)) {
        defineCustomElement$1();
      }
      break;
  } });
}
defineCustomElement();

export { KlevuSearchField as K, defineCustomElement as d };

//# sourceMappingURL=klevu-search-field2.js.map