import backgroundImage from "@Assets/images/background_refonte.svg";
import Button from "@Front/Components/DesignSystem/Button";
import { IOption } from "@Front/Components/DesignSystem/Dropdown/DropdownMenu/DropdownOption";
import Form from "@Front/Components/DesignSystem/Form";
import AutocompleteMultiSelectField from "@Front/Components/DesignSystem/Form/AutocompleteMultiSelectField";
import SelectField from "@Front/Components/DesignSystem/Form/SelectField";
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
import TextField from "@Front/Components/DesignSystem/Form/TextField";
import RadioBox from "@Front/Components/DesignSystem/RadioBox";
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
import { ToasterService } from "@Front/Components/DesignSystem/Toaster";
import BackArrow from "@Front/Components/Elements/BackArrow";
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
import { ValidationError } from "class-validator/types/validation/ValidationError";
import { Deed, Office, OfficeFolder } from "le-coffre-resources/dist/Notary";
import User from "le-coffre-resources/dist/Notary";
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
import { DeedType } from "le-coffre-resources/dist/Notary";
import { useRouter } from "next/router";
import React, { useCallback, useEffect, useState } from "react";
import classes from "./classes.module.scss";

import UserStore from "@Front/Stores/UserStore";

import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
import DeedTypeService from "src/common/Api/LeCoffreApi/sdk/DeedTypeService";
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";
import CollaboratorService from "src/common/Api/LeCoffreApi/sdk/CollaboratorService";

export default function CreateFolder(): JSX.Element {
	/**
	 * State
	 */
	const [folderAccessType, setFolderAccessType] = useState<"whole_office" | "select_collaborators">("select_collaborators");
	const [availableDeedTypes, setAvailableDeedTypes] = useState<DeedType[]>([]);
	const [availableCollaborators, setAvailableCollaborators] = useState<User[]>([]);
	const [validationError, setValidationError] = useState<ValidationError[]>([]);
	const [selectedCollaborators, setSelectedCollaborators] = useState<User[]>([]);

	/**
	 * Hooks call
	 */
	const router = useRouter();

	/**
	 * Callbacks
	 */

	const onFormSubmit = async (
		e: React.FormEvent<HTMLFormElement> | null,
		values: {
			[key: string]: any;
		},
	) => {
		const user: any = UserStore.instance.getUser();
		const officeId: string = user.office.uid;

		const officeFolderModel = OfficeFolder.hydrate<OfficeFolder>({
			folder_number: values["folder_number"],
			name: values["name"],
			description: values["description"],
			deed: Deed.hydrate<Deed>({
				deed_type: DeedType.hydrate<DeedType>({
					uid: values["deed"],
				}),
			}),
			office: Office.hydrate<Office>({
				uid: officeId,
			}),
			customers: [],
			stakeholders: folderAccessType === "whole_office" ? availableCollaborators : selectedCollaborators,
		});

		try {
			await officeFolderModel.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: true });
		} catch (validationErrors) {
			setValidationError(validationErrors as ValidationError[]);
			return;
		}

		try {
			const folderData: any = {
				folder_number: values["folder_number"],
				name: values["name"],
				deed: {
					deed_type: {
						uid: values["deed"],
					}
				},
				description: values["description"],
				office: {
					uid: officeId
				},
				customers: [],
				documents: [],
				notes: [],
				stakeholders: (folderAccessType === "whole_office" ? availableCollaborators : selectedCollaborators).map((collaborator: any) => ({ uid: collaborator.uid })),
				status: EFolderStatus.LIVE
			};

			LoaderService.getInstance().show();
			FolderService.createFolder(folderData, [], []).then((processCreated: any) => {
				ToasterService.getInstance().success({
					title: "Succès !",
					description: "Dossier créé avec succès"
				});
				const folderUid: string = processCreated.processData.uid;
				router.push(`/folders/${folderUid}`);
				LoaderService.getInstance().hide();
			});
		} catch (backError) {
			if (!Array.isArray(backError)) return;
			setValidationError(backError as ValidationError[]);
			return;
		}
	};

	const radioOnChange = (e: React.ChangeEvent<HTMLInputElement>) =>
		setFolderAccessType(e.target.value as "whole_office" | "select_collaborators");

	const onSelectedCollaboratorsChange = useCallback(
		(options: IOption[] | null) => {
			if (!options) return;
			const collaborators = availableCollaborators.filter((collaborator) => options.find((option) => option.id === collaborator.uid));
			setSelectedCollaborators(collaborators);
		},
		[availableCollaborators],
	);

	/**
	 * UseEffect
	 */
	useEffect(() => {
		DeedTypeService.getDeedTypes().then((processes: any[]) => {
			if (processes.length > 0) {
				const deedTypes: any[] = processes.map((process: any) => process.processData);
				setAvailableDeedTypes(deedTypes);
			}
		});

		CollaboratorService.getCollaborators().then((processes: any[]) => {
			if (processes.length > 0) {
				const collaborators: any[] = processes.map((process: any) => process.processData);
				setAvailableCollaborators(collaborators);

				const user: any = UserStore.instance.getUser();
				const currentUser: any = collaborators.find((collaborator: any) => collaborator.uid === user.uid);
				if (currentUser) {
					setSelectedCollaborators([currentUser]);
				}
			}
		});
	}, []);

	/**
	 * Renderer
	 */
	return (
		<DefaultDoubleSidePage title={"Dossier"} image={backgroundImage} type="background" showHeader={true}>
			<div className={classes["root"]}>
				<BackArrow />
				<div className={classes["header"]}>
					<Typography typo={ETypo.DISPLAY_LARGE} color={ETypoColor.COLOR_GENERIC_BLACK} className={classes["title"]}>
						Créer un dossier
					</Typography>
					<Typography typo={ETypo.TITLE_H5} color={ETypoColor.COLOR_PRIMARY_500} className={classes["subtitle"]}>
						Informations du dossier
					</Typography>
				</div>

				<Form onSubmit={onFormSubmit} className={classes["form"]}>
					<TextField
						name="folder_number"
						label="Numéro de dossier"
						placeholder="Entrer le numéro de dossier"
						validationError={validationError.find((error) => error.property === "folder_number")}
					/>
					<TextField
						name="name"
						label="Intitulé"
						placeholder="Entrer l'intitulé du dossier"
						validationError={validationError.find((error) => error.property === "name")}
					/>
					<SelectField
						name="deed"
						label="Type d'acte"
						placeholder="Sélectionner un type d'acte"
						options={
							availableDeedTypes.map((deedType) => ({
								id: deedType.uid,
								label: deedType.name,
							})) as IOption[]
						}
						validationError={validationError.find((error) => error.property === "deed")}
					/>

					<TextAreaField
						name="description"
						label="Note de dossier"
						placeholder="Renseigner une note"
						validationError={validationError.find((error) => error.property === "description")}
						required={false}
					/>

					<div className={classes["bottom-container"]}>
						<Typography typo={ETypo.TITLE_H5} color={ETypoColor.COLOR_PRIMARY_500}>
							Donner l'accès au dossier
						</Typography>
						<div className={classes["radio-container"]}>
							<RadioBox name="file_access" onChange={radioOnChange} value="whole_office" label="Sélectionner tout l'office" />
							<RadioBox
								name="file_access"
								defaultChecked
								onChange={radioOnChange}
								value="select_collaborators"
								label="Sélectionner certains collaborateurs"
							/>
						</div>
						{folderAccessType === "select_collaborators" && (
							<div className={classes["collaborators-container"]}>
								<AutocompleteMultiSelectField
									label="Sélectionner les collaborateurs"
									options={availableCollaborators.map((collaborator) => ({
										label: collaborator.contact?.last_name.concat(" ", collaborator.contact.first_name) ?? "",
										id: collaborator.uid ?? "",
									}))}
									selectedOptions={selectedCollaborators.map((collaborator) => ({
										label: collaborator.contact?.last_name.concat(" ", collaborator.contact.first_name) ?? "",
										id: collaborator.uid ?? "",
									}))}
									onSelectionChange={onSelectedCollaboratorsChange}
									validationError={validationError.find((error) => error.property === "stakeholders")}
								/>
							</div>
						)}
						<div className={classes["buttons-container"]}>
							<Button type="submit">Créer le dossier</Button>
						</div>
					</div>
				</Form>
			</div>
		</DefaultDoubleSidePage>
	);
}
