import { memo, useCallback, useRef, useState } from "react";

import AsyncCheckGroup from "@ax/components/Fields/AsyncCheckGroup";
import CheckGroup from "@ax/components/Fields/CheckGroup";
import { useHandleClickOutside } from "@ax/hooks";
import type { ILanguage, ISite } from "@ax/types";

import * as S from "./style";

const MultiCheckSelect = (props: IMultiCheckSelectProps) => {
	const {
		placeholder,
		source,
		value,
		onChange,
		site,
		className,
		mandatory,
		options,
		selectAllOption,
		floating,
		disabled,
		contentType = "data",
		languages,
		contentLanguages,
		allOption,
	} = props;

	const [isOpen, setIsOpen] = useState(false);
	const wrapperRef = useRef<HTMLDivElement | null>(null);

	const handleClick = useCallback(() => setIsOpen((prev) => !prev), []);

	const handleClickOutside = useCallback((e: MouseEvent) => {
		if (wrapperRef.current?.contains(e.target as HTMLElement)) {
			return;
		}

		setIsOpen(false);
	}, []);

	useHandleClickOutside(isOpen, handleClickOutside);

	const Asterisk = useCallback(() => (mandatory ? <S.Asterisk>*</S.Asterisk> : null), [mandatory]);

	return (
		<S.Wrapper ref={wrapperRef} className={className} data-testid="multi-check-select-wrapper">
			<S.Field isOpen={isOpen} onClick={handleClick} disabled={disabled} data-testid="field">
				{placeholder} <Asterisk />
			</S.Field>
			{isOpen && (
				<S.DropDown floating={floating} isOpen={isOpen}>
					{options && (
						<CheckGroup
							options={options}
							value={value}
							onChange={onChange}
							selectAllOption={selectAllOption}
							disabled={disabled}
						/>
					)}
					{source && !options && (
						<AsyncCheckGroup
							source={source}
							site={site}
							value={value}
							onChange={onChange}
							fullHeight={true}
							disabled={disabled}
							contentType={contentType}
							languages={languages}
							contentLanguages={contentLanguages}
							allOption={allOption}
						/>
					)}
				</S.DropDown>
			)}
		</S.Wrapper>
	);
};

export interface IMultiCheckSelectProps {
	value: any[];
	onChange: (value: string | any[]) => void;
	site?: ISite | null;
	placeholder: string;
	source?: string;
	className?: string;
	mandatory?: boolean;
	options?: { name: string; value: string; title: string }[];
	selectAllOption?: string;
	floating?: boolean;
	disabled?: boolean;
	contentType: "data" | "formCategory";
	languages: ILanguage[];
	contentLanguages?: "current" | "all" | string[];
	allOption?: boolean;
}

export default memo(MultiCheckSelect);
