'use client';
import clsx from 'clsx';
import { useEffect, useRef, useState, } from 'react';
import { FaSortDown } from 'react-icons/fa';
import { IoIosSearch, IoMdCloseCircleOutline } from 'react-icons/io';
import { generateUniqueId } from '../../../utils';
import { Each, Show } from '../../00-base';
import { Checkbox } from '../Checkbox';
import { generateBorder } from '../Input/utils/border';
import { RenderErrorOrHelperText } from '../Input/utils/RenderErrorOrHelperText';
/**
 * MultiSelect component for rendering a multi-select dropdown.
 *
 * @component
 * @example
 * // Example usage of MultiSelect component
 * const options = [
 *   { value: 1, label: 'Option 1' },
 *   { value: 2, label: 'Option 2' },
 * ];
 * const handleChange = (selectedOptions) => console.log(selectedOptions);
 *
 * <MultiSelect
 *   label="Select Options"
 *   options={options}
 *   value={[options[0]]}
 *   onChange={handleChange}
 *   disabled={false}
 *   helperText="Select multiple options"
 *   error=""
 * />
 *
 * @param {MultiSelectProps} props - The properties of the MultiSelect component.
 * @param {string} props.label - The label for the multi-select input.
 * @param {OptionType[]} props.options - Array of options to be displayed in the dropdown.
 * @param {OptionType[]} [props.value] - Array of selected options.
 * @param {function} [props.onChange] - Callback function to handle change in selected options.
 * @param {boolean} [props.disabled] - Boolean to disable the multi-select input.
 * @param {string} [props.helperText] - Helper text to be displayed below the input.
 * @param {string} [props.error] - Error message to be displayed below the input.
 * @param {HTMLAttributes<HTMLDivElement>} [props.restProps] - Additional HTML attributes for the container div.
 *
 * @returns {ReactNode} The rendered MultiSelect component.
 */
export function MultiSelect({ options, value = [], onChange, label, disabled, helperText, error, ...restProps }) {
    const [id, setId] = useState('');
    const [filteredOptions, setFilteredOptions] = useState([]);
    const [selectedOptions, setSelectedOptions] = useState(value);
    const [isOpen, setIsOpen] = useState(false);
    const [query, setQuery] = useState('');
    const [itemsSelected, setItemsSelected] = useState(0);
    const containerRef = useRef(null);
    const inputClasses = clsx('peer disabled:text-gray-3 pointer-events-none h-full w-full rounded-full bg-transparent px-5 text-sm font-normal text-black outline-0 transition-all select-none focus:text-black');
    const { labelProps, legendClasses, fieldsetClasses } = generateBorder(error);
    const handleToggleDropdown = () => {
        if (disabled) {
            return;
        }
        setIsOpen(!isOpen);
    };
    const handleOptionClick = (option) => {
        const isSelected = selectedOptions.some((selectedOption) => selectedOption.value === option.value);
        const newSelectedOptions = isSelected
            ? selectedOptions.filter((selectedOption) => selectedOption.value !== option.value)
            : [...selectedOptions, option];
        setSelectedOptions(newSelectedOptions);
        onChange && onChange(newSelectedOptions);
    };
    const handleQueryChange = (e) => {
        const newQuery = e.target.value;
        setQuery(newQuery);
        const dataFiltered = options.filter((option) => option.label.toLowerCase().includes(newQuery.toLowerCase()));
        setFilteredOptions(dataFiltered);
    };
    const handleOutsideClick = (event) => {
        if (containerRef.current &&
            !containerRef.current.contains(event.target)) {
            setIsOpen(false);
        }
    };
    const handleRemoveItems = () => {
        setSelectedOptions([]);
        setFilteredOptions(options);
        setQuery('');
    };
    if (id) {
        labelProps.htmlFor = id;
    }
    useEffect(() => {
        setFilteredOptions(options);
    }, [options]);
    useEffect(() => {
        setSelectedOptions(value);
    }, [value?.length]);
    useEffect(() => {
        setItemsSelected(selectedOptions?.length);
    }, [selectedOptions]);
    useEffect(() => {
        document.addEventListener('mousedown', handleOutsideClick);
        setId(generateUniqueId());
        return () => {
            document.removeEventListener('mousedown', handleOutsideClick);
        };
    }, []);
    return (<div className={clsx('relative w-full', restProps.className)} ref={containerRef}>
      <div className={clsx('relative h-9 rounded-full', disabled ? 'pointer-events-none select-none' : 'cursor-pointer')} onClick={handleToggleDropdown}>
        <input id={id} placeholder=" " defaultValue={itemsSelected ? `${itemsSelected} seleccionado(s)` : ''} className={inputClasses} disabled={disabled}/>
        <label {...labelProps}>{label}</label>
        <FaSortDown className="absolute top-2 right-4"/>
        <fieldset className={fieldsetClasses}>
          <legend className={legendClasses}>{label}</legend>
        </fieldset>
      </div>
      <RenderErrorOrHelperText disabled={disabled} helperText={helperText} error={error} className="pl-6"/>
      {!!isOpen && (<div className="border-gray-5 absolute top-10 z-20 w-full rounded-lg border bg-white px-4 py-2 shadow-lg">
          <div className="mb-2 flex items-center gap-x-2">
            <div className="relative flex w-full">
              <input type="text" className="peer flex-1 rounded-full border px-3 py-1.5 outline-hidden" value={query} onChange={handleQueryChange} onFocus={() => setIsOpen(true)}/>
              <IoIosSearch size={18} className="absolute top-2 right-2"/>
            </div>
            <button type="button" onClick={handleRemoveItems} className="disabled:text-gray-3 size-7 rounded-full p-1 text-xl transition not-disabled:hover:bg-black not-disabled:hover:text-white">
              <IoMdCloseCircleOutline />
            </button>
          </div>
          <ul className="flex max-h-64 flex-col gap-y-1 overflow-y-auto bg-white">
            <Show>
              <Show.When isTrue={Boolean(filteredOptions.length)}>
                <Each of={filteredOptions} render={(option) => (<li className="flex items-center gap-2" key={option.value}>
                      <Checkbox checkbox={{
                    checked: selectedOptions.some((selectedOption) => selectedOption.value === option.value),
                    onChange: () => handleOptionClick(option),
                }} label={{
                    children: option.label,
                    className: 'flex-auto',
                }}/>
                    </li>)}/>
              </Show.When>
              <Show.Else>
                <span className="p-2">Opción no encontrada</span>
              </Show.Else>
            </Show>
          </ul>
        </div>)}
    </div>);
}
//# sourceMappingURL=MultiSelect.jsx.map