import { SearchQuery, InputSearchQuery, SearchResult, SearchOptions } from '@nosto/nosto-js/client';
import * as _nosto_search_js from '@nosto/search-js';
import { HitDecorator, SearchOptions as SearchOptions$1 } from '@nosto/search-js';
export { priceDecorator } from '@nosto/search-js/currencies';

/**
 * @group Autocomplete
 * @category Core
 */
interface GoogleAnalyticsConfig {
    /**
     * Path of search page
     * @default "/search"
     */
    serpPath?: string;
    /**
     * Search query url parameter name
     * @default "query"
     */
    queryParamName?: string;
    /**
     * Enable Google Analytics
     * @default true
     */
    enabled?: boolean;
}
type Selector = string | Element;
/**
 * @group Autocomplete
 * @category Core
 */
interface AutocompleteConfig<State> {
    /**
     * The input element to attach the autocomplete to
     */
    inputSelector: Selector;
    /**
     * The dropdown element to attach the autocomplete to
     */
    dropdownSelector: Selector | ((input: HTMLInputElement) => Selector);
    /**
     * The function to use to render the dropdown
     */
    render: (container: HTMLElement, state: State) => void | PromiseLike<void>;
    /**
     * Minimum length of the query before searching
     */
    minQueryLength?: number;
    /**
     * The function to use to fetch the search state
     */
    fetch: SearchQuery | ((input: string) => PromiseLike<State>);
    /**
     * The function to use to submit the search
     */
    submit?: (query: string, config: AutocompleteConfig<State>, options?: SearchAutocompleteOptions) => void;
    /**
     * Enable history
     */
    historyEnabled?: boolean;
    /**
     * Max number of history items to show
     */
    historySize?: number;
    /**
     * Enable Nosto Analytics
     */
    nostoAnalytics?: boolean;
    /**
     * Google Analytics configuration. Set to `false` to disable.
     */
    googleAnalytics?: GoogleAnalyticsConfig | boolean;
    /**
     * Decorate each search hit before rendering
     *
     * @example
     * ```ts
     * import { priceDecorator } from "@nosto/autocomplete"
     *
     * autocomplete({
     *   hitDecorators: [
     *     priceDecorator({ defaultCurrency: "USD" })
     *   ]
     * })
     * ```
     */
    hitDecorators?: HitDecorator[];
    /**
     * Whether to submit the form natively or not
     */
    nativeSubmit?: boolean;
    /**
     * A function to call when the user clicks on a search hit to use custom routing
     * @example
     * ```ts
     * autocomplete({
     *  routingHandler: (url) => {
     *    location.href = url
     *  }
     * })
     * ```
     */
    routingHandler?: (url: string) => void;
}

/**
 * @group Autocomplete
 * @category Core
 */
interface DefaultState {
    /**
     * The current search query object.
     */
    query?: InputSearchQuery;
    /**
     * The current search response.
     */
    response?: SearchResult;
    /**
     * The history items.
     */
    history?: {
        item: string;
    }[];
}

type AutocompleteInstance = {
    /**
     * Open the dropdown.
     */
    open(): void;
    /**
     * Close the dropdown.
     */
    close(): void;
    /**
     * Destroy the autocomplete instance.
     */
    destroy(): void;
};
type SearchAutocompleteOptions = Pick<SearchOptions, "isKeyword" | "redirect">;
/**
 * @param config Autocomplete configuration.
 * @returns Autocomplete instance.
 * @group Autocomplete
 * @category Core
 * @example
 * ```js
 * import { autocomplete } from '@nosto/autocomplete';
 *
 * // Basic usage
 * autocomplete({
 *   inputSelector: '#search',
 *   dropdownSelector: '#dropdown',
 *   render: (container, state) => {
 *     container.innerHTML = `
 *        <div>
 *         <h1>${state.query}</h1>
 *        <ul>
 *        ${state.response.products
 *          .map((product) => `<li>${product.name}</li>`)
 *          .join('')}
 *       </ul>
 *     </div>
 *    `;
 *   },
 *   fetch: {
 *     products: {
 *       fields: ['name', 'url', 'imageUrl', 'price', 'listPrice', 'brand'],
 *       size: 5
 *     },
 *     keywords: {
 *       size: 5,
 *       fields: ['keyword', '_highlight.keyword'],
 *       highlight: {
 *         preTag: `<strong>`,
 *         postTag: '</strong>'
 *       }
 *     }
 *   }
 * });
 *
 * // Liquid template.
 * import { autocomplete, fromRemoteLiquidTemplate, fromLiquidTemplate, defaultLiquidTemplate } from '@nosto/autocomplete/liquid';
 *
 * autocomplete({
 *   inputSelector: '#search',
 *   dropdownSelector: '#dropdown',
 *   render: fromRemoteLiquidTemplate('autocomplete.liquid'),
 *   // Or:
 *   render: window.nostoAutocomplete.fromLiquidTemplate(defaultLiquidTemplate),
 *   ...
 * });
 *
 * // Mustache template.
 * import { autocomplete, fromRemoteMustacheTemplate, fromMustacheTemplate, defaultMustacheTemplate } from '@nosto/autocomplete/mustache';
 *
 * autocomplete({
 *   inputSelector: '#search',
 *   dropdownSelector: '#dropdown',
 *   render: fromRemoteMustacheTemplate('autocomplete.mustache'),
 *   // Or:
 *   render: fromMustacheTemplate(defaultMustacheTemplate),
 *   ...
 * });
 *
 * // React example.
 * import { autocomplete, Autocomplete } from '@nosto/autocomplete/react';
 * import ReactDOM from 'react-dom';
 *
 * let reactRoot;
 *
 * autocomplete({
 *   inputSelector: '#search',
 *   dropdownSelector: '#dropdown',
 *   render: function (container, state) {
 *     if (!reactRoot) {
 *       reactRoot = ReactDOM.createRoot(container);
 *     }
 *     reactRoot.render(<Autocomplete {...state} />);
 *   },
 *   ...
 * });
 * ```
 */
declare function autocomplete<State = DefaultState>(config: AutocompleteConfig<State>): AutocompleteInstance;

/**
 *
 * @param query Query object.
 * @param options Options object.
 * @returns Promise of search response.
 * @group Autocomplete
 * @category Core
 * @example
 * ```js
 * import { search } from "@nosto/autocomplete"
 *
 * search({
 *     query: "shoes",
 *     products: {
 *       fields: ["name", "price"],
 *       facets: ["brand", "category"],
 *       size: 10,
 *       from: 0,
 *     }
 * }).then((state) => {
 *    console.log(state.response)
 * })
 * ```
 */
declare function search(query: SearchQuery, options?: SearchOptions$1): Promise<{
    query: SearchQuery;
    response: _nosto_search_js.DecoratedResult<readonly _nosto_search_js.HitDecorator[]>;
}>;

export { autocomplete, search };
export type { AutocompleteConfig, AutocompleteInstance, DefaultState, GoogleAnalyticsConfig, SearchAutocompleteOptions, Selector };
