import React, { useEffect, useState } from 'react';
import { isFunction } from 'lodash';
import Dropdown, { DropdownOption, DropdownOptionFormatContext, InputChangeCallback } from 'src/components/dropdown';
import { SearchableDropdownProps } from './types';
import { getSelectedOption, useDebounceCallback } from './utils';

export const CLASSNAME = 'SearchableDropdown';

function SearchableDropdown<T extends object = object>({
    name,
    placeholder,
    disabled,
    clearable = true,
    debounceTimeout,
    options,
    selectedOption,
    onInputChange,
    onChange,
    formatOptionLabel,
    loading
}: SearchableDropdownProps<T>) {
    const [term, setTerm] = useState<string>();
    const handleInputChange = useDebounceCallback<InputChangeCallback>((searchTerm: string, { action }) => {
        setTerm(searchTerm);
        if (action !== 'input-blur')
            onInputChange?.(searchTerm);
    }, debounceTimeout);

    useEffect(() => () => handleInputChange.cancel(), [handleInputChange]);

    const handleFormatOptionLabel = (
        option: DropdownOption<T>,
        context: DropdownOptionFormatContext
    ) => {
        if (!option)
            return null;
        const { label } = option;

        if (formatOptionLabel)
            return (
                <div className="dropdownOption">
                    {formatOptionLabel(option, context)}
                </div>
            );

        return (
            <div className="dropdownOption">
                {label}
            </div>
        );
    };

    const selectedValue = getSelectedOption(options, selectedOption);
    const isClearable = isFunction(clearable) ? clearable(selectedValue) : clearable;

    return (
        <Dropdown<T>
            name={name}
            className={CLASSNAME}
            onChange={onChange}
            onInputChange={handleInputChange}
            options={options}
            isPlainValue={false}
            value={selectedValue}
            placeholder={placeholder}
            enabled={!disabled}
            formatOptionLabel={handleFormatOptionLabel}
            clearable={isClearable}
            loading={loading && !!term}
        />
    );
}

export default SearchableDropdown;
