import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
import { forwardRef, useState, useEffect, useMemo, useContext } from 'react';
import { dropdownDefaultCSSData } from './dropdownTypes.js';
import { ThemeContext } from '../ThemeProvider/ThemeProvider.js';
import classNames from '../../_virtual/index.js';
import Button from '../Button/Button.js';
import Typography from '../Typography/Typography.js';
import Checkbox from '../Checkbox/Checkbox.js';
import Tooltip from '../Tooltip/Tooltip.js';
import { isTextTruncated, truncateText } from '../../utils/truncateText/truncateText.js';
import { getValue, getLabel } from '../../utils/getSelectOptionValue/getSelectOptionValue.js';
import { useIntersectionObserver } from '../../hooks/useIntersectionObserver.js';
import { useKeyboardActions } from '../../utils/keyBoardActionUtil/UseKeyboardActions.js';
import { ALPHA_NUM_EXTENDED_REGEX, START_END_WHITESPACE_REGEX } from '../../validations/regex.js';
import { ffid } from '../../utils/ffID/ffid.js';

const Dropdown = forwardRef(({ options, handleOptionChange, searchedKeyword = '', dropdownPosition = {}, zIndex, withSelectButton, labelAccessor = 'label', valueAccessor = 'value', searchAccessor = valueAccessor, loadMoreOptions, isAllSelected, onToggleAllSelect, isAllSelect, maxDropdownHeight: _maxDropdownHeight, variant, handleIconClick, noResultsMessage, maxSearchCharacterLength = 25, }, ref) => {
    const [focusedIndex, setFocusedIndex] = useState(null);
    const [validationError, setValidationError] = useState(null);
    const [selectDisable, setSelectDisable] = useState(true);
    const filteredOptions = options
        ? options.filter((option) => getValue(option, searchAccessor)
            ?.toLowerCase()
            .includes(searchedKeyword.trim().toLowerCase()))
        : [];
    const { verticalMargin, optionHeight, maxDropdownHeight } = dropdownDefaultCSSData;
    useEffect(() => {
        if (variant !== 'labels')
            return;
        switch (true) {
            case searchedKeyword.length < 3 && searchedKeyword.trim() !== '':
                setValidationError('Minimum 3 characters required');
                break;
            case !!searchedKeyword &&
                !START_END_WHITESPACE_REGEX.test(searchedKeyword):
                setValidationError('Space is not allowed at starting and at the end');
                break;
            case !!searchedKeyword &&
                !ALPHA_NUM_EXTENDED_REGEX.test(searchedKeyword):
                setValidationError('Name should be alphanumeric');
                break;
            case searchedKeyword.length > maxSearchCharacterLength:
                setValidationError(`Maximum ${maxSearchCharacterLength} characters allowed`);
                break;
            default:
                setValidationError(null);
        }
    }, [searchedKeyword, variant, maxSearchCharacterLength]);
    useEffect(() => {
        const hasChecked = filteredOptions.some((option) => option.isChecked === true && !option.isDisabled);
        setSelectDisable(!hasChecked);
    }, [filteredOptions]);
    const onSelectClick = (e) => {
        e.stopPropagation();
        handleOptionChange({}, false);
    };
    const renderOption = (info, labelAccessor) => {
        if (typeof info[labelAccessor] === 'string') {
            return truncateText(getLabel(info, labelAccessor), dropdownPosition.width - 50, 'pixel');
        }
        return info[labelAccessor];
    };
    const topPosition = useMemo(() => {
        let calculatedDropdownHeight = Math.min(filteredOptions.length * optionHeight, _maxDropdownHeight || maxDropdownHeight);
        if (filteredOptions.length < 5 && withSelectButton) {
            calculatedDropdownHeight += 32;
        }
        const isEnoughSpaceAvailable = dropdownPosition.fromBottom >=
            calculatedDropdownHeight + verticalMargin;
        const topPosition = isEnoughSpaceAvailable
            ? dropdownPosition.top
            : dropdownPosition.top -
                calculatedDropdownHeight -
                dropdownPosition.selectHeight -
                2 * verticalMargin;
        return topPosition;
    }, [filteredOptions.length, withSelectButton, dropdownPosition]);
    const themeContext = useContext(ThemeContext);
    const currentTheme = themeContext?.currentTheme;
    useIntersectionObserver(['ff-multiselect-pagination'], {
        root: document.getElementById('ff-multiselect-options-wrapper'),
        rootMargin: '0px',
        threshold: 0.1,
        onIntersect: (entry, _observer) => {
            if (entry.isIntersecting) {
                if (loadMoreOptions) {
                    loadMoreOptions();
                }
            }
        },
    });
    useKeyboardActions([
        {
            key: 'ArrowDown',
            action: () => {
                setFocusedIndex((prev) => prev === null ? 0 : (prev + 1) % filteredOptions.length);
            },
        },
        {
            key: 'ArrowUp',
            action: () => {
                setFocusedIndex((prev) => prev === null
                    ? filteredOptions.length - 1
                    : (prev - 1 + filteredOptions.length) % filteredOptions.length);
            },
        },
        {
            key: 'Enter',
            action: () => {
                if (focusedIndex !== null) {
                    handleOptionChange(filteredOptions[focusedIndex], !filteredOptions[focusedIndex]?.isChecked);
                }
                else {
                    withSelectButton && !selectDisable && handleOptionChange({}, false);
                }
            },
        },
    ]);
    useEffect(() => {
        if (focusedIndex !== null) {
            const optionElement = document.querySelector(`.dropdown-option-container:nth-child(${focusedIndex + 1})`);
            if (optionElement) {
                optionElement.scrollIntoView({
                    behavior: 'smooth',
                    block: 'nearest',
                });
            }
        }
    }, [focusedIndex]);
    return (jsxs("div", { role: "listbox", ref: ref, className: classNames('ff-multiselect-dropdown-container', {
            [currentTheme || '']: true,
        }), style: {
            left: dropdownPosition.left,
            top: topPosition,
            width: dropdownPosition.width,
            zIndex,
            maxHeight: `${_maxDropdownHeight}px`,
        }, children: [jsx("div", { className: "ff-multiselect-options-wrapper", style: {
                    maxHeight: withSelectButton
                        ? `${_maxDropdownHeight - 32}px`
                        : `${_maxDropdownHeight}px`,
                }, id: "ff-multiselect-options-wrapper", children: validationError ? (jsx(Typography, { as: "p", className: "validation-error", children: validationError })) : filteredOptions.length === 0 ? (variant === 'labels' && searchedKeyword.trim().length > 2 ? (jsxs(Typography, { as: "p", className: "no-options", onClick: handleIconClick, children: [searchedKeyword, ' ', jsx(Typography, { as: "span", color: 'var(--brand-color)', children: "add label" })] })) : (jsx(Typography, { textAlign: "center", as: "p", className: "no-options", children: noResultsMessage || 'No Result Found' }))) : (jsxs(Fragment, { children: [isAllSelect && (jsxs("div", { className: "dropdown-option-container", children: [jsx(Checkbox, { checked: isAllSelected, onChange: (event) => {
                                        onToggleAllSelect?.(event.target.checked);
                                    } }), jsx(Typography, { className: "dropdown-option-label", children: "All" })] })), filteredOptions.map((info, index) => (jsxs("div", { role: "option", className: `dropdown-option-container${info.isDisabled ? ' disabled' : ''} ${focusedIndex === index ? 'focused' : ''}`, onMouseEnter: () => setFocusedIndex(null), onClick: (e) => {
                                const target = e.target;
                                if (target.type === 'checkbox') {
                                    return;
                                }
                                !info?.isDisabled &&
                                    handleOptionChange(info, !info.isChecked);
                            }, children: [jsx(Checkbox, { checked: info.isChecked, disabled: info?.isDisabled }), jsx(Tooltip, { zIndex: zIndex + 1, title: isTextTruncated(getLabel(info, labelAccessor), dropdownPosition.width - 50, 'pixel')
                                        ? getLabel(info, labelAccessor)
                                        : '', children: jsx(Typography, { className: "dropdown-option-label", children: renderOption(info, labelAccessor) }) })] }, getLabel(info, labelAccessor) + ffid()))), jsx("div", { id: "ff-multiselect-pagination" })] })) }), withSelectButton && filteredOptions.length > 0 && (jsx("div", { className: "select-button-container", children: jsx(Button, { label: "Select", variant: "primary", onClick: onSelectClick, disabled: selectDisable, buttonWidth: "100%", buttonHeight: "24px" }) }))] }));
});

export { Dropdown as default };
//# sourceMappingURL=Dropdown.js.map
