import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import ListItemIcon from '@mui/material/ListItemIcon';
import MuiPopper from '@mui/material/Popper';
import { useCallback, useRef, } from 'react';
import { CrossOutlineMd } from '../../icons/CrossOutlineMd';
import { DownOutlineMd } from '../../icons/DownOutlineMd';
import { Checkbox } from '../Checkbox';
import { forwardRefWithGeneric } from '../forwardRefWithGeneric';
import { Loader } from '../Loader';
import { OverflowTypography } from '../OverflowTypography';
import { TagsList } from '../TagsList';
import { TextField } from '../TextField';
import { classNames } from '../utils/classNames';
import { DEFAULT_AUTOCOMPLETE_ELEMENT_ROWS_COUNT, DEFAULT_PLACEHOLDER, INPUT_MIN_WIDTH, } from './constants';
import { StyledAutocomplete, StyledMenuItem } from './styles';
import { useLogic } from './useLogic';
const AutocompleteInner = (props, ref) => {
    const { isValueEmpty, isPopperVisible, autocompleteProps } = useLogic(props);
    const inputBaseRef = useRef(null);
    const { required, success, error, label, getOptionLabel, helperText, inputRef, multiple, size = 'medium', placeholder = DEFAULT_PLACEHOLDER, overflowOption, closeText = 'Закрыть', openText = 'Открыть', clearText = 'Очистить', loadingText = _jsx(Loader, {}), isLoadedDataError, loadedDataError, noOptionsText, autoHighlight, renderInput: externalRenderInput, renderTags: externalRenderTags, renderOption: externalRenderOption, inputProps, hideHelperText = false, loading, value, onChange, ...restProps } = props;
    const renderInput = useCallback((inputParams) => {
        const createStartAdornment = () => {
            if (!multiple || !Array.isArray(value)) {
                return null;
            }
            const tagsListElement = (_jsx(TagsList, { data: value, getOptionLabel: (option) => getOptionLabel?.(option) ??
                    option.toString(), inputContainerRef: inputBaseRef, reservedWidth: INPUT_MIN_WIDTH, onChange: (tagValues) => {
                    if (!onChange) {
                        return;
                    }
                    const syntheticEvent = {
                        type: 'change',
                        target: { value: tagValues },
                        currentTarget: { value: tagValues },
                    };
                    const reason = 'removeOption';
                    onChange(syntheticEvent, tagValues, reason);
                } }));
            return tagsListElement;
        };
        const generalInputParams = {
            ...inputParams,
            inputProps: {
                ...inputParams.inputProps,
                className: classNames(inputParams?.inputProps?.className, inputProps?.className),
            },
            InputProps: {
                ...inputParams.InputProps,
                ref: (element) => {
                    inputBaseRef.current = element;
                    const orig = inputParams.InputProps?.ref;
                    if (typeof orig === 'function') {
                        orig(element);
                    }
                    else if (orig) {
                        orig.current = element;
                    }
                },
                // Если есть externalRenderTags, используем renderTags(mui использует inputParams.InputProps?.startAdornment)
                startAdornment: externalRenderTags
                    ? inputParams.InputProps?.startAdornment
                    : createStartAdornment(),
            },
            inputRef,
            required,
            placeholder: isValueEmpty ? placeholder : '',
            label,
            success,
            error,
            helperText,
            size,
            hideHelperText,
        };
        if (externalRenderInput) {
            return externalRenderInput(generalInputParams);
        }
        return _jsx(TextField, { ...generalInputParams });
    }, [
        isValueEmpty,
        value,
        externalRenderInput,
        externalRenderTags,
        inputRef,
        required,
        placeholder,
        label,
        success,
        error,
        helperText,
        size,
        hideHelperText,
        multiple,
        getOptionLabel,
        onChange,
    ]);
    const renderOption = useCallback((optionProps, option, optionState, ownerState) => {
        if (externalRenderOption) {
            return externalRenderOption(optionProps, option, optionState, ownerState);
        }
        const isSelected = Boolean(optionProps['aria-selected']);
        const { key, ...restOptionProps } = optionProps;
        return (_jsxs(StyledMenuItem, { selected: isSelected, ...restOptionProps, children: [multiple && (_jsx(ListItemIcon, { children: _jsx(Checkbox, { role: "menuitemcheckbox", checked: isSelected }) })), _jsx(OverflowTypography, { rowsCount: DEFAULT_AUTOCOMPLETE_ELEMENT_ROWS_COUNT, ...overflowOption, children: optionProps.key })] }, key));
    }, [multiple, overflowOption, externalRenderOption]);
    const renderPopper = useCallback((popperProps) => {
        if (!isPopperVisible) {
            return null;
        }
        return _jsx(MuiPopper, { ...popperProps });
    }, [isPopperVisible]);
    const renderTags = useCallback((tags, getTagProps, ownerState) => {
        if (externalRenderTags) {
            return externalRenderTags(tags, getTagProps, ownerState);
        }
        return null;
    }, [externalRenderTags]);
    return (_jsx(StyledAutocomplete, { ...restProps, ref: ref, size: size, clearText: clearText, closeText: !loading ? closeText : '', openText: !loading ? openText : '', loadingText: loadingText, multiple: multiple, disableCloseOnSelect: multiple, clearIcon: _jsx(CrossOutlineMd, {}), loading: loading, popupIcon: loading ? _jsx(Loader, { color: "primary", size: "small" }) : _jsx(DownOutlineMd, {}), forcePopupIcon: true, slotProps: {
            popper: {
                component: renderPopper,
            },
        }, getOptionLabel: getOptionLabel, renderInput: renderInput, renderTags: renderTags, renderOption: renderOption, value: value, onChange: onChange, ...autocompleteProps }));
};
export const Autocomplete = forwardRefWithGeneric(AutocompleteInner);
