import WarningIcon from "@Assets/images/warning.png";
//import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
import Roles from "@Front/Api/LeCoffreApi/Admin/Roles/Roles";
import LiveVotes from "@Front/Api/LeCoffreApi/SuperAdmin/LiveVotes/LiveVotes";
import Users from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Confirm from "@Front/Components/DesignSystem/OldModal/Confirm";
import Switch from "@Front/Components/DesignSystem/Switch";
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
import DefaultUserDashboard from "@Front/Components/LayoutTemplates/DefaultUserDashboard";
import JwtService from "@Front/Services/JwtService/JwtService";
import Toasts from "@Front/Stores/Toasts";
import User, { Appointment, Vote } from "le-coffre-resources/dist/SuperAdmin";
import { EAppointmentStatus, EVote } from "le-coffre-resources/dist/SuperAdmin/Appointment";
import Image from "next/image";
import { useRouter } from "next/router";
import { useCallback, useEffect, useState } from "react";

import classes from "./classes.module.scss";
import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
import Loader from "@Front/Components/DesignSystem/Loader";

type IProps = {};
export default function UserInformations(props: IProps) {
	const router = useRouter();
	let { userUid } = router.query;

	const [userSelected, setUserSelected] = useState<User | null>(null);

	const [isSuperAdminModalOpened, setIsSuperAdminModalOpened] = useState<boolean>(false);
	const [superAdminModalType, setSuperAdminModalType] = useState<"add" | "remove">("add");
	const [adminModalType, setAdminModalType] = useState<"add" | "remove">("add");

	const [isSuperAdminChecked, setIsSuperAdminChecked] = useState<boolean>(false);
	const [isAdminChecked, setIsAdminChecked] = useState<boolean>(false);
	const [isAdminModalOpened, setIsAdminModalOpened] = useState<boolean>(false);

	const [currentAppointment, setCurrentAppointment] = useState<Appointment | null>(null);

	const [isLoading, setIsLoading] = useState<boolean>(true);
	/** When page change, get the user of the page */

	const getUser = useCallback(async () => {
		if (!userUid) return;
		setIsLoading(true);
		const user = await Users.getInstance().getByUid(userUid as string, {
			q: {
				contact: true,
				office_role: true,
				office_membership: true,
				role: true,
				appointment: {
					include: {
						votes: {
							include: {
								voter: true,
							},
						},
					},
				},
				votes: true,
			},
		});
		if (!user) return;
		const roles = await OfficeRoles.getInstance().get({
			where: {
				office: { uid: user.office_membership?.uid },
				NOT: { OR: [{ name: "super-admin" }, { name: "admin" }] },
			},
		});
		if (!roles) return;
		setIsLoading(false);
		setUserSelected(user);
	}, [userUid]);

	useEffect(() => {
		getUser();
	}, [getUser, userUid]);

	useEffect(() => {
		if (!userSelected) return;
		setCurrentAppointment(
			userSelected?.appointment?.find(
				(appointment) => appointment.status === EAppointmentStatus.OPEN && appointment.votes?.length != 0,
			) ?? null,
		);
	}, [userSelected]);

	/** Functions for the admin modal */
	const openAdminModal = () => {
		setIsAdminModalOpened(true);
	};

	const closeAdminModal = useCallback(() => {
		setIsAdminModalOpened(false);
		setIsAdminChecked(userSelected?.role?.name === "admin");
	}, [userSelected]);

	const handleAdminChanged = (checked: boolean) => {
		setIsAdminChecked(checked);
		setAdminModalType(checked ? "add" : "remove");
		openAdminModal();
	};

	const handleAdminModalAccepted = useCallback(async () => {
		if (!userSelected) return;
		if (adminModalType === "add") {
			const adminRole = await Roles.getInstance().getOne({
				where: {
					name: "admin",
				},
			});

			if (!adminRole) return;
			await Users.getInstance().put(
				userSelected?.uid as string,
				User.hydrate<User>({
					uid: userSelected?.uid as string,
					office_role: undefined,
					role: adminRole,
				}),
			);
		} else {
			const defaultRole = await Roles.getInstance().getOne({
				where: {
					name: "default",
				},
			});

			if (!defaultRole) return;
			await Users.getInstance().put(
				userSelected?.uid as string,
				User.hydrate<User>({
					uid: userSelected?.uid as string,
					office_role: undefined,
					role: defaultRole,
				}),
			);
		}
		getUser();
		setIsAdminModalOpened(false);
	}, [userSelected, adminModalType, getUser]);

	/** Functions for the super admin modal  */
	const openSuperAdminModal = () => {
		setIsSuperAdminModalOpened(true);
	};

	const closeSuperAdminModal = useCallback(() => {
		setIsSuperAdminModalOpened(false);
		setIsSuperAdminChecked(userSelected?.role?.name === "super-admin");
	}, [userSelected]);

	const handleSuperAdminChanged = (checked: boolean) => {
		setIsSuperAdminChecked(checked);
		setSuperAdminModalType(checked ? "add" : "remove");
		openSuperAdminModal();
	};

	const handleSuperAdminModalAccepted = useCallback(async () => {
		if (!userSelected) return;

		let vote = Vote.hydrate<Vote>({
			appointment: Appointment.hydrate<Appointment>({
				uid: currentAppointment?.uid ?? undefined,
				user: User.hydrate<User>({
					uid: userSelected.uid,
				}),
				choice: superAdminModalType === "add" ? EVote.NOMINATE : EVote.DISMISS,
			}),
		});

		const liveVote = await LiveVotes.getInstance().post(vote);

		if (liveVote.appointment.votes?.length === 3) {
			if (superAdminModalType === "add") {
				Toasts.getInstance().open({
					title: `Le titre de super-administrateur a été attribué à ${userSelected.contact?.first_name} ${userSelected.contact?.last_name} `,
				});
			} else {
				Toasts.getInstance().open({
					title: `Le titre de super-administrateur a été retiré à ${userSelected.contact?.first_name} ${userSelected.contact?.last_name} `,
				});
			}
		}
		await getUser();
		setIsSuperAdminModalOpened(false);
	}, [userSelected, currentAppointment, superAdminModalType, getUser]);

	/** Reset switch state when userSelect change */
	useEffect(() => {
		if (!userSelected) return;
		setIsSuperAdminChecked(userSelected.role?.name === "super-admin");
		setIsAdminChecked(userSelected.role?.name === "admin");
	}, [userSelected]);

	const userHasVoted = useCallback(() => {
		if (!currentAppointment) return false;
		const user = JwtService.getInstance().decodeJwt();
		return currentAppointment.votes?.find((vote) => vote.voter?.uid === user?.userId) !== undefined;
	}, [currentAppointment]);

	const deleteMyVote = useCallback(async () => {
		if (!currentAppointment) return;
		const user = JwtService.getInstance().decodeJwt();
		const vote = currentAppointment.votes?.find((vote) => vote.voter?.uid === user?.userId);
		if (!vote) return;
		await LiveVotes.getInstance().delete({ uid: vote.uid });
		await getUser();
	}, [currentAppointment, getUser]);

	return (
		<DefaultUserDashboard mobileBackText={"Liste des utilisateurs"}>
			{!isLoading && (
				<div className={classes["root"]}>
					<div className={classes["header"]}>
						<Typography typo={ETypo.TITLE_H1}>
							{userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name}
						</Typography>
						<Typography typo={ETypo.TITLE_H5} color={ETypoColor.COLOR_NEUTRAL_500}>
							Office {userSelected?.office_membership?.name.toLocaleUpperCase()}
						</Typography>
					</div>
					<div className={classes["user-infos"]}>
						<div className={classes["user-infos-row"]}>
							<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.COLOR_NEUTRAL_500}>
								Nom
							</Typography>
							<Typography typo={ETypo.TEXT_LG_REGULAR}>{userSelected?.contact?.first_name}</Typography>
						</div>
						<div className={classes["user-infos-row"]}>
							<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.COLOR_NEUTRAL_500}>
								Prénom
							</Typography>
							<Typography typo={ETypo.TEXT_LG_REGULAR}>{userSelected?.contact?.last_name}</Typography>
						</div>
						<div className={classes["user-infos-row"]}>
							<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.COLOR_NEUTRAL_500}>
								Numéro de téléphone
							</Typography>
							<Typography typo={ETypo.TEXT_LG_REGULAR}>{userSelected?.contact?.cell_phone_number}</Typography>
						</div>
						<div className={classes["user-infos-row"]}>
							<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.COLOR_NEUTRAL_500}>
								Email
							</Typography>
							<Typography typo={ETypo.TEXT_LG_REGULAR}>{userSelected?.contact?.email}</Typography>
						</div>
					</div>

					<div className={classes["role-container"]}>
						<div className={classes["part"]}>
							<div className={classes["first-line"]}>
								<Typography typo={ETypo.TEXT_LG_SEMIBOLD}>Rôle au sein de son office</Typography>
							</div>
							<div className={classes["second-line"]}>
								<Typography typo={ETypo.TEXT_LG_REGULAR}>
									{userSelected?.office_role ? userSelected?.office_role?.name : "Utilisateur restreint"}
								</Typography>
							</div>
						</div>
						<div className={classes["part"]}>
							<div className={classes["first-line"]}>
								<Typography typo={ETypo.TEXT_LG_SEMIBOLD}>Attribuer un titre</Typography>
							</div>
							<div className={classes["second-line"]}>
								{!isSuperAdminChecked && !currentAppointment && (
									<Switch label="Admin de son office" checked={isAdminChecked} onChange={handleAdminChanged} />
								)}

								<Switch
									label="Super-admin LEcoffre.io"
									checked={isSuperAdminChecked}
									disabled={userHasVoted()}
									onChange={handleSuperAdminChanged}
								/>
								{currentAppointment && (
									<div className={classes["votes-block"]}>
										<div className={classes["left"]}>
											<Image src={WarningIcon} alt="warning" width={28} height={28} />
										</div>
										<div className={classes["right"]}>
											<div>
												<Typography typo={ETypo.TEXT_LG_SEMIBOLD}>{currentAppointment.votes?.length}/3</Typography>
											</div>
											<div>
												<Typography typo={ETypo.TEXT_SM_REGULAR}>
													{currentAppointment.choice === EVote.NOMINATE
														? `Un ou des collaborateurs souhaitent attribuer le titre de Super Admin à ce collaborateur. Il manque ${
																3 - currentAppointment.votes?.length!
														  } vote(s) pour que le collaborateur se voit attribuer le titre.`
														: `Un ou des collaborateurs souhaitent retirer le titre de Super Admin à ce collaborateur. Il manque ${
																3 - currentAppointment.votes?.length!
														  } vote(s) pour que le collaborateur se voit retirer le titre.`}
												</Typography>
											</div>
											{userHasVoted() && (
												<div className={classes["remove-my-vote"]}>
													<Button variant={EButtonVariant.SECONDARY} onClick={deleteMyVote}>
														Retirer mon vote
													</Button>
												</div>
											)}
										</div>
									</div>
								)}
							</div>
						</div>
					</div>
					<Confirm
						isOpen={isSuperAdminModalOpened}
						onClose={closeSuperAdminModal}
						onAccept={handleSuperAdminModalAccepted}
						closeBtn
						header={`Souhaitez-vous attribuer un vote à ${
							userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name
						} pour ${superAdminModalType === "add" ? "devenir" : "retirer son rôle de"} Super Administrateur ?`}
						confirmText={"Attribuer un vote"}
						cancelText={"Annuler"}>
						<div className={classes["modal-content"]}>
							<Typography typo={ETypo.TEXT_MD_REGULAR} className={classes["text"]}>
								{superAdminModalType === "add" ? "Nommer" : "Retirer"} une personne Super Administrateur nécessite 3 votes
								de super administrateurs existants. Souhaitez-vous attribuer un vote ?
							</Typography>
						</div>
					</Confirm>
					<Confirm
						isOpen={isAdminModalOpened}
						onClose={closeAdminModal}
						onAccept={handleAdminModalAccepted}
						closeBtn
						header={
							adminModalType === "add"
								? `Souhaitez-vous nommer ${
										userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name
								  } administrateur de son office ?`
								: `Souhaitez-vous retirer le rôle administrateur de son office à ${
										userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name
								  } ?`
						}
						confirmText={adminModalType === "add" ? "Ajouter" : "Retirer"}
						cancelText={"Annuler"}>
						<div className={classes["modal-content"]}></div>
					</Confirm>
				</div>
			)}
			{isLoading && (
				<div className={classes["loader-container"]}>
					<div className={classes["loader"]}>
						<Loader />
					</div>
				</div>
			)}
		</DefaultUserDashboard>
	);
}
