import { Autocomplete, Chip, CircularProgress, TextField } from "@mui/material";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";

import { Entity } from "@/common/models/Entity";
import { SelectFieldProps } from "@/common/models/SelectFieldProps";
import { KeyValue } from "@/models/KeyValue";

import { CardField } from "../CardField";

export function MultiSelectCardField<T extends Entity>(
	props: SelectFieldProps<T>,
) {
	const { t } = useTranslation();
	const [options, setOptions] = useState<KeyValue[]>(props.options ?? []);
	const [isLoading, setIsLoading] = useState(false);
	const values = props.formik.values;
	const loadOptions = props.loadOptions;

	useEffect(() => {
		if (loadOptions) {
			setIsLoading(true);
			loadOptions(values)
				.then((options) => {
					setOptions(options);
				})
				.finally(() => {
					setIsLoading(false);
				});
		}
	}, [values, loadOptions]);

	useEffect(() => {
		if (props.options) {
			setOptions(props.options);
		}
	}, [props.options]);

	if (isLoading) {
		return <CircularProgress />;
	}

	const getFieldTitle = (field: CardField<T>) => {
		const translatedTitle = t(`${field.title}`);
		if (field.required) {
			return `${translatedTitle} *`;
		}

		return translatedTitle;
	};

	return (
		<Autocomplete
			multiple
			options={options}
			filterSelectedOptions
			readOnly={props.readOnly}
			getOptionLabel={(option) => {
				return option.value;
			}}
			renderInput={(params) => (
				<TextField
					{...params}
					variant="outlined"
					label={getFieldTitle(props)}
					placeholder={t("Choose...")}
				/>
			)}
			renderTags={(value, getTagProps) => {
				return value.map((option, index) => {
					const tagProps = getTagProps({ index });
					return (
						<Chip
							{...tagProps}
							key={tagProps.key}
							label={option.value}
							variant="outlined"
						/>
					);
				});
			}}
			value={options.filter((x) =>
				props.formik.values[props.name]?.includes(x.key),
			)}
			onChange={(_, changedValue) =>
				props.formik.setFieldValue(
					props.name.toString(),
					changedValue.map((x) => x.key),
				)
			}
			isOptionEqualToValue={(option, value) => {
				return option.key === value.key;
			}}
			noOptionsText={t("Has no options")}
		/>
	);
}
