import useOpenable from "@Front/Hooks/useOpenable";
import { useCallback, useEffect, useState } from "react";

import { getLabel } from "../Dropdown";
import DropdownMenu from "../Dropdown/DropdownMenu";
import { IOption } from "../Dropdown/DropdownMenu/DropdownOption";
import Typography, { ETypo, ETypoColor } from "../Typography";
import ChipContainer from "./ChipContainer";
import classes from "./classes.module.scss";

type IProps = {
	options: IOption[];
	placeholder?: string;
	disabled?: boolean;
	label?: string;
	onSelectionChange?: (options: IOption[] | null) => void;
	selectedOptions?: IOption[] | null;
};

export default function AutocompleteMultiSelect(props: IProps) {
	const { onSelectionChange, options, placeholder, disabled, label, selectedOptions: selectedOptionsProps } = props;
	const [selectedOptions, setSelectedOptions] = useState<IOption[] | null>(selectedOptionsProps ?? null);
	const [searchValue, setSearchValue] = useState("");
	const [filteredOptions, setFilteredOptions] = useState<IOption[]>(options);
	const openable = useOpenable({ defaultOpen: false });

	useEffect(() => {
		if (searchValue) {
			const filteredOptions = options.filter((option) => getLabel(option)?.toLowerCase().includes(searchValue.toLowerCase()));
			if (filteredOptions.length === 0)
				return setFilteredOptions([{ id: "no-results", label: "Aucun résulats", notSelectable: true }]);
			return setFilteredOptions(filteredOptions);
		}
		return setFilteredOptions(options);
	}, [searchValue, options]);

	const handleSearchChange = useCallback(
		(value: string) => {
			setSearchValue(value);
			if (value) {
				openable.open();
			} else {
				openable.close();
			}
		},
		[openable],
	);

	const handleChange = useCallback(
		(options: IOption[] | null) => {
			setSelectedOptions(options);
			onSelectionChange?.(options);
		},
		[onSelectionChange],
	);

	useEffect(() => {
		setSelectedOptions(selectedOptionsProps ?? null);
	}, [selectedOptionsProps]);

	const handleSelectOption = useCallback(
		(_newOption: IOption, options: IOption[]) => {
			handleChange(options);
			setSearchValue("");
			openable.close();
		},
		[handleChange, openable],
	);

	return (
		<DropdownMenu
			options={filteredOptions}
			openable={openable}
			onSelect={handleSelectOption}
			selectedOptions={selectedOptions ? selectedOptions : []}>
			<div className={classes["root"]}>
				{label && (
					<Typography className={classes["label"]} typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.CONTRAST_DEFAULT}>
						{label}
					</Typography>
				)}
			</div>
			<ChipContainer
				placeholder={placeholder}
				disabled={disabled}
				onChange={handleSearchChange}
				value={searchValue}
				onClear={() => handleChange(null)}
				onFocus={openable.open}
				selectedOptions={selectedOptions ?? []}
				onSelectedOptionsChange={handleChange}
			/>
		</DropdownMenu>
	);
}
