"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenFilter = void 0;
const react_1 = __importStar(require("react"));
const helpers_1 = require("../../utils/helpers");
const AutoSuggest_1 = require("./AutoSuggest");
const FilterChip_1 = require("./FilterChip");
const generate_autocomplete_options_1 = require("./helpers/generate-autocomplete-options");
const parse_query_text_1 = require("./helpers/parse-query-text");
/*
 * 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
 */
exports.TokenFilter = (0, react_1.forwardRef)(({ query, className, propertyDefinitions, options, onChange }, ref) => {
    const [filterText, setFilterText] = (0, react_1.useState)("");
    const [open, setOpen] = (0, react_1.useState)(false);
    const { parsedPropertyDefinitions, parsedPropertyOptions } = derrivedFilterState(propertyDefinitions, options);
    const queryState = (0, parse_query_text_1.parseQueryText)(filterText, parsedPropertyDefinitions);
    const autoCompleteOptions = (0, generate_autocomplete_options_1.generateAutoCompleteOptions)(queryState, parsedPropertyDefinitions, parsedPropertyOptions);
    const { addToken, removeToken, updateOperation } = createActionHandlers({
        query,
        onChange,
    });
    const createToken = (newText) => {
        const newQueryState = (0, parse_query_text_1.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 = (0, parse_query_text_1.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_1.default.createElement("div", { ref: ref, className: (0, helpers_1.cl)("aksel-property-filter", className), role: "search" },
        react_1.default.createElement(AutoSuggest_1.AutoSuggest, { onSelect: handleSelectOption, options: autoCompleteOptions.options, value: filterText, onChange: setFilterText, open: open, setOpen: setOpen }),
        react_1.default.createElement(FilterChip_1.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