import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { useContext, useRef, forwardRef, useMemo, useEffect, } from 'react';
import { dropdownDefaultCSSData } from './types';
import './Dropdown.scss';
import { checkEmpty } from '../../../utils/checkEmpty/checkEmpty';
import Typography from '../../Typography';
import { ThemeContext } from '../../ThemeProvider/ThemeProvider';
import classNames from 'classnames';
import { getLabel, getValue, } from '../../../utils/getSelectOptionValue/getSelectOptionValue';
import useClickOutside from '../../../hooks/useClickOutside';
import Icon from '../../Icon';
import Button from '../../Button';
import { useMergeRefs } from '../../../hooks/useMergeRefs';
import TruncatedTooltip from '../../TruncatedTooltip';
import { FixedSizeList } from 'react-window';
const Dropdown = forwardRef(({ options = [], optionZIndex = 10000000, dropdownPosition, labelAccessor, onSelectOptionSelector, onSelectBlur, inputRef, selectArrowRef, heightFromTop, selectedOption, valueAccessor, showIcon = false, customReccurenece = true, onCancelModal = () => { }, onSaveModal = () => { }, recurrence = false, modalJSXProps = _jsx(_Fragment, {}), showArrowIcon = true, hasInnerClearIcon = false, noResultsMessage, searchedIcon = '', dropDownHeight = 160, isCustomButtonDisabled = false, dropdownInnerIconWidth = 0, highlightedIndex, sortedOptions, }, ref) => {
    const themeContext = useContext(ThemeContext);
    const currentTheme = themeContext?.currentTheme;
    const { optionHeight, dropDownWrapperPadding } = dropdownDefaultCSSData;
    const listRef = useRef(null);
    const customRecurrenceOnBlur = customReccurenece ? () => { } : onSelectBlur;
    const optionsWrapperRef = useRef(null);
    const mergedRef = useMergeRefs(optionsWrapperRef, ref);
    useClickOutside(optionsWrapperRef, customRecurrenceOnBlur, [
        inputRef,
        selectArrowRef,
    ]);
    const { positionX, positionY, fromBottom, width } = dropdownPosition;
    const { margin, selectInputHeight } = dropdownDefaultCSSData;
    const updateDropdownPosition = () => {
        let dropdownContainerHeight;
        if (checkEmpty(options)) {
            dropdownContainerHeight = 32 + 2 * dropDownWrapperPadding;
        }
        else if (options?.length > 5) {
            dropdownContainerHeight = 160;
        }
        else {
            dropdownContainerHeight =
                options.length * optionHeight + 2 * dropDownWrapperPadding;
        }
        if (fromBottom > dropdownContainerHeight + margin) {
            const dynamicHeightFromTop = heightFromTop <= 25
                ? heightFromTop + 7
                : heightFromTop <= 32
                    ? heightFromTop
                    : heightFromTop <= 40
                        ? heightFromTop - 4
                        : heightFromTop <= 50
                            ? heightFromTop - 9
                            : heightFromTop - 15;
            return {
                left: positionX,
                top: positionY + dynamicHeightFromTop - 10,
                width: hasInnerClearIcon
                    ? width + dropdownInnerIconWidth
                    : showIcon && !checkEmpty(searchedIcon)
                        ? width + 70
                        : showArrowIcon
                            ? width + 32
                            : width + 10,
                zIndex: optionZIndex,
                marginLeft: showIcon && !checkEmpty(searchedIcon) ? '-31px' : '-2px',
            };
        }
        return {
            zIndex: optionZIndex,
            left: positionX,
            width: hasInnerClearIcon
                ? width + dropdownInnerIconWidth
                : showIcon
                    ? width + 70
                    : showArrowIcon
                        ? width + 32
                        : width + 10,
            top: positionY - selectInputHeight - dropdownContainerHeight + 4 * margin,
            marginLeft: showIcon ? '-29px' : '-2px',
        };
    };
    const positionStyle = updateDropdownPosition();
    const dropdownWidth = positionStyle.width;
    const basePadding = 16;
    const iconPadding = showIcon ? 32 : 0;
    const effectiveContentWidth = customReccurenece
        ? (typeof dropdownWidth === 'number' ? dropdownWidth / 2 : 0) -
            basePadding -
            iconPadding
        : dropdownWidth - basePadding - iconPadding;
    const getOptionLabel = (label, icon, tooltipWidth, iconColor) => {
        if (React.isValidElement(label)) {
            return label;
        }
        return (_jsxs("div", { className: "ff-select-dropdown-option-wrapper", children: [showIcon && icon && (_jsx(Icon, { name: icon, className: "ff-select-dropdown__icon", ...(iconColor && { color: iconColor }) })), _jsx(Typography, { as: "div", lineHeight: "25px", color: "var(--ff-select-text-color)", className: classNames('ff-select-dropdown-text', {
                        'ff-select-dropdown-icon-container': showIcon,
                    }), children: _jsx(TruncatedTooltip, { title: label, width: tooltipWidth }) })] }));
    };
    const onHandleCancelModal = () => {
        onCancelModal();
    };
    const onHandleSaveModal = () => {
        onSelectBlur();
        onSaveModal();
    };
    // Calculate height for virtualization
    const listHeight = useMemo(() => {
        if (sortedOptions.length === 0)
            return 32;
        if (sortedOptions.length > 5)
            return dropDownHeight;
        return sortedOptions.length * optionHeight;
    }, [sortedOptions]);
    const renderRow = ({ index, style }) => {
        const item = sortedOptions[index];
        if (!item)
            return null;
        const isHighlighted = index === highlightedIndex;
        // GROUP HEADER
        if (item.type === 'group') {
            return (_jsx("div", { style: style, className: classNames('ff-select-dropdown-group-header', currentTheme), children: _jsx(Typography, { className: "ff-select-dropdown-group", children: item.groupName }) }));
        }
        // OPTION
        const option = item.option;
        const optionValue = getValue(option, valueAccessor);
        const optionLabel = getLabel(option, labelAccessor);
        const iconName = 'iconName' in option ? option.iconName : undefined;
        const iconColor = 'iconColor' in option ? option.iconColor : undefined;
        const isDisabled = 'disable' in option && option.disable;
        return (_jsx("div", { className: classNames('ff-select-dropdown-option', {
                'ff-select-dropdown-option__selected': optionValue === selectedOption?.value &&
                    selectedOption?.group == option?.group,
            }, {
                'ff-select-dropdown-option__disabled': isDisabled,
            }, {
                'ff-select-dropdown-option__highlighted': isHighlighted,
            }, currentTheme), "aria-selected": isHighlighted, style: style, onClick: () => {
                if (isDisabled)
                    return;
                onSelectOptionSelector(option);
            }, children: getOptionLabel(optionLabel, iconName, effectiveContentWidth, iconColor) }, index));
    };
    useEffect(() => {
        if (highlightedIndex >= 0) {
            listRef.current?.scrollToItem(highlightedIndex, 'smart');
        }
    }, [highlightedIndex]);
    return (_jsxs("div", { className: classNames('ff-select-dropdown-wrapper', currentTheme, {
            'ff-select-dropdown-modal-wrapper': recurrence,
            'ff-select-dropdown-mini-modal-wrapper': customReccurenece,
        }), ref: mergedRef, style: positionStyle, children: [_jsx("div", { className: classNames({
                    'ff-select-label-minimodal-wrapper': customReccurenece,
                }), children: sortedOptions.length > 0 ? (_jsx("div", { style: {
                        padding: `${dropDownWrapperPadding}px 0`,
                        fontSize: '12px',
                    }, children: _jsx(FixedSizeList, { height: listHeight, width: "100%", itemCount: sortedOptions.length, itemSize: optionHeight, ref: listRef, children: renderRow }) })) : (_jsx(Typography, { textAlign: "center", as: "div", lineHeight: "32px", color: "var(--ff-select-text-color)", className: classNames('ff-select-no-option', currentTheme), children: noResultsMessage || 'No Result Found' })) }), customReccurenece && (_jsx("div", { className: "ff-select-mini-modal-wrapper", id: "ff-select-mini-id", children: _jsxs("div", { className: "ff-select-modal-wrapper", children: [_jsx(_Fragment, { children: modalJSXProps }), _jsxs("div", { className: "ff-select-mini-modal-footer", children: [_jsx(Button, { label: "Cancel", variant: "tertiary", onClick: onHandleCancelModal }), _jsx(Button, { label: "Save", variant: "primary", onClick: onHandleSaveModal, disabled: isCustomButtonDisabled })] })] }) }))] }));
});
export default Dropdown;
//# sourceMappingURL=Dropdown.js.map