'use client';
"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;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SIDE_OPTIONS = void 0;
exports.AutocompleteTrigger = AutocompleteTrigger;
exports.AutocompleteValue = AutocompleteValue;
exports.AutocompleteMultipleValue = AutocompleteMultipleValue;
exports.AutocompleteEmpty = AutocompleteEmpty;
exports.AutocompleteLoading = AutocompleteLoading;
exports.AutocompleteContent = AutocompleteContent;
exports.AutocompleteGroup = AutocompleteGroup;
exports.AutocompleteItem = AutocompleteItem;
exports.Autocomplete = Autocomplete;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importDefault(require("react"));
const SelectPrimitive = __importStar(require("@radix-ui/react-select"));
const lucide_react_1 = require("lucide-react");
const badge_1 = require("../badge");
const utils_1 = require("../../../lib/utils");
const separator_1 = require("../separator");
const cmdk_1 = require("cmdk");
const use_click_away_1 = require("../../../hooks/use-click-away");
const lodash_1 = require("lodash");
const AutocompleteContext = react_1.default.createContext({
    value: [],
    onValueChange: (values) => values,
    handleChange: (value) => value,
    handleClear: () => { },
    setOpen: () => { },
    setOnScrollbar: () => { },
    options: {},
    addOption: (option) => option,
    inputRef: react_1.default.createRef()
});
const useAutocomplete = () => {
    const context = react_1.default.useContext(AutocompleteContext);
    if (!context) {
        throw new Error('useAutocomplete must be used within a AutocompleteProvider');
    }
    return context;
};
function AutocompleteTrigger({ ref, className, onClear, children }) {
    const _ref = react_1.default.useRef(null);
    const { open, readOnly, setOpen, disabled, value, inputRef, handleClear } = useAutocomplete();
    react_1.default.useImperativeHandle(ref, () => _ref.current);
    const isNoSelection = disabled || readOnly || value.length < 1;
    return ((0, jsx_runtime_1.jsxs)("div", { ref: _ref, className: (0, utils_1.cn)('bg-background ring-offset-background placeholder:text-shadcn-400 data-[disabled=true]:bg-shadcn-100 data-[read-only=true]:bg-shadcn-100 border-input flex rounded-md border text-sm focus:outline-hidden focus-visible:outline-hidden data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 data-[read-only=true]:opacity-50 md:text-sm [&>span]:line-clamp-1', {
            'h-9': value.length === 0,
            'min-h-9': value.length > 0,
            'cursor-text': !disabled && value.length !== 0
        }, className), onClick: () => {
            // Redirect focus to the input field when clicking on the container
            if (readOnly || disabled) {
                return;
            }
            if (open) {
                inputRef?.current?.blur();
            }
            else {
                inputRef?.current?.focus();
            }
            setOpen(!open);
        }, "data-disabled": disabled, "data-read-only": readOnly, children: [(0, jsx_runtime_1.jsx)("div", { className: "flex grow flex-wrap gap-1 px-3 py-2", children: children }), (0, jsx_runtime_1.jsxs)("div", { className: "flex shrink-0 items-center justify-end", children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: (0, utils_1.cn)(isNoSelection && 'hidden'), children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "text-muted-foreground mx-2 h-4 cursor-pointer", onClick: (event) => {
                                event.stopPropagation();
                                handleClear();
                                onClear?.();
                            } }) }), (0, jsx_runtime_1.jsx)(separator_1.Separator, { orientation: "vertical", className: (0, utils_1.cn)(isNoSelection && 'hidden') }), (0, jsx_runtime_1.jsx)(SelectPrimitive.Icon, { className: "cursor-pointer data-[disabled=true]:cursor-not-allowed data-[read-only=true]:cursor-default", "data-disabled": disabled, "data-read-only": readOnly, children: (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { className: "mx-3 my-2 h-4 w-4 opacity-50" }) })] })] }));
}
function AutocompleteValue({ ref, className, value: valueProp, onValueChange, onBlur, ...props }) {
    const [search, setSearch] = react_1.default.useState(valueProp);
    const { value, showValue, options, readOnly, disabled, inputRef } = useAutocomplete();
    react_1.default.useImperativeHandle(ref, () => inputRef.current);
    const updateSearch = (value) => {
        if ((0, lodash_1.isNil)(value)) {
            return;
        }
        const v = typeof value === 'string' ? value : value[0];
        if (v === '') {
            handleValueChange('');
            return;
        }
        handleValueChange(showValue ? v : options[v]);
    };
    const handleValueChange = (value) => {
        setSearch(value);
        onValueChange?.(value);
    };
    const handleBlur = (event) => {
        updateSearch(value);
        onBlur?.(event);
    };
    // If options changes, update only the internal value
    react_1.default.useEffect(() => {
        if ((0, lodash_1.isNil)(value)) {
            return;
        }
        const v = typeof value === 'string' ? value : value[0];
        if (v === '') {
            return;
        }
        setSearch(showValue ? v : options[v]);
    }, [options]);
    react_1.default.useEffect(() => {
        updateSearch(value);
    }, [value]);
    return ((0, jsx_runtime_1.jsx)(cmdk_1.Command.Input, { ...props, ref: inputRef, value: search, onValueChange: handleValueChange, disabled: disabled, readOnly: readOnly, className: (0, utils_1.cn)('placeholder:text-muted-foreground w-full bg-transparent outline-hidden read-only:opacity-50 read-only:placeholder:opacity-0 focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-50 disabled:placeholder:opacity-0', className), onBlur: handleBlur }));
}
function AutocompleteMultipleValue({ ref, className, ...props }) {
    const { value, disabled, handleChange, options, showValue, inputRef } = useAutocomplete();
    react_1.default.useImperativeHandle(ref, () => inputRef.current);
    return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [options &&
                value?.map((value) => ((0, jsx_runtime_1.jsxs)(badge_1.Badge, { variant: "secondary", className: (0, utils_1.cn)('data-disabled:bg-muted-foreground data-fixed:bg-muted-foreground data-disabled:text-muted data-fixed:text-muted data-disabled:hover:bg-muted-foreground data-fixed:hover:bg-muted-foreground'), children: [showValue ? value : options[value], (0, jsx_runtime_1.jsx)("button", { type: "button", className: (0, utils_1.cn)('ring-offset-background focus:ring-ring ml-1 rounded-full outline-hidden focus:ring-2 focus:ring-offset-2', disabled && 'hidden'), children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "text-muted-foreground hover:text-foreground h-3 w-3", onClick: (event) => {
                                    event.stopPropagation();
                                    handleChange(value);
                                } }) })] }, value))), (0, jsx_runtime_1.jsx)(cmdk_1.Command.Input, { ...props, ref: inputRef, disabled: disabled, className: (0, utils_1.cn)('placeholder:text-muted-foreground w-full bg-transparent outline-hidden focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-50 disabled:placeholder:opacity-0', className) })] }));
}
function AutocompleteEmpty({ className, ...props }) {
    const render = (0, cmdk_1.useCommandState)((state) => state.filtered.count === 0);
    if (!render)
        return null;
    return ((0, jsx_runtime_1.jsx)("div", { "data-slot": "autocomplete-empty", className: (0, utils_1.cn)('py-6 text-center text-sm', className), "cmdk-empty": "", role: "presentation", ...props }));
}
function AutocompleteLoading({ className, ref, ...props }) {
    return ((0, jsx_runtime_1.jsx)(cmdk_1.Command.Loading, { ref: ref, "data-slot": "autocomplete-loading", className: (0, utils_1.cn)('flex items-center justify-center py-6 text-center text-sm', className), ...props, children: (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "text-muted-foreground h-5 w-5 animate-spin" }) }));
}
exports.SIDE_OPTIONS = ['top', 'right', 'bottom', 'left'];
function AutocompleteContent({ className, position = 'popper', side = 'bottom', ref, children, onMouseEnter, onMouseLeave, onPointerDownOutside, ...props }) {
    const _ref = react_1.default.useRef(null);
    const { open, addOption, setOpen, onScrollbar, setOnScrollbar, inputRef } = useAutocomplete();
    react_1.default.useImperativeHandle(ref, () => _ref.current);
    (0, use_click_away_1.useClickAway)(_ref, (event) => {
        // Should not close when clicking on the scrollbar
        if (onScrollbar) {
            return;
        }
        setOpen(false);
        inputRef.current?.blur();
        onPointerDownOutside?.(event);
    });
    /**
     * Iterates recursively into react children to find valid items options
     * Adds the valid ones into the options object
     * @param children
     */
    const _searchChildren = (children) => {
        react_1.default.Children.forEach(react_1.default.Children.toArray(children), (child) => {
            // If child is already invalid, like pure string, dismiss
            if (!react_1.default.isValidElement(child)) {
                return;
            }
            // If child is recognized as an AutocompleteItem
            if (child.type &&
                child.type.displayName === 'AutocompleteItem') {
                // Check if the item was proper filled with a value prop
                if (child.props.value) {
                    addOption({
                        [child.props.value]: child.props.children
                    });
                }
                return;
            }
            // If not, search recursively into the childrens
            if (child.props.children) {
                _searchChildren(child.props.children);
            }
        });
    };
    // Since this component is not going to be rendered in the DOM until open is true,
    // we need to register the options when the component mounts
    // and when the children changes.
    react_1.default.useEffect(() => {
        _searchChildren(children);
    }, [children]);
    if (!open) {
        return null;
    }
    return ((0, jsx_runtime_1.jsx)("div", { className: "relative", children: (0, jsx_runtime_1.jsx)(cmdk_1.Command.List, { ref: _ref, className: (0, utils_1.cn)('bg-popover text-popover-foreground animate-in absolute top-1 z-50 max-h-96 w-full min-w-32 overflow-x-hidden overflow-y-auto rounded-md border shadow-md outline-hidden', position === 'popper' &&
                'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1', className), "data-side": side, ...props, onMouseEnter: (e) => {
                onMouseEnter?.(e);
                setOnScrollbar(true);
            }, onMouseLeave: (e) => {
                onMouseLeave?.(e);
                setOnScrollbar(false);
            }, children: children }) }));
}
function AutocompleteGroup({ className, ...props }) {
    return ((0, jsx_runtime_1.jsx)(cmdk_1.Command.Group, { "data-slot": "autocomplete-group", className: (0, utils_1.cn)('text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium', className), ...props }));
}
function AutocompleteItem({ className, value, onSelect, ...props }) {
    const { handleChange } = useAutocomplete();
    return ((0, jsx_runtime_1.jsx)(cmdk_1.Command.Item, { "data-slot": "autocomplete-item", value: value, className: (0, utils_1.cn)("data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", className), ...props, onMouseDown: (e) => {
            e.preventDefault();
            e.stopPropagation();
        }, onSelect: (value) => {
            handleChange(value);
            onSelect?.(value);
        } }));
}
function Autocomplete({ ref, value, defaultValue, onValueChange, onClear, className, open: openProp, onOpenChange, showValue, readOnly, disabled, multiple, onKeyDown, children, ...props }) {
    const _ref = react_1.default.useRef(null);
    const [open, _setOpen] = react_1.default.useState(openProp);
    const inputRef = react_1.default.useRef(null);
    const [onScrollbar, setOnScrollbar] = react_1.default.useState(false);
    const [selected, setSelected] = react_1.default.useState(defaultValue ?? value ?? (multiple ? [] : ''));
    const [options, addOption] = react_1.default.useReducer((prev, state) => ({
        ...prev,
        ...state
    }), {});
    react_1.default.useImperativeHandle(ref, () => _ref.current);
    const setOpen = (open) => {
        _setOpen(open);
        onOpenChange?.(open);
    };
    const handleClear = () => {
        onClear?.();
        if (!multiple) {
            setSelected('');
            onValueChange?.('');
            return;
        }
        setSelected([]);
        onValueChange?.([]);
    };
    const handleChange = react_1.default.useCallback((value) => {
        if (!value) {
            return;
        }
        if (!multiple) {
            setSelected(value);
            onValueChange?.(value);
            setOpen(false);
            return;
        }
        const newSelected = selected.includes(value)
            ? selected.filter((item) => item !== value)
            : [...selected, value];
        setSelected(newSelected);
        onValueChange?.(newSelected);
    }, [selected, onValueChange]);
    const handleKeyDown = react_1.default.useCallback((e) => {
        const input = inputRef.current;
        if (input) {
            if (e.key === 'Delete' || e.key === 'Backspace') {
                if (multiple) {
                    if (input.value === '' && selected.length > 0) {
                        handleChange(selected[selected.length - 1]);
                    }
                }
            }
            // This is not a default behavior of the <input /> field
            if (e.key === 'Escape') {
                e.stopPropagation();
                input.blur();
            }
        }
    }, [selected, handleChange]);
    // Keeps the selected value in sync with the value prop
    react_1.default.useEffect(() => {
        if (!(0, lodash_1.isNil)(value)) {
            setSelected(value);
        }
    }, [value]);
    // Keeps the open state in sync with the open prop
    react_1.default.useEffect(() => {
        if (openProp !== undefined) {
            setOpen(openProp);
        }
    }, [openProp]);
    return ((0, jsx_runtime_1.jsx)(AutocompleteContext.Provider, { value: {
            value: selected,
            onValueChange: setSelected,
            showValue,
            readOnly,
            disabled,
            handleChange,
            handleClear,
            onScrollbar,
            setOnScrollbar,
            open,
            setOpen,
            options,
            addOption,
            inputRef
        }, children: (0, jsx_runtime_1.jsx)(cmdk_1.Command, { ref: _ref, className: (0, utils_1.cn)('text-foreground flex h-auto w-full flex-col overflow-visible rounded-md bg-transparent', className), "data-disabled": disabled, "aria-disabled": disabled, "data-read-only": readOnly, "aria-readonly": readOnly, ...props, onKeyDown: (e) => {
                handleKeyDown(e);
                onKeyDown?.(e);
            }, children: children }) }));
}
