import backgroundImage from "@Assets/images/background_refonte.svg";
import Folders from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
import Users, { IGetUsersParams } from "@Front/Api/LeCoffreApi/Notary/Users/Users";
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Form from "@Front/Components/DesignSystem/Form";
import { IOptionOld } from "@Front/Components/DesignSystem/Form/SelectFieldOld";
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
import Typography, { ETypo } from "@Front/Components/DesignSystem/Typography";
import BackArrow from "@Front/Components/Elements/BackArrow";
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
import Module from "@Front/Config/Module";
import { ValidationError } from "class-validator";
import User from "le-coffre-resources/dist/Notary/User";
import Link from "next/link";
import { useRouter } from "next/router";
import { useCallback, useEffect, useState } from "react";

import classes from "./classes.module.scss";

enum ERadioBoxValue {
	ALL = "all",
	SELECTION = "selection",
}

export default function UpdateFolderCollaborators() {
	const router = useRouter();
	let { folderUid } = router.query;

	const [availableCollaborators, setAvailableCollaborators] = useState<User[]>([]);
	const [selectedCollaborators, setSelectedCollaborators] = useState<readonly IOptionOld[]>([]);
	const [defaultCheckedAllOffice, setDefaultCheckedAllOffice] = useState<boolean>(false);
	const [selectedOption, setSelectedOption] = useState<ERadioBoxValue>(ERadioBoxValue.SELECTION);
	const [loading, setLoading] = useState<boolean>(true);
	const [validationError, setValidationError] = useState<ValidationError[]>([]);

	const onFormSubmit = useCallback(
		async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
			if (!folderUid || typeof folderUid !== "string") return;
			try {
				let collaboratorsUid: User[] = availableCollaborators;
				if (selectedOption === ERadioBoxValue.SELECTION) {
					collaboratorsUid = selectedCollaborators.map((collaborator) =>
						User.hydrate<User>({ uid: collaborator.value as string }),
					);
				}
				await Folders.getInstance().put(folderUid, { stakeholders: collaboratorsUid });
				router.push(
					Module.getInstance().get().modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", folderUid),
				);
			} catch (error) {
				if (!Array.isArray(error)) return;
				setValidationError(error as ValidationError[]);
			}
		},
		[availableCollaborators, folderUid, router, selectedCollaborators, selectedOption],
	);

	const onSelectedOptionAllOffice = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
		if (event.target.value !== ERadioBoxValue.ALL) return;
		setSelectedOption(ERadioBoxValue.ALL);
	}, []);

	const onChangeSelectedCollaborators = useCallback((selectedCollaborators: readonly IOptionOld[]) => {
		setSelectedCollaborators(selectedCollaborators);
	}, []);

	const onSelectedOptionSpecific = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
		if (event.target.value !== ERadioBoxValue.SELECTION) return;
		setSelectedOption(ERadioBoxValue.SELECTION);
	}, []);

	const getFolderInfos = useCallback(async () => {
		if (!folderUid || typeof folderUid !== "string") return;
		const query = {
			q: {
				office: true,
				stakeholders: {
					include: {
						contact: true,
					},
				},
			},
		};

		let folder = null;
		try {
			folder = await Folders.getInstance().getByUid(folderUid, query);
			const preSelectedCollaborators: IOptionOld[] = folder.stakeholders!.map((collaborator) => {
				return {
					label: collaborator.contact?.first_name + " " + collaborator.contact?.last_name,
					value: collaborator.uid,
				};
			});

			// no need to pass query 'where' param here, default query for notaries include only users which are in the same office as the caller
			const userQuery: IGetUsersParams = {
				include: {
					contact: {
						select: {
							first_name: true,
							last_name: true,
						},
					},
				},
			};

			const availableCollaborators = await Users.getInstance().get(userQuery);

			setLoading(false);
			setAvailableCollaborators(availableCollaborators);
			setSelectedCollaborators(preSelectedCollaborators);
			setDefaultCheckedAllOffice(preSelectedCollaborators.length === availableCollaborators.length);
			setSelectedOption(
				preSelectedCollaborators.length === availableCollaborators.length ? ERadioBoxValue.ALL : ERadioBoxValue.SELECTION,
			);
		} catch (error) {
			router.push(Module.getInstance().get().modules.pages["404"].props.path);
			return;
		}
	}, [folderUid, router]);

	useEffect(() => {
		getFolderInfos();
	}, [getFolderInfos]);

	const foldersInformationPath = Module.getInstance().get().modules.pages.Folder.pages.FolderInformation.props.path;
	const backwardPath = foldersInformationPath.replace("[folderUid]", folderUid as string);
	const selectOptions: IOptionOld[] = availableCollaborators.map((collaborator) => {
		return {
			label: collaborator.contact?.first_name + " " + collaborator.contact?.last_name,
			value: collaborator.uid,
		};
	});

	return (
		<DefaultDoubleSidePage title={"Dossier"} image={backgroundImage} type="background" showHeader={true}>
			<div className={classes["root"]}>
				<div className={classes["back-arrow"]}>
					<BackArrow url={backwardPath} />
				</div>
				<Typography typo={ETypo.TITLE_H1}>Modifier les collaborateurs</Typography>

				{!loading && (
					<Form className={classes["form"]} onSubmit={onFormSubmit}>
						<div className={classes["content"]}>
							<RadioBox
								name="office"
								value={ERadioBoxValue.ALL}
								defaultChecked={defaultCheckedAllOffice}
								onChange={onSelectedOptionAllOffice}>
								Tout l'office
							</RadioBox>
							<RadioBox
								name="office"
								value={ERadioBoxValue.SELECTION}
								defaultChecked={!defaultCheckedAllOffice}
								onChange={onSelectedOptionSpecific}>
								Sélectionner des collaborateurs
							</RadioBox>
						</div>

						{selectedOption === ERadioBoxValue.SELECTION && (
							<div className={classes["sub-content"]}>
								<MultiSelect
									onChange={onChangeSelectedCollaborators}
									options={selectOptions}
									placeholder="Collaborateurs"
									defaultValue={selectedCollaborators}
									validationError={validationError?.find((error) => error.property === "stakeholders")}
								/>
							</div>
						)}

						<div className={classes["button-container"]}>
							<Link href={backwardPath} className={classes["cancel-button"]}>
								<Button variant={EButtonVariant.PRIMARY} styletype={EButtonstyletype.OUTLINED}>
									Annuler
								</Button>
							</Link>
							<Button type="submit">Enregistrer</Button>
						</div>
					</Form>
				)}
			</div>
		</DefaultDoubleSidePage>
	);
}
