import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access */
import { Autocomplete, CircularProgress, FormControl, TextField, } from '@mui/material';
import cx from 'classnames';
import { ThemeProvider, useTheme } from '@mui/material/styles';
import { useEffect, useRef, useState } from 'react';
import { Controller } from 'react-hook-form';
import { selectAutocompleteTheme } from './SelectAutocompleteTheme';
import './styles.scss';
const MIN_QUERY_LENGTH = 2;
const LOAD_DEBOUNCE_MS = 300;
export default function AsyncSelectField({ className, attr, label, createdForm, disabled, title, placeholder, loadOptions, required, multiple = false, freeSolo = false, minQueryLength = MIN_QUERY_LENGTH, onChange, noOptionsText, }) {
    const fieldName = attr;
    const outerTheme = useTheme();
    const [options, setOptions] = useState([]);
    const [active, setActive] = useState(false);
    const [loading, setLoading] = useState(false);
    const [focus, setFocus] = useState(false);
    const [mouseOver, setMouseOver] = useState(false);
    const [inputValue, setInputValue] = useState('');
    const debounceRef = useRef(null);
    const hasError = () => !!createdForm.formState.errors[attr];
    const getClassNames = cx('ds-select-text', className, {
        disabled: disabled,
    });
    useEffect(() => {
        if (debounceRef.current) {
            clearTimeout(debounceRef.current);
        }
        if (inputValue.length < minQueryLength) {
            setOptions([]);
            setLoading(false);
            return;
        }
        debounceRef.current = setTimeout(() => {
            setLoading(true);
            loadOptions(inputValue)
                .then((data) => {
                setOptions(data);
                setLoading(false);
            })
                .catch(() => {
                setLoading(false);
            });
        }, LOAD_DEBOUNCE_MS);
        return () => {
            if (debounceRef.current) {
                clearTimeout(debounceRef.current);
            }
        };
    }, [inputValue, loadOptions, minQueryLength]);
    useEffect(() => {
        if (focus || mouseOver) {
            setActive(true);
        }
        else {
            setActive(false);
        }
    }, [focus, mouseOver]);
    const commitFreeSoloInput = (field, input) => {
        const trimmed = input.trim();
        if (!trimmed)
            return;
        const current = field.value;
        if (typeof current === 'string' && current.trim() === trimmed)
            return;
        if (current != null &&
            typeof current === 'object' &&
            'value' in current &&
            String(current.value).trim() === trimmed) {
            return;
        }
        field.onChange(trimmed);
        onChange?.(attr, trimmed);
    };
    return (_jsx("div", { className: getClassNames, children: _jsx(Controller, { name: fieldName, control: createdForm.control, render: ({ field }) => (_jsxs(ThemeProvider, { theme: selectAutocompleteTheme(outerTheme), children: [_jsx(FormControl, { fullWidth: true, variant: "filled", disabled: disabled, children: _jsx(Autocomplete, { multiple: multiple, freeSolo: freeSolo, disableCloseOnSelect: multiple, value: field.value ?? (multiple ? [] : null), onChange: (_event, newValue) => {
                                field.onChange(newValue);
                                onChange?.(attr, newValue);
                            }, onInputChange: (_event, newInputValue) => {
                                setInputValue(newInputValue);
                            }, onFocus: () => setFocus(true), onBlur: (event) => {
                                setFocus(false);
                                if (freeSolo && !multiple) {
                                    const target = event.target;
                                    commitFreeSoloInput(field, target?.value ?? inputValue);
                                }
                            }, onMouseOver: () => setMouseOver(true), onMouseOut: () => setMouseOver(false), options: options, loading: loading, isOptionEqualToValue: (option, value) => {
                                if (typeof option === 'string' && typeof value === 'string') {
                                    return option === value;
                                }
                                if (typeof option === 'string' || typeof value === 'string') {
                                    return false;
                                }
                                return option.value === value.value;
                            }, getOptionLabel: (option) => {
                                if (typeof option === 'string')
                                    return option;
                                return option.label || '';
                            }, noOptionsText: noOptionsText, renderInput: (params) => (_jsx(TextField, { ...params, label: label, variant: "filled", required: required, disabled: disabled, placeholder: placeholder, InputProps: {
                                    ...params.InputProps,
                                    endAdornment: (_jsxs(_Fragment, { children: [loading ? _jsx(CircularProgress, { size: 20 }) : null, params.InputProps.endAdornment] })),
                                }, slotProps: {
                                    inputLabel: {
                                        shrink: true,
                                    },
                                }, sx: {
                                    borderColor: disabled
                                        ? '#BEBFC1'
                                        : hasError()
                                            ? '#C6080A'
                                            : active
                                                ? '#1C83F4'
                                                : '#BEBFC1',
                                    '.MuiInputLabel-root': {
                                        color: disabled
                                            ? '#BEBFC1'
                                            : hasError()
                                                ? '#C6080A'
                                                : active
                                                    ? '#1C83F4'
                                                    : '#000000',
                                    },
                                    '.MuiInputBase-root': {
                                        minHeight: '48px',
                                        height: multiple ? 'auto' : '48px',
                                    },
                                    '& .MuiInputBase-input': {
                                        paddingTop: multiple ? '8px' : '16px',
                                    },
                                } })) }) }), title && !hasError() && (_jsx("div", { className: "validation-message", children: title })), hasError() && (_jsx("div", { className: "validation-message error", children: createdForm.formState.errors[attr]?.label?.message }))] })) }) }));
}
