import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
import { useMemo, useState, useRef, useEffect } from 'react';
import Icon from '../Icon/Icon.js';
import Typography from '../Typography/Typography.js';
import classNames from '../../_virtual/index.js';
import { createPortal } from 'react-dom';
import Dropdown from './components/Dropdown.js';
import { getValue } from '../../utils/getSelectOptionValue/getSelectOptionValue.js';
import usePortalPosition from '../../hooks/usePortalPosition.js';
import Tooltip from '../Tooltip/Tooltip.js';
import { checkEmpty } from '../../utils/checkEmpty/checkEmpty.js';
import { truncateText } from '../../utils/truncateText/truncateText.js';

const Select = ({ label = 'Default Label', showLabel = true, optionsList = [], selectedOption = { label: '', value: '' }, onChange = () => { }, errorMsg = '', className = '', optionZIndex = 1500, disabled = false, showBorder = true, required = true, optionsRequired = true, selectedOptionColor = 'var(--ff-select-text-color)', labelAccessor = '', valueAccessor = '', height = 32, width = '100%', onBlur = () => { }, disableInput = false, showIcon = false, placeHolder = '', showToolTip = false, onCancelModal = () => { }, onSaveModal = () => { }, modalJSXProps = jsx(Fragment, {}), recurrence = false, showArrowIcon = true, showClearIcon = false, handelClear = () => { }, showOptions = { open: false, toggle: false }, tooltip = false, background = '', borderRadius = '0px', noResultsMessage, dropDownRef, dropDownHeight = 160, onSearchText, isCustomButtonDisabled = false, hasInnerClearIcon = false, dropdownInnerIconWidth = 0, onDropdownOpen = () => { }, }) => {
    const selectWidth = typeof width === 'number' ? `${width}px` : width;
    const memoizedOptionsList = useMemo(() => optionsList, [optionsList]);
    const [showDropdownOptions, setShowDropdownOptions] = useState(false);
    const [customRecurrence, setCustomRecurrence] = useState(false);
    const [searchedOption, setSearchedOption] = useState({
        searchedText: '',
        searchedIcon: '',
        searchedIconColor: '',
    });
    const { searchedText, searchedIcon, searchedIconColor } = searchedOption;
    const [selectOptionList, setSelectOptionList] = useState([]);
    const [dropdownPosition, setDropdownPosition] = useState({
        positionX: 0,
        positionY: 0,
        width: 0,
        fromBottom: 0,
    });
    const DropdownRef = useRef(null);
    const selectWrapperRef = useRef(null);
    const inputRef = useRef(null);
    const selectArrowRef = useRef(null);
    const calculatePosition = usePortalPosition(inputRef, showDropdownOptions);
    const handleIconClick = () => {
        if (disabled)
            return;
        setShowDropdownOptions(!showDropdownOptions);
        setSearchedOption({
            ...searchedOption,
            searchedText: getValue(selectedOption, valueAccessor) || '',
        });
        setSelectOptionList(optionsList);
        if (!showDropdownOptions && inputRef.current) {
            inputRef.current.focus();
        }
    };
    const handleChange = (event) => {
        if (disabled)
            return;
        const { value } = event.target;
        onSearchText?.(value);
        const filteredOptions = optionsList.filter((option) => {
            const valueData = getValue(option, valueAccessor);
            return valueData.trim().toLowerCase().includes(value.toLowerCase().trim());
        });
        setSelectOptionList(filteredOptions);
        setSearchedOption({
            ...searchedOption,
            searchedText: value,
        });
    };
    const onSelectUpdatePosition = () => {
        if (!showDropdownOptions || !DropdownRef?.current || disabled)
            return;
        setDropdownPosition(calculatePosition(inputRef));
    };
    const onSelectToggleScroll = (isEnabled) => {
        const scrollWidth = window.innerWidth - document.documentElement.clientWidth;
        if (isEnabled) {
            document.body.style.paddingRight = '';
            document.body.style.overflow = '';
        }
        else {
            document.body.style.paddingRight = `${scrollWidth}px`;
            document.body.style.overflow = 'hidden';
        }
    };
    const handleFocus = () => {
        if (disabled)
            return;
        setShowDropdownOptions(true);
    };
    useEffect(() => {
        if (showOptions.open) {
            setShowDropdownOptions(true);
        }
    }, [showOptions.toggle]);
    const onSelectBlur = () => {
        setShowDropdownOptions(false);
        setDropdownPosition({
            positionX: 0,
            positionY: 0,
            fromBottom: 0,
            width: 0,
        });
        setSelectOptionList(optionsList);
        if (inputRef?.current === document.activeElement) {
            inputRef?.current?.blur();
            setSearchedOption({
                searchedText: getValue(selectedOption, valueAccessor) || '',
                searchedIcon: selectedOption.iconName || '',
                searchedIconColor: selectedOption.iconColor,
            });
            setCustomRecurrence(false);
            onBlur();
        }
    };
    const onSelectOptionSelector = (option) => {
        if (disabled)
            return;
        const isCustomRecurrence = option?.recurrence || false;
        setCustomRecurrence(isCustomRecurrence);
        setSearchedOption({
            searchedText: getValue(selectedOption, valueAccessor),
            searchedIcon: selectedOption.iconName,
            searchedIconColor: selectedOption.iconColor,
        });
        if (!isCustomRecurrence) {
            onSelectBlur();
        }
        if (onChange) {
            onChange(option);
        }
    };
    const handleResizeOrScroll = () => onSelectUpdatePosition();
    const getScrollParent = (element) => {
        const scrollableParents = [];
        if (!element)
            return scrollableParents;
        let parent = element.parentElement;
        while (parent) {
            const tagName = parent.tagName.toLowerCase();
            // Skip tbody and similar non-scrollable semantic containers
            if (tagName === 'tbody') {
                parent = parent.parentElement;
                continue;
            }
            const style = window.getComputedStyle(parent);
            const overflowY = style.overflowY;
            const overflowX = style.overflowX;
            const isScrollable = (overflowY === 'auto' ||
                overflowY === 'scroll' ||
                overflowX === 'auto' ||
                overflowX === 'scroll') &&
                (parent.scrollHeight > parent.clientHeight ||
                    parent.scrollWidth > parent.clientWidth);
            if (isScrollable) {
                scrollableParents.push(parent);
            }
            parent = parent.parentElement;
        }
        // as fallback also include window scroll (document.body)
        return scrollableParents.length ? scrollableParents : [document.body];
    };
    useEffect(() => {
        if (!showDropdownOptions || disabled)
            return;
        onDropdownOpen();
        if (optionsRequired) {
            onSelectToggleScroll(false);
        }
        onSelectUpdatePosition();
        const scrollableParents = getScrollParent(inputRef.current);
        window.addEventListener('resize', handleResizeOrScroll);
        scrollableParents.forEach((parent) => {
            parent.addEventListener('scroll', onSelectBlur);
        });
        return () => {
            onSelectToggleScroll(true);
            window.removeEventListener('resize', handleResizeOrScroll);
            scrollableParents.forEach((parent) => {
                parent.removeEventListener('scroll', onSelectBlur);
            });
        };
    }, [showDropdownOptions]);
    useEffect(() => {
        setSearchedOption({
            searchedText: getValue(selectedOption, valueAccessor),
            searchedIcon: selectedOption.iconName,
            searchedIconColor: selectedOption.iconColor,
        });
    }, [
        selectedOption?.label,
        selectedOption?.value,
        selectedOption?.iconName,
        getValue(selectedOption, valueAccessor),
    ]);
    useEffect(() => {
        setSelectOptionList(memoizedOptionsList);
    }, [memoizedOptionsList]);
    if (showLabel) {
        placeHolder = '';
    }
    const [isTruncated, setIsTruncated] = useState(false);
    const [displaySearchedText, setDisplaySearchedText] = useState('');
    useEffect(() => {
        const updateTruncation = () => {
            const input = inputRef.current;
            if (!input)
                return;
            // derive properties from input
            const styles = window.getComputedStyle(input);
            const paddingLeft = parseFloat(styles.paddingLeft || '0');
            const paddingRight = parseFloat(styles.paddingRight || '0');
            const availableWidth = input.clientWidth - paddingLeft - paddingRight;
            const fontSize = parseFloat(styles.fontSize || '12');
            const fontFamily = styles.fontFamily;
            const letterSpacing = parseFloat(styles.letterSpacing || '0') || 0;
            const truncated = truncateText(searchedText, availableWidth, 'pixel', fontSize, fontFamily, letterSpacing);
            setDisplaySearchedText(truncated);
            setIsTruncated(truncated !== searchedText); // if different → truncated → show tooltip
        };
        updateTruncation();
        window.addEventListener('resize', updateTruncation);
        return () => {
            window.removeEventListener('resize', updateTruncation);
        };
    }, [searchedText, width]);
    const inputElement = (jsxs(Fragment, { children: [jsx("input", { type: "text", ref: inputRef, id: "select-input-element", className: classNames('ff-select-inputField', {
                    'ff-select-inputField__disabled': disabled,
                    'ff-select-inputField__readonly': disableInput,
                    'ff-select-inputField__icon': showIcon && !checkEmpty(searchedIcon),
                    'ff-select-inputField__hasicon': hasInnerClearIcon,
                }), onFocus: handleFocus, value: isTruncated ? displaySearchedText : searchedText, autoCorrect: "off", autoComplete: "off", spellCheck: "false", style: {
                    zIndex: optionZIndex,
                    color: selectedOptionColor,
                }, disabled: disabled, onChange: handleChange, readOnly: disableInput, placeholder: placeHolder }), hasInnerClearIcon && (jsx("span", { className: "ff-select-clear-icon", children: jsx(Tooltip, { title: "Clear", children: jsx(Icon, { name: "close", height: 16, width: 16, onClick: handelClear, hoverEffect: true, cursorType: "pointer" }) }) }))] }));
    return (jsxs("div", { className: `ff-select-wrapper ${className} ${showClearIcon ? 'show-clear-icon' : ''}`, ref: selectWrapperRef, style: {
            height: `${height}px`,
            width: `${selectWidth}`,
            background: `${background}`,
            borderRadius: `${borderRadius}`,
        }, children: [jsxs("div", { className: classNames('ff-select', {
                    'ff-select__focus': showDropdownOptions,
                    'ff-select__disabled': disabled,
                    'ff-select__error': !!errorMsg,
                    'ff-select__error__focused': !!errorMsg && showDropdownOptions,
                    'ff-select__no_border': !showBorder,
                }), children: [showIcon && !checkEmpty(searchedIcon) && (jsx(Tooltip, { placement: "bottom", title: searchedText, children: jsx(Icon, { name: searchedIcon, color: searchedIconColor, className: "ff-select-input-icon", withPadding: !checkEmpty(searchedText) }) })), tooltip && isTruncated ? (jsx(Tooltip, { title: searchedText, style: { width: '100%' }, children: inputElement })) : (inputElement), optionsRequired && (jsx("div", { ref: selectArrowRef, className: classNames('ff-select-arrows-wrapper', {
                            'ff-select-arrows-wrapper__disabled': disabled,
                        }), onClick: handleIconClick, children: showArrowIcon && (jsx(Icon, { name: "arrow_down", className: "ff-select-arrows", height: 8, width: 12, color: 'var(--brand-color)', "z-index": 9999 })) })), showLabel && (jsx(Typography, { as: "span", className: classNames('ff-select-labels', {
                            'ff-select-labels__icon': showIcon && !checkEmpty(searchedIcon),
                            'ff-select-labels__active': searchedText,
                        }), fontSize: searchedText || showDropdownOptions ? 10 : 12, lineHeight: searchedText || showDropdownOptions ? '12px' : '16px', required: required, style: {
                            maxWidth: `calc(${selectWidth} - ${hasInnerClearIcon ? '56px' : '40px'})`,
                        }, children: label }))] }), errorMsg && (jsx(Typography, { as: "div", lineHeight: "15px", fontSize: 10, color: "var(--error_light)", className: "ff-select-error-msg", children: errorMsg })), optionsRequired && (jsx("div", { ref: DropdownRef, children: showDropdownOptions &&
                    createPortal(jsx(Dropdown, { options: selectOptionList, dropdownPosition: dropdownPosition, labelAccessor: labelAccessor, optionZIndex: optionZIndex, inputRef: inputRef, selectArrowRef: selectArrowRef, onSelectBlur: onSelectBlur, onSelectOptionSelector: onSelectOptionSelector, heightFromTop: height, selectedOption: selectedOption, showIcon: showIcon, showToolTip: showToolTip, customReccurenece: customRecurrence, onSaveModal: onSaveModal, onCancelModal: () => {
                            onCancelModal();
                            setCustomRecurrence(false);
                        }, modalJSXProps: modalJSXProps, recurrence: recurrence, valueAccessor: valueAccessor, showArrowIcon: showArrowIcon, showClearIcon: showClearIcon, hasInnerClearIcon: hasInnerClearIcon, noResultsMessage: noResultsMessage, ref: dropDownRef, searchedIcon: searchedIcon, dropDownHeight: dropDownHeight, isCustomButtonDisabled: isCustomButtonDisabled, dropdownInnerIconWidth: dropdownInnerIconWidth }), document.body) })), showClearIcon && (jsx(Tooltip, { title: "Cancel", style: { zIndex: 99999 }, children: jsx(Icon, { name: "close", height: 16, width: 16, onClick: handelClear, hoverEffect: true }) }))] }));
};

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