import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Form from "@Front/Components/DesignSystem/Form";
import TextField from "@Front/Components/DesignSystem/Form/TextField";
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import DefaultRolesDashboard from "@Front/Components/LayoutTemplates/DefaultRoleDashboard";
import Module from "@Front/Config/Module";
import { Office, OfficeRole } from "le-coffre-resources/dist/Admin";
import { useRouter } from "next/router";
import { useCallback, useState } from "react";

import classes from "./classes.module.scss";
import JwtService from "@Front/Services/JwtService/JwtService";
import Rules, { RulesMode } from "@Front/Components/Elements/Rules";
import { AppRuleActions, AppRuleNames } from "@Front/Api/Entities/rule";
import { ValidationError } from "class-validator";

type IProps = {};
export default function RolesCreate(props: IProps) {
	const [hasChanged, setHasChanged] = useState<boolean>(false);
	const [isConfirmModalVisible, setIsConfirmModalVisible] = useState<boolean>(false);
	const [validationError, setValidationError] = useState<ValidationError[]>([]);

	const router = useRouter();
	const onSubmitHandler = useCallback(
		async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
			const jwt = JwtService.getInstance().decodeJwt();
			const officeRole = OfficeRole.hydrate<OfficeRole>({
				name: values["name"],
				office: Office.hydrate<Office>({
					uid: jwt?.office_Id,
				}),
			});
			try {
				await officeRole.validateOrReject?.({ groups: ["createOfficeRole"], forbidUnknownValues: true });
			} catch (validationErrors: Array<ValidationError> | any) {
				if (!Array.isArray(validationErrors)) return;
				setValidationError(validationErrors as ValidationError[]);
				return;
			}
			try {
				const role = await OfficeRoles.getInstance().post(
					OfficeRole.hydrate<OfficeRole>({
						name: values["name"],
						office: Office.hydrate<Office>({
							uid: jwt?.office_Id,
						}),
					}),
				);

				router.push(Module.getInstance().get().modules.pages.Roles.pages.RolesInformations.props.path.replace("[uid]", role.uid!));
			} catch (validationErrors: Array<ValidationError> | any) {
				if (!Array.isArray(validationErrors)) return;
				setValidationError(validationErrors as ValidationError[]);
				return;
			}
		},
		[router],
	);

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

	const onFieldChange = useCallback((name: string, field: any) => {
		setHasChanged(true);
	}, []);

	const redirect = useCallback(() => {
		router.push(Module.getInstance().get().modules.pages.Roles.props.path);
	}, [router]);

	const onCancel = useCallback(() => {
		if (hasChanged) {
			setIsConfirmModalVisible(true);
		} else {
			redirect();
		}
	}, [hasChanged, redirect]);

	return (
		<Rules
			mode={RulesMode.NECESSARY}
			rules={[
				{
					action: AppRuleActions.create,
					name: AppRuleNames.officeRoles,
				},
			]}>
			<DefaultRolesDashboard mobileBackText={"Liste des rôles"} hasBackArrow title="Créer un rôle">
				<div className={classes["root"]}>
					<div className={classes["header"]}>
						<Typography typo={ITypo.H1Bis}>Créer un rôle</Typography>
					</div>
					<Form onSubmit={onSubmitHandler} className={classes["form-container"]} onFieldChange={onFieldChange}>
						<TextField
							name="name"
							placeholder="Nom du rôle"
							validationError={validationError.find((error) => error.property === "name")}
						/>
						<div className={classes["buttons-container"]}>
							<Button variant={EButtonVariant.GHOST} onClick={onCancel}>
								Annuler
							</Button>
							<Button type="submit">Créer le rôle</Button>
						</div>
					</Form>
					<Confirm
						isOpen={isConfirmModalVisible}
						onClose={closeConfirmModal}
						onAccept={redirect}
						closeBtn
						header={"Êtes-vous sur de vouloir quitter sans enregistrer ?"}
						cancelText={"Annuler"}
						confirmText={"Quitter"}>
						<div className={classes["modal-content"]}>
							<Typography typo={ITypo.P_16} className={classes["text"]}>
								Si vous quittez, toutes les modifications que vous avez effectuées ne seront pas enregistrées.
							</Typography>
						</div>
					</Confirm>
				</div>
			</DefaultRolesDashboard>
		</Rules>
	);
}
