import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
import Button from "@Front/Components/DesignSystem/Button";
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
import Form from "@Front/Components/DesignSystem/Form";
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import DefaultRoleDashboard from "@Front/Components/LayoutTemplates/DefaultRoleDashboard";
import { OfficeRole, Rule, RulesGroup } from "le-coffre-resources/dist/Admin";
import { useRouter } from "next/router";
import { useCallback, useEffect, useState } from "react";
import React from "react";

import classes from "./classes.module.scss";
import RulesGroups from "@Front/Api/LeCoffreApi/Admin/RulesGroups/RulesGroups";

type RuleGroupsCheckbox = RulesGroup & {
	checked: boolean;
};

export default function RolesInformations() {
	const router = useRouter();
	let { roleUid } = router.query;

	const [roleSelected, setRoleSelected] = useState<OfficeRole | null>(null);
	const [rulesGroupsCheckboxes, setRulesGroupsCheckboxes] = useState<RuleGroupsCheckbox[]>([]);
	const [selectAll, setSelectAll] = useState<boolean>(false);

	const [isConfirmModalOpened, setIsConfirmModalOpened] = useState<boolean>(false);

	const openConfirmModal = useCallback(() => {
		setIsConfirmModalOpened(true);
	}, []);

	const closeConfirmModal = useCallback(() => {
		setIsConfirmModalOpened(false);
	}, []);

	useEffect(() => {
		setSelectAll(false);
		async function getUser() {
			if (!roleUid) return;
			const role = await OfficeRoles.getInstance().getByUid(roleUid as string, {
				q: {
					rules: true,
				},
			});

			const rulesGroups = await RulesGroups.getInstance().get({
				include: {
					rules: true,
				},
			});

			if (!role) return;
			setRoleSelected(role);
			if (!role.rules) return;
			const rulesCheckboxes = rulesGroups
				.map((ruleGroup) => {
					if (ruleGroup.rules?.every((rule) => role.rules?.find((r) => r.uid === rule.uid))) {
						return { ...ruleGroup, checked: true };
					}
					return { ...ruleGroup, checked: false };
				})
				.sort((ruleA, ruleB) => (ruleA.name! < ruleB.name! ? 1 : -1))
				.sort((rule) => (rule.checked ? -1 : 1));

			const selectAll = rulesCheckboxes.every((rule) => rule.checked);
			setSelectAll(selectAll);
			setRulesGroupsCheckboxes(rulesCheckboxes);
		}

		getUser();
	}, [roleUid]);

	const handleSelectAllChange = useCallback(
		(e: React.ChangeEvent<HTMLInputElement>) => {
			setSelectAll(e.target.checked);
			const checked = e.target.checked;
			rulesGroupsCheckboxes.forEach((rule) => (rule.checked = checked));
			setRulesGroupsCheckboxes([...rulesGroupsCheckboxes]);
		},
		[rulesGroupsCheckboxes],
	);

	const modifyRules = useCallback(async () => {
		if (!roleSelected || !roleSelected.uid) return;
		const rulesGroupsChecked = rulesGroupsCheckboxes.filter((rule) => rule.checked);

		let newRules: Rule[] = [];

		for (let ruleGroup of rulesGroupsChecked) {
			if (!ruleGroup.rules) continue;
			newRules = [...newRules, ...ruleGroup.rules];
		}
		await OfficeRoles.getInstance().put(roleSelected.uid, {
			uid: roleSelected.uid,
			rules: newRules,
		});

		const roleUpdated = await OfficeRoles.getInstance().getByUid(roleSelected.uid, {
			q: {
				rules: true,
			},
		});
		setRoleSelected(roleUpdated);
		closeConfirmModal();
	}, [closeConfirmModal, roleSelected, rulesGroupsCheckboxes]);

	const handleRuleChange = useCallback(
		(e: React.ChangeEvent<HTMLInputElement>) => {
			const ruleUid = e.target.value;
			const rule = rulesGroupsCheckboxes.find((rule) => rule.uid === ruleUid);
			if (!rule) return;
			rule.checked = e.target.checked;
			setRulesGroupsCheckboxes([...rulesGroupsCheckboxes]);
		},
		[rulesGroupsCheckboxes],
	);

	return (
		<DefaultRoleDashboard mobileBackText={"Liste des rôles"}>
			<div className={classes["root"]}>
				<div className={classes["header"]}>
					<Typography typo={ITypo.TITLE_H1}>Gestion des rôles</Typography>
				</div>
				<div className={classes["subtitle"]}>
					<Typography typo={ITypo.TITLE_H5}>{roleSelected?.name}</Typography>
				</div>
				<div className={classes["rights-container"]}>
					<div className={classes["rights-header"]}>
						<Typography typo={ITypo.TEXT_LG_SEMIBOLD}>Modifier les droits</Typography>
					</div>
					<div className={classes["select-all-container"]}>
						<CheckBox
							option={{
								label: "Tout sélectionner",
								value: "all",
							}}
							onChange={handleSelectAllChange}
							checked={selectAll}
						/>
					</div>
					<Form>
						<div className={classes["rights"]}>
							{rulesGroupsCheckboxes.map((ruleGroup) => (
								<div className={classes["right"]} key={ruleGroup.uid}>
									<CheckBox
										option={{ label: ruleGroup.name!, value: ruleGroup.uid }}
										checked={ruleGroup.checked}
										onChange={handleRuleChange}
									/>
								</div>
							))}
						</div>
						<div className={classes["save-container"]}>
							<Button onClick={openConfirmModal}>Enregistrer</Button>
						</div>
					</Form>
				</div>
				<Confirm
					isOpen={isConfirmModalOpened}
					onClose={closeConfirmModal}
					onAccept={modifyRules}
					closeBtn
					header={"Êtes-vous sûr d'enregistrer ?"}
					confirmText={"Valider"}
					cancelText={"Annuler"}>
					<div className={classes["modal-content"]}>
						<Typography typo={ITypo.TEXT_MD_REGULAR} className={classes["text"]}>
							En enregistrant vous modifiez les droits des rôles.
						</Typography>
					</div>
				</Confirm>
			</div>
		</DefaultRoleDashboard>
	);
}
