import React, { forwardRef, useState } from "react";
import { cl } from "../../utils/helpers/index.js";
import { AutoSuggest } from "./AutoSuggest.js";
import { TokenFilterChips } from "./FilterChip.js";
import { generateAutoCompleteOptions } from "./helpers/generate-autocomplete-options.js";
import { parseQueryText } from "./helpers/parse-query-text.js";
/*
 * TODO:
 * - Implement onChange handler to update query state when user selects an autocomplete option.
 * - Handle token rendering and editing (e.g., show tokens for matched properties/operators/values, allow deleting tokens).
 * - Writing "stance" still shows status and hostname options
 */
export const TokenFilter = forwardRef(({ query, className, propertyDefinitions, options, onChange }, ref) => {
    const [filterText, setFilterText] = useState("");
    const [open, setOpen] = useState(false);
    const { parsedPropertyDefinitions, parsedPropertyOptions } = derrivedFilterState(propertyDefinitions, options);
    const queryState = parseQueryText(filterText, parsedPropertyDefinitions);
    const autoCompleteOptions = generateAutoCompleteOptions(queryState, parsedPropertyDefinitions, parsedPropertyOptions);
    const { addToken, removeToken, updateOperation } = createActionHandlers({
        query,
        onChange,
    });
    const createToken = (newText) => {
        const newQueryState = parseQueryText(newText, parsedPropertyDefinitions);
        let newToken = null;
        switch (newQueryState.step) {
            case "property": {
                if (newQueryState.value === "") {
                    return false;
                }
                newToken = {
                    propertyKey: newQueryState.property.key,
                    operator: newQueryState.operator,
                    value: newQueryState.value,
                };
                break;
            }
            case "free-text": {
                break;
            }
            case "operator": {
                break;
            }
        }
        if (newToken) {
            addToken(newToken);
            setFilterText("");
            return true;
        }
        return false;
    };
    const handleSelectOption = (option) => {
        const newQueryState = parseQueryText(option.value, parsedPropertyDefinitions);
        if ((newQueryState.step === "property" && newQueryState.value === "") ||
            newQueryState.step === "operator") {
            /* Add space after for better formatting */
            /* TODO: Handle this scenario better */
            setFilterText(`${option.value} `);
            return false;
        }
        setFilterText(option.value);
        return createToken(option.value);
    };
    return (React.createElement("div", { ref: ref, className: cl("aksel-property-filter", className), role: "search" },
        React.createElement(AutoSuggest, { onSelect: handleSelectOption, options: autoCompleteOptions.options, value: filterText, onChange: setFilterText, open: open, setOpen: setOpen }),
        React.createElement(TokenFilterChips, { tokens: query.tokens, removeToken: removeToken, updateOperation: updateOperation, operation: query.operation })));
});
function derrivedFilterState(propertyDefinitions, propteryOptions) {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const propertyMap = new Map();
    for (const property of propertyDefinitions) {
        propertyMap.set(property.key, {
            key: property.key,
            label: (_a = property === null || property === void 0 ? void 0 : property.label) !== null && _a !== void 0 ? _a : "",
            groupLabel: (_b = property === null || property === void 0 ? void 0 : property.groupLabel) !== null && _b !== void 0 ? _b : "",
            group: (_c = property === null || property === void 0 ? void 0 : property.group) !== null && _c !== void 0 ? _c : "",
            operators: (_d = property === null || property === void 0 ? void 0 : property.operators) !== null && _d !== void 0 ? _d : [],
            externalProperty: property,
        });
    }
    const internalOptions = [];
    for (const option of propteryOptions) {
        internalOptions.push({
            property: (_e = propertyMap.get(option.propertyKey)) !== null && _e !== void 0 ? _e : null,
            value: option.value,
            label: (_g = (_f = option.label) !== null && _f !== void 0 ? _f : option.value) !== null && _g !== void 0 ? _g : "",
            tags: (_h = option.tags) !== null && _h !== void 0 ? _h : [],
        });
    }
    return {
        parsedPropertyDefinitions: [...propertyMap.values()],
        parsedPropertyOptions: internalOptions,
    };
}
function createActionHandlers({ query, onChange, }) {
    const handleChange = (newQuery) => {
        onChange(newQuery);
    };
    const addToken = (token) => {
        handleChange(Object.assign(Object.assign({}, query), { tokens: [...query.tokens, token] }));
    };
    const updateToken = (updateIndex, updatedToken) => {
        handleChange(Object.assign(Object.assign({}, query), { tokens: query.tokens.map((token, index) => index === updateIndex ? updatedToken : token) }));
    };
    const updateOperation = (operation) => {
        handleChange(Object.assign(Object.assign({}, query), { operation }));
    };
    const removeToken = (removeIndex) => {
        handleChange(Object.assign(Object.assign({}, query), { tokens: query.tokens.filter((_, index) => index !== removeIndex) }));
    };
    const removeAllTokens = () => {
        handleChange(Object.assign(Object.assign({}, query), { tokens: [] }));
    };
    return {
        addToken,
        updateToken,
        updateOperation,
        removeToken,
        removeAllTokens,
    };
}
//# sourceMappingURL=TokenFilter.js.map