import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/*
 * Copyright (c) 2020-present SMC Treviso s.r.l. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
import { faSearch } from "@fortawesome/free-solid-svg-icons/faSearch";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React from "react";
import { useTranslation } from "react-i18next";
import { css } from "styled-components";
import { TokenSelect } from "../components/TokenSelect";
import Autocomplete from "./Autocomplete";
import { DeleteLogo } from "./DeleteLogo";
import { useAutocomplete } from "./useAutocomplete";
import { useClickAway } from "./useClickAway";
export function Search({ configuration, spans, selectionsState, selectionsDispatch, showSyntax, btnSearch = true, htmlKey, customMessageSearch, messageSearchIsVisible = true, viewColor = true, actionOnClick, callbackClickSearch, characterControl, extraClass, callbackChangeSearch, }) {
    const autoSelect = configuration.searchAutoselect;
    const replaceText = configuration.searchReplaceText;
    const [openedDropdown, setOpenedDropdown] = React.useState({ textPosition: 0, optionPosition: 1 });
    const [isAutocompleteOpen, setIsAutocompleteOpen] = React.useState(false);
    const [highlightIndex, setHighlightIndex] = React.useState(-1);
    const [acceptSuggestion, setAcceptSuggestion] = React.useState(true);
    const autocompleteQ = useAutocomplete(selectionsState.textOnChange, configuration.autocompleteEnabled);
    const suggestions = autocompleteQ.data ?? [];
    React.useEffect(() => {
        if (suggestions.length > 0) {
            setIsAutocompleteOpen(true);
        }
        else {
            setIsAutocompleteOpen(false);
        }
    }, [suggestions]);
    const clickAwayRef = React.useRef(null);
    useClickAway([clickAwayRef], () => {
        setOpenedDropdown(null);
        setIsAutocompleteOpen(false);
    });
    const inputRef = React.useRef(null);
    const [adjustedSelection, setAdjustedSelection] = React.useState({ selectionStart: 0, selectionEnd: 0 });
    React.useLayoutEffect(() => {
        if (inputRef.current) {
            inputRef.current.selectionStart = adjustedSelection.selectionStart;
            inputRef.current.selectionEnd = adjustedSelection.selectionEnd;
        }
    }, [adjustedSelection]);
    const { setText, search, clearSearch } = setValueSearch({
        isBtn: btnSearch,
        selectionsDispatch,
        characterControl,
        actionSearch: characterControl?.actionCharacter,
    });
    const { t } = useTranslation();
    const applySuggestion = (s) => {
        selectionsDispatch({
            type: "set-text",
            text: s.autocomplete,
            textOnchange: s.autocomplete,
        });
        setIsAutocompleteOpen(false);
        setHighlightIndex(-1);
        setOpenedDropdown(null);
        setAcceptSuggestion(true);
        inputRef.current?.focus();
    };
    return (_jsx(React.Fragment, { children: _jsxs("div", { className: "openk9--search-container", css: css `
          display: flex;
          align-items: center;
          gap: 10px;
          width: 100%;
          @media (max-width: 480px) {
            flex-direction: row;
          }
          .openk9-focusable:has(input:focus) {
            border: 1px solid #c22525;
          }
        `, children: [_jsxs("div", { ref: clickAwayRef, className: "openk9-embeddable-search--input-container openk9-focusable", css: css `
            display: flex;
            align-items: center;
            border-radius: 8px;
            width: 100%;
            max-height: 50px;
            position: relative;
            @media (max-width: 480px) {
              width: 100%;
            }
          `, children: [_jsx(FontAwesomeIcon, { className: "openk9--search-icon", icon: faSearch, css: css `
              padding-left: 16px;
              opacity: 0.5;
              color: var(--openk9-embeddable-search--secondary-text-color);
            ` }), isAutocompleteOpen &&
                            suggestions.length > 0 &&
                            selectionsState.textOnChange &&
                            !acceptSuggestion && (_jsx(Autocomplete, { applySuggestion: applySuggestion, highlightIndex: highlightIndex, setHighlightIndex: setHighlightIndex, setIsAutocompleteOpen: setIsAutocompleteOpen, suggestions: suggestions })), _jsxs("div", { className: "openk9--search-container-show-syntax", css: css `
              flex-grow: 1;
              position: relative;
              display: flex;
            `, children: [_jsx("div", { className: "openk9--search-show-syntax", css: css `
                top: 0px;
                left: 0px;
                width: 100%;
                padding: var(--openk9-embeddable-search--input-padding);
                display: flex;
                position: absolute;
                @media (max-width: 480px) {
                  display: none;
                }
              `, children: showSyntax &&
                                        spans.map((span, index) => {
                                            const isOpen = openedDropdown !== null &&
                                                openedDropdown.textPosition > span.start &&
                                                openedDropdown.textPosition <= span.end &&
                                                span.tokens.length > 0;
                                            const optionIndex = openedDropdown?.optionPosition ?? null;
                                            const selection = selectionsState.selection.find((s) => s.start === span.start && s.end === span.end);
                                            const selected = selection?.token ?? null;
                                            const onSelect = (token) => {
                                                selectionsDispatch({
                                                    type: "set-selection",
                                                    replaceText,
                                                    selection: {
                                                        text: span.text,
                                                        textOnChange: span.text,
                                                        start: span.start,
                                                        end: span.end,
                                                        token,
                                                        isAuto: autoSelect,
                                                    },
                                                });
                                                setIsAutocompleteOpen(false);
                                                if (inputRef.current?.selectionStart &&
                                                    inputRef.current?.selectionEnd) {
                                                    setAdjustedSelection({
                                                        selectionStart: inputRef.current.selectionStart,
                                                        selectionEnd: inputRef.current.selectionEnd,
                                                    });
                                                }
                                            };
                                            const isAutoSelected = selection?.isAuto ?? false;
                                            const onOptionIndexChange = (i) => {
                                                setOpenedDropdown((o) => o ? { ...o, optionPosition: i } : o);
                                            };
                                            return (_jsx(TokenSelect, { span: span, isOpen: isOpen, onOptionIndexChange: onOptionIndexChange, optionIndex: optionIndex, selected: selected, onSelect: onSelect, isAutoSlected: isAutoSelected, setOpenedDropdown: setOpenedDropdown, isColorSearch: viewColor }, index));
                                        }) }), !htmlKey && (_jsx("label", { htmlFor: "search-openk9", className: "visually-hidden label-search", css: css `
                  border: 0;
                  padding: 0;
                  margin: 0;
                  position: absolute !important;
                  height: 1px;
                  width: 1px;
                  overflow: hidden;
                  clip: rect(1px 1px 1px 1px);
                  clip: rect(1px, 1px, 1px, 1px);
                  clip-path: inset(50%);
                  white-space: nowrap;
                `, children: "Search" })), _jsx("input", { className: `openk9--input-search ${extraClass?.input || ""}`, autoComplete: "off", ref: inputRef, id: htmlKey || "search-openk9", "aria-describedby": "message-search", type: "text", placeholder: t("search") || "search...", value: selectionsState.textOnChange, onClick: () => {
                                        callbackClickSearch && callbackClickSearch();
                                        setAcceptSuggestion(false);
                                        if (suggestions.length > 0) {
                                            setIsAutocompleteOpen(true);
                                            setHighlightIndex(-1);
                                        }
                                    }, onFocus: () => {
                                        setAcceptSuggestion(false);
                                        if (suggestions.length > 0) {
                                            setIsAutocompleteOpen(true);
                                            setHighlightIndex(-1);
                                        }
                                    }, onBlur: (e) => {
                                        const related = e.relatedTarget;
                                        if (!related ||
                                            !related.className?.includes("openk9--autocomplete-suggestion-item")) {
                                            setIsAutocompleteOpen(false);
                                        }
                                    }, onChange: (event) => {
                                        setText(event.currentTarget.value);
                                        setAcceptSuggestion(false);
                                        if (suggestions.length > 0)
                                            setIsAutocompleteOpen(true);
                                        callbackChangeSearch &&
                                            callbackChangeSearch(event.currentTarget.value);
                                    }, css: css `
                position: relative;
                flex-grow: 1;
                border: none;
                outline: none;
                padding: var(--openk9-embeddable-search--input-padding);
                caret-color: black;
                font-size: inherit;
                font-family: inherit;
                background-color: inherit;
                color: ${viewColor
                                        ? showSyntax
                                            ? "transparent"
                                            : "black"
                                        : "black"};
                @media (max-width: 480px) {
                  color: black;
                }
              `, spellCheck: "false", onSelect: (event) => {
                                        if ((event.currentTarget.selectionDirection === "forward" ||
                                            event.currentTarget.selectionDirection === "none") &&
                                            event.currentTarget.selectionStart ===
                                                event.currentTarget.selectionEnd) {
                                            setOpenedDropdown({
                                                textPosition: event.currentTarget.selectionStart,
                                                optionPosition: openedDropdown?.optionPosition ?? 0,
                                            });
                                        }
                                    }, onKeyDown: (event) => {
                                        setAcceptSuggestion(false);
                                        if (isAutocompleteOpen && suggestions.length > 0) {
                                            if (event.key === "ArrowDown") {
                                                event.preventDefault();
                                                setHighlightIndex((prev) => prev < suggestions.length - 1 ? prev + 1 : 0);
                                            }
                                            else if (event.key === "ArrowUp") {
                                                event.preventDefault();
                                                setHighlightIndex((prev) => prev > 0 ? prev - 1 : suggestions.length - 1);
                                            }
                                            else if (event.key === "Enter") {
                                                if (highlightIndex >= 0 &&
                                                    highlightIndex < suggestions.length) {
                                                    event.preventDefault();
                                                    applySuggestion(suggestions[highlightIndex]);
                                                }
                                                else {
                                                    event.preventDefault();
                                                    inputRef &&
                                                        inputRef.current &&
                                                        search(inputRef.current.value || "");
                                                    if (actionOnClick)
                                                        actionOnClick();
                                                }
                                            }
                                            else if (event.key === "Escape") {
                                                setIsAutocompleteOpen(false);
                                                setHighlightIndex(-1);
                                            }
                                        }
                                        else {
                                            const span = openedDropdown &&
                                                spans.find((s) => openedDropdown.textPosition > s.start &&
                                                    openedDropdown.textPosition <= s.end);
                                            const option = openedDropdown &&
                                                span?.tokens[openedDropdown.optionPosition - 1];
                                            if (event.key === "ArrowDown") {
                                                event.preventDefault();
                                                if (openedDropdown && span) {
                                                    setOpenedDropdown({
                                                        textPosition: openedDropdown.textPosition,
                                                        optionPosition: openedDropdown.optionPosition < span.tokens.length
                                                            ? openedDropdown.optionPosition + 1
                                                            : 1,
                                                    });
                                                }
                                            }
                                            else if (event.key === "ArrowUp") {
                                                event.preventDefault();
                                                if (openedDropdown && openedDropdown.optionPosition > 0) {
                                                    setOpenedDropdown({
                                                        textPosition: openedDropdown.textPosition,
                                                        optionPosition: openedDropdown.optionPosition === 1
                                                            ? span?.tokens.length || 1
                                                            : openedDropdown.optionPosition - 1,
                                                    });
                                                }
                                            }
                                            else if (event.key === "Enter") {
                                                event.preventDefault();
                                                inputRef &&
                                                    inputRef.current &&
                                                    search(inputRef?.current?.value || "");
                                                if (actionOnClick)
                                                    actionOnClick();
                                                if (span && option) {
                                                    selectionsDispatch({
                                                        type: "set-selection",
                                                        replaceText,
                                                        selection: {
                                                            text: span.text,
                                                            textOnChange: span.text,
                                                            start: span.start,
                                                            end: span.end,
                                                            token: option ?? null,
                                                            isAuto: false,
                                                        },
                                                    });
                                                    if (replaceText && option) {
                                                        const text = option &&
                                                            (option.tokenType === "ENTITY"
                                                                ? option.entityName
                                                                : option.value);
                                                        const cursorPosition = span.start + (text?.length ?? 0);
                                                        setAdjustedSelection({
                                                            selectionStart: cursorPosition,
                                                            selectionEnd: cursorPosition,
                                                        });
                                                    }
                                                    else if (event.currentTarget.selectionStart &&
                                                        event.currentTarget.selectionEnd) {
                                                        setAdjustedSelection({
                                                            selectionStart: event.currentTarget.selectionStart,
                                                            selectionEnd: event.currentTarget.selectionEnd,
                                                        });
                                                    }
                                                }
                                            }
                                        }
                                    } }), messageSearchIsVisible && (_jsx("p", { className: "visually-hidden", id: "message-search", css: css `
                  border: 0;
                  padding: 0;
                  margin: 0;
                  position: absolute !important;
                  height: 1px;
                  width: 1px;
                  overflow: hidden;
                  clip: rect(1px 1px 1px 1px);
                  clip: rect(1px, 1px, 1px, 1px);
                  clip-path: inset(50%);
                  white-space: nowrap;
                `, children: customMessageSearch ||
                                        t("insert-text-to-set-the-value-or-use-up-and-down-arrow-keys-to-navigate-the-suggestion-box") ||
                                        "insert text to set the value or use up and down arrow keys to navigate the suggestion box" }))] }), _jsx("button", { className: "openk9--search-delete-container-icon", title: t("remove-text") || "", "aria-label": t("remove-text") || "", css: css `
              padding-right: 16px;
              display: flex;
              flex-direction: row;
              padding: 4px 8px;
              gap: 4px;
              align-items: center;
              margin-right: 21px;
              background: inherit;
              border: none;
              position: relative;
              z-index: 10;
            `, tabIndex: 0, onClick: (e) => {
                                e.stopPropagation();
                                setIsAutocompleteOpen(false);
                                clearSearch();
                                inputRef.current?.focus();
                            }, children: _jsx("span", { className: "openk9--search-delete-span-icon", css: css `
                cursor: pointer;
              `, children: _jsx(DeleteLogo, {}) }) })] }), btnSearch && (_jsx("div", { className: "openk9-search-btn-external-container", children: _jsx("button", { className: `openk9-search-btn-external ${extraClass?.button || ""}`, "aria-label": t("search-on-website") || "search on website", css: css `
                min-height: 50px;
                min-width: 50px;
                border: 1px solid var(--openk9-embeddable-search--border-color);
                border-radius: 8px;
                cursor: pointer;
                background-color: white;
                display: flex;
                justify-content: center;
                align-items: center;
              `, onClick: () => {
                            inputRef &&
                                inputRef.current &&
                                search(inputRef.current.value || "");
                            if (actionOnClick)
                                actionOnClick();
                        }, children: _jsx("svg", { "aria-hidden": "true", className: "openk9-search-btn-external-icon", height: "1em", viewBox: "0 0 512 512", fill: "gray", children: _jsx("path", { d: "M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z" }) }) }) }))] }) }));
}
function setValueSearch({ isBtn, selectionsDispatch, characterControl, actionSearch, }) {
    const setText = (text) => !isBtn
        ? selectionsDispatch({
            type: "set-text",
            text,
            textOnchange: text,
        })
        : selectionsDispatch({
            type: "set-text-btn",
            textOnchange: text,
        });
    const search = (text) => {
        (!characterControl?.numberOfCharacters ||
            text === "" ||
            text.length > characterControl.numberOfCharacters) &&
            selectionsDispatch({
                type: "set-text",
                text,
                textOnchange: text,
            });
        if (characterControl &&
            text.length <= characterControl.numberOfCharacters &&
            text !== "") {
            actionSearch && actionSearch();
        }
    };
    const clearSearch = () => selectionsDispatch({
        type: "reset-search",
    });
    return { setText, search, clearSearch };
}
export const SearchMemo = React.memo(Search);
