'use client';
import { useEffect, useState, } from 'react';
import { FiArrowRight } from 'react-icons/fi';
import { MdClose } from 'react-icons/md';
import { Each, Show } from '../../00-base';
import { Button, Checkbox, Input, List, MultiSelect, Paragraph, Radio, Select, } from '../../01-atoms';
import { Autocomplete } from '../Autocomplete';
/**
 * Filter component for managing a set of filters with various input types.
 *
 * @component
 * @example
 * <Filter
 *   filtersEnabledText="Filters Enabled"
 *   resetButton={{ text: "Reset", callback: () => console.log("Reset") }}
 *   submitButton={{ text: "Submit", callback: (data) => console.log(data) }}
 *   inputs={{
 *     filter1: {
 *       title: "Filter 1",
 *       config: [{ type: "text", label: "Text Input" }]
 *     },
 *     filter2: {
 *       title: "Filter 2",
 *       config: [
 *         { type: "select", label: "Select Input", options: { option1: "Option 1", option2: "Option 2" } }
 *       ]
 *     }
 *   }}
 * />
 *
 * @param {Object} props - The properties of the Filter component.
 * @param {string} props.filtersEnabledText - Text displayed when filters are enabled.
 * @param {Object} props.resetButton - Configuration for the reset button.
 * @param {string} props.resetButton.text - Text displayed on the reset button.
 * @param {Function} props.resetButton.callback - Callback function triggered on reset.
 * @param {Object} props.submitButton - Configuration for the submit button.
 * @param {string} props.submitButton.text - Text displayed on the submit button.
 * @param {Function} props.submitButton.callback - Callback function triggered on submit.
 * @param {Object} props.inputs - Configuration object for the filter inputs.
 * @param {Object} props.inputs.title - The title of each filter group.
 * @param {Array<Object>} props.inputs.config - Configuration for each input field.
 * @param {string} [props.inputs.config.label] - Label for the input field.
 * @param {string} [props.inputs.config.type] - The type of input field (text, select, radio, multiselect).
 * @param {Object|Array} [props.inputs.config.options] - Options for select, radio, or multiselect fields.
 * @param {string} [props.inputs.config.placeholder] - Placeholder text for the input field.
 * @returns {ReactNode} The rendered Filter component.
 */
export function Filter({ filtersEnabledText, submitButton, resetButton, inputs, getValuesFilter, }) {
    const inputArr = Object.entries(inputs);
    const [filters, setFilters] = useState(inputArr.reduce((previousValue, [name, { config }]) => {
        if (!config.length) {
            return previousValue;
        }
        if (config.length === 1) {
            const { value } = config[0];
            if (value) {
                previousValue[`${name}`] = value;
            }
            return previousValue;
        }
        if (config.length > 1) {
            config.map(({ value }, index) => {
                if (value) {
                    previousValue[`${name}__${index}`] = value;
                }
            });
            return previousValue;
        }
        return previousValue;
    }, {}));
    const [autocompleteOptions, setAutocompleteOptions] = useState({});
    const handlerChange = (name, value) => {
        setFilters((prevValues) => {
            if (!value || (Array.isArray(value) && !value.length)) {
                delete prevValues[name];
                clearAutocompleteOptions(name);
                return { ...prevValues };
            }
            return { ...prevValues, [name]: value };
        });
    };
    const handlerRemoveFilter = (name) => {
        setFilters((prevValues) => {
            delete prevValues[name];
            const newValues = { ...prevValues };
            clearAutocompleteOptions(name);
            setTimeout(() => {
                submitButton.callback(newValues);
            }, 50);
            return newValues;
        });
    };
    const handlerSubmit = (event) => {
        event.preventDefault();
        submitButton.callback(filters);
    };
    const handlerReset = () => {
        setFilters({});
        setAutocompleteOptions({});
        resetButton.callback();
    };
    const clearAutocompleteOptions = (key) => {
        setAutocompleteOptions((prev) => {
            if (!(key in prev))
                return prev;
            const next = { ...prev };
            delete next[key];
            return next;
        });
    };
    useEffect(() => {
        if (filters && getValuesFilter) {
            getValuesFilter(filters);
        }
    }, [JSON.stringify(filters)]);
    return (<>
      <Show>
        <Show.When isTrue={Boolean(Object.values(filters).filter((value) => value).length)}>
          <div className="border-gray-5 border-b px-5 py-4">
            <Paragraph size="subtitle-1" className="mb-4 flex items-center justify-between gap-4">
              <span>{filtersEnabledText}</span>
              <button type="reset" onClick={handlerReset} className="border-b border-b-transparent transition hover:border-b-current">
                {resetButton.text} <MdClose className="inline h-4 w-4"/>
              </button>
            </Paragraph>
            <List orientation="horizontal" className="flex-wrap gap-2">
              <Each of={Object.entries(filters)} render={([key]) => {
            const [name, index] = key.split('__');
            const currentConfig = inputs[name].config[Number(index) || 0];
            if (!currentConfig) {
                return null;
            }
            const { label, type, options } = currentConfig;
            let labelValue;
            if (type === 'autocomplete') {
                const allOptions = autocompleteOptions[key] || options;
                labelValue =
                    allOptions?.find((o) => String(o.value) === filters[key])
                        ?.label || filters[key];
            }
            else if (Array.isArray(options)) {
                labelValue = filters[key]
                    .map((option) => option.label)
                    .join(', ');
            }
            else if (type === 'select' || type === 'radio') {
                labelValue =
                    (options && options[filters[key]]) || '';
            }
            else {
                labelValue = filters[key];
            }
            return (<li key={label}>
                      <div className="bg-gray-5 inline-flex items-center rounded-full px-4 py-2">
                        <Paragraph size="chips">
                          <Show>
                            <Show.When isTrue={type === 'checkbox'}>
                              {inputs[name].title}: {label}
                            </Show.When>
                            <Show.Else>
                              {label}: {labelValue}
                            </Show.Else>
                          </Show>
                        </Paragraph>
                        <MdClose className="bg-error ml-1.5 inline-block h-4 w-4 cursor-pointer rounded-full p-0.5 text-white" onClick={() => handlerRemoveFilter(key)}/>
                      </div>
                    </li>);
        }}/>
            </List>
          </div>
        </Show.When>
      </Show>
      <form onSubmit={handlerSubmit}>
        <Each of={inputArr} render={([name, { title, config }]) => {
            if (!config.length) {
                return null;
            }
            return (<div key={title} className="border-gray-5 border-b px-5 py-4">
                <Paragraph size="subtitle-1" className="mb-4">
                  {title}
                </Paragraph>
                <div className="grid gap-4">
                  <Each of={config} render={(inputConfig, index) => {
                    const { type, label, options, minDate, maxDate, placeholder, onDebouncedChange, debounceDelay, } = inputConfig;
                    const filterKey = config.length > 1 ? `${name}__${index}` : name;
                    return (<Show key={label}>
                          <Show.When isTrue={type === 'select'}>
                            <Select label={label} select={{
                            name: filterKey,
                            value: filters[filterKey] || '',
                            onChange: (event) => {
                                handlerChange(filterKey, event.target.value);
                            },
                        }} options={options} placeholder={placeholder}/>
                          </Show.When>
                          <Show.When isTrue={type === 'radio'}>
                            <Radio label={label} radio={{
                            name: filterKey,
                            value: filters[filterKey] || '',
                            onChange: (event) => {
                                handlerChange(filterKey, event.target.value);
                            },
                        }} options={options}/>
                          </Show.When>
                          <Show.When isTrue={type === 'checkbox'}>
                            <Checkbox label={{
                            children: label,
                            className: '-my-2',
                        }} checkbox={{
                            name: filterKey,
                            checked: filters[filterKey] || false,
                            onChange: (event) => {
                                handlerChange(filterKey, event.target.checked);
                            },
                        }}/>
                          </Show.When>
                          <Show.When isTrue={type === 'multiselect'}>
                            <MultiSelect label={label} options={options} value={filters[filterKey]} onChange={(selectedOptions) => handlerChange(filterKey, selectedOptions)}/>
                          </Show.When>
                          <Show.When isTrue={type === 'autocomplete'}>
                            <Autocomplete label={label} options={autocompleteOptions[filterKey] ||
                            options} value={filters[filterKey] || ''} onSelect={(option) => {
                            handlerChange(filterKey, String(option?.value ?? ''));
                        }} onDebouncedChange={onDebouncedChange
                            ? async (query) => {
                                const result = await onDebouncedChange(query);
                                if (Array.isArray(result)) {
                                    setAutocompleteOptions((prev) => ({
                                        ...prev,
                                        [filterKey]: result,
                                    }));
                                }
                                return result;
                            }
                            : undefined} debounceDelay={debounceDelay}/>
                          </Show.When>
                          <Show.Else>
                            <Input label={label} input={{
                            type: type,
                            name: filterKey,
                            value: filters[filterKey] || '',
                            onChange: (event) => {
                                handlerChange(filterKey, event.target.value);
                            },
                            min: minDate,
                            max: maxDate,
                        }}/>
                          </Show.Else>
                        </Show>);
                }}/>
                </div>
              </div>);
        }}/>
        <div className="flex items-center justify-center px-5 py-4">
          <Button className="z-10" iconR={<FiArrowRight />} type="submit">
            {submitButton.text}
          </Button>
        </div>
      </form>
    </>);
}
//# sourceMappingURL=Filter.jsx.map