import ChevronIcon from "@Assets/Icons/chevron.svg";
import Folders from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
import OfficeFolderAnchors from "@Front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import FolderBoxInformation, { EFolderBoxInformationType } from "@Front/Components/DesignSystem/FolderBoxInformation";
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
import Module from "@Front/Config/Module";
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
import { EDocumentStatus } from "le-coffre-resources/dist/Notary/Document";
import Link from "next/link";
import { NextRouter, useRouter } from "next/router";
import { ChangeEvent } from "react";
import Image from "next/image";
import ValidateAnchoringGif from "@Front/Assets/images/validate_anchoring.gif";

import BasePage from "../../Base";
import classes from "./classes.module.scss";
import ClientSection from "./ClientSection";
import CheckBox from "@Front/Components/DesignSystem/CheckBox";

type IProps = {};

type IPropsClass = IProps & {
	router: NextRouter;
	selectedFolderUid: string;
};

type IState = {
	selectedFolder: OfficeFolder | null;
	isArchivedModalOpen: boolean;
	inputArchivedDescripton: string;
	isValidateModalVisible: boolean;
	hasValidateAnchoring: boolean;
	isVerifDeleteModalVisible: boolean;
	isAnchored: boolean | null;
	isPreventArchiveModalOpen: boolean;
};
class FolderInformationClass extends BasePage<IPropsClass, IState> {
	public constructor(props: IPropsClass) {
		super(props);
		this.state = {
			selectedFolder: null,
			isArchivedModalOpen: false,
			inputArchivedDescripton: "",
			isValidateModalVisible: false,
			hasValidateAnchoring: false,
			isVerifDeleteModalVisible: false,
			isAnchored: null,
			isPreventArchiveModalOpen: false,
		};
		this.onSelectedFolder = this.onSelectedFolder.bind(this);
		this.openArchivedModal = this.openArchivedModal.bind(this);
		this.closeArchivedModal = this.closeArchivedModal.bind(this);
		this.onArchivedModalAccepted = this.onArchivedModalAccepted.bind(this);
		this.getCompletionNumber = this.getCompletionNumber.bind(this);
		this.onArchivedDescriptionInputChange = this.onArchivedDescriptionInputChange.bind(this);
		this.deleteFolder = this.deleteFolder.bind(this);
		this.closeModal = this.closeModal.bind(this);
		this.validateAnchoring = this.validateAnchoring.bind(this);
		this.openValidateModal = this.openValidateModal.bind(this);
		this.openVerifDeleteFolder = this.openVerifDeleteFolder.bind(this);
		this.closeVerifDeleteFolder = this.closeVerifDeleteFolder.bind(this);
		this.verifyAnchorStatus = this.verifyAnchorStatus.bind(this);
		this.closePreventArchiveModal = this.closePreventArchiveModal.bind(this);
	}

	// TODO: Message if the user has not created any folder yet
	// TODO: get the selected folder from the api in componentDidMount
	public override render(): JSX.Element {
		const redirectPathEditCollaborators = Module.getInstance()
			.get()
			.modules.pages.Folder.pages.EditCollaborators.props.path.replace("[folderUid]", this.props.selectedFolderUid);
		return (
			<DefaultNotaryDashboard
				title={"Dossier"}
				onSelectedFolder={this.onSelectedFolder}
				isArchived={false}
				mobileBackText="Retour aux dossiers">
				<div className={classes["root"]}>
					{this.state.selectedFolder ? (
						<div className={classes["folder-informations"]}>
							<div className={classes["folder-header"]}>
								<div className={classes["header"]}>
									<div className={classes["title"]}>
										<Typography typo={ITypo.H1Bis}>Informations du dossier</Typography>
									</div>
									<Link href={redirectPathEditCollaborators}>
										<Button variant={EButtonVariant.LINE} icon={ChevronIcon}>
											Modifier les collaborateurs
										</Button>
									</Link>
								</div>
								<FolderBoxInformation folder={this.state.selectedFolder} type={EFolderBoxInformationType.INFORMATIONS} />
								<div className={classes["second-box"]}>
									<FolderBoxInformation folder={this.state.selectedFolder} type={EFolderBoxInformationType.DESCRIPTION} />
								</div>
								<div className={classes["progress-bar"]}>
									<QuantityProgressBar
										title="Complétion du dossier"
										total={100}
										currentNumber={this.getCompletionNumber()}
									/>
								</div>
								{this.doesFolderHaveCustomer() && <ClientSection folder={this.state.selectedFolder} />}
							</div>

							{!this.doesFolderHaveCustomer() && <ClientSection folder={this.state.selectedFolder} />}

							<div className={classes["button-container"]}>
								<Button variant={EButtonVariant.GHOST} onClick={this.openArchivedModal}>
									Archiver le dossier
								</Button>
								{this.everyDocumentValidated() && (
									<>
										{this.state.isAnchored === null && (
											<Button variant={EButtonVariant.PRIMARY} onClick={this.openValidateModal}>
												Ancrer le dossier
											</Button>
										)}
										{this.state.isAnchored === true && (
											<Button
												variant={EButtonVariant.PRIMARY}
												onClick={() => this.downloadAnchoringProof(this.state.selectedFolder?.uid)}>
												Télécharger la preuve d'ancrage
											</Button>
										)}
									</>
								)}
								{!this.doesFolderHaveCustomer() && (
									<span className={classes["delete-folder"]} onClick={this.openVerifDeleteFolder}>
										<Button variant={EButtonVariant.SECONDARY}>Supprimer le dossier</Button>
									</span>
								)}
							</div>
							<Confirm
								isOpen={this.state.isArchivedModalOpen}
								onAccept={this.onArchivedModalAccepted}
								onClose={this.closeArchivedModal}
								closeBtn
								header={"Archiver le dossier ?"}
								cancelText={"Annuler"}
								confirmText={"Archiver"}>
								<div className={classes["modal-title"]}>
									<Typography typo={ITypo.P_16}>Souhaitez-vous vraiment archiver le dossier ?</Typography>
								</div>
								<TextAreaField
									name="archived_description"
									placeholder="Description"
									onChange={this.onArchivedDescriptionInputChange}
								/>
							</Confirm>
							<Confirm
								isOpen={this.state.isVerifDeleteModalVisible}
								onAccept={this.deleteFolder}
								onClose={this.closeVerifDeleteFolder}
								closeBtn
								header={"Êtes-vous sûr de vouloir supprimer ce dossier ?"}
								cancelText={"Annuler"}
								confirmText={"Confirmer"}>
								<div className={classes["modal-title"]}>
									<Typography typo={ITypo.P_16}>Cette action sera irréversible.</Typography>
								</div>
							</Confirm>
						</div>
					) : (
						<div className={classes["no-folder-selected"]}>
							<Typography typo={ITypo.H1Bis}>Informations du dossier</Typography>
							<div className={classes["choose-a-folder"]}>
								<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
									Sélectionnez un dossier
								</Typography>
							</div>
						</div>
					)}
				</div>
				<Confirm
					isOpen={this.state.isPreventArchiveModalOpen}
					onAccept={this.closePreventArchiveModal}
					onClose={this.closePreventArchiveModal}
					closeBtn
					header={"Vous devez valider et certifier un dossier avant de pouvoir l'archiver"}
					cancelText={"Annuler"}
					confirmText={"J'ai compris"}>
					<div className={classes["modal-title"]}>
						<Typography typo={ITypo.P_16}>
							Pour valider un dossier, toutes les pièces envoyées par vos clients doivent être validées (vert). Si certains
							documents sont en attente (orange), alors, veuillez les valider ou les refuser et veillez à ce qu'aucun document
							ne soit encore en demandé au client (gris)
						</Typography>
					</div>
				</Confirm>
				<Confirm
					isOpen={this.state.isValidateModalVisible}
					onClose={this.closeModal}
					onAccept={this.validateAnchoring}
					closeBtn={true}
					hasContainerClosable={true}
					header={
						this.state.hasValidateAnchoring
							? "Dossier en cours de certification"
							: "Êtes-vous sûr de vouloir ancrer et certifier ce dossier ?"
					}
					cancelText={"Annuler"}
					confirmText={"Confirmer"}
					showButtons={!this.state.hasValidateAnchoring}>
					<div className={classes["validate-document-container"]}>
						{!this.state.hasValidateAnchoring && (
							<Typography typo={ITypo.P_16} color={ITypoColor.BLACK} className={classes["validate-text"]}>
								Les documents du dossier seront certifiés sur la blockchain. Pensez à bien télécharger l'ensemble des
								documents du dossier ainsi que le fichier de preuve d'ancrage pour les mettre dans la GED de votre logiciel
								de rédaction d'actes.
							</Typography>
						)}
						{this.state.hasValidateAnchoring && (
							<div className={classes["document-validating-container"]}>
								<Typography typo={ITypo.P_16} color={ITypoColor.BLACK} className={classes["validate-text"]}>
									Vous pouvez désormais télécharger les feuilles d'ancrage et les mettre dans la GED de votre logiciel de
									rédaction d'acte.
								</Typography>
								<Image src={ValidateAnchoringGif} alt="Anchoring animation" className={classes["validate-gif"]} />
								<div className={classes["dont-show-again"]}>
									<CheckBox option={{ label: "Ne plus afficher ce message", value: false }} />
								</div>
							</div>
						)}
					</div>
				</Confirm>
			</DefaultNotaryDashboard>
		);
	}
	public override async componentDidMount() {
		const selectedFolder = await this.getFolder();
		this.setState(
			{
				selectedFolder,
			},
			() => {
				this.verifyAnchorStatus();
			},
		);
	}

	private closePreventArchiveModal() {
		this.setState({
			isPreventArchiveModalOpen: false,
		});
	}

	private async verifyAnchorStatus() {
		if (!this.state.selectedFolder || !this.state.selectedFolder.uid) return;
		try {
			const anchorStatus = await OfficeFolderAnchors.getInstance().get(this.state.selectedFolder.uid!);
			this.setState({
				isAnchored: anchorStatus.status === "VERIFIED_ON_CHAIN",
			});
		} catch (e) {
			this.setState({
				isAnchored: null,
			});
		}
	}
	public openVerifDeleteFolder() {
		this.setState({
			isVerifDeleteModalVisible: true,
		});
	}

	public closeVerifDeleteFolder() {
		this.setState({
			isVerifDeleteModalVisible: false,
		});
	}

	private closeModal() {
		this.setState({
			isValidateModalVisible: false,
		});
	}

	private openValidateModal() {
		this.setState({
			isValidateModalVisible: true,
		});
	}

	private async validateAnchoring() {
		this.setState({
			hasValidateAnchoring: true,
		});

		try {
			const timeoutDelay = 9800;
			await this.anchorFolder();
			setTimeout(() => {
				this.setState({
					isValidateModalVisible: false,
				});
			}, timeoutDelay);

			setTimeout(() => {
				this.setState({
					hasValidateAnchoring: false,
				});
			}, timeoutDelay + 1000);
		} catch (e) {
			this.setState({
				isValidateModalVisible: false,
				hasValidateAnchoring: false,
			});
			console.error(e);
		}
	}

	private async anchorFolder() {
		if (!this.state.selectedFolder?.uid) return;
		return await OfficeFolderAnchors.getInstance().post(this.state.selectedFolder.uid);
	}

	private async downloadAnchoringProof(uid?: string) {
		if (!uid) return;

		try {
			const file: Blob = await OfficeFolderAnchors.getInstance().download(uid);
			const url = window.URL.createObjectURL(file);
			const a = document.createElement("a");
			a.style.display = "none";
			a.href = url;
			// the filename you want
			a.download = `anchoring_proof_${this.state.selectedFolder?.folder_number}_${this.state.selectedFolder?.name}.pdf`;
			document.body.appendChild(a);
			a.click();
			window.URL.revokeObjectURL(url);
		} catch (e) {
			console.error(e);
		}
	}

	private everyDocumentValidated(): boolean {
		if (!this.state.selectedFolder?.documents) return false;
		return (
			this.state.selectedFolder?.documents?.length >= 1 &&
			this.state.selectedFolder?.documents.every((document) => document.document_status === EDocumentStatus.VALIDATED)
		);
	}

	private async deleteFolder() {
		if (!this.state.selectedFolder?.uid) return;
		await Folders.getInstance().delete(this.state.selectedFolder.uid);
		this.props.router.push(Module.getInstance().get().modules.pages.Folder.props.path);
	}

	private getCompletionNumber() {
		const documents = this.state.selectedFolder?.documents;
		if (!documents) return 0;
		const totalDocuments = documents.length;
		const refusedDocuments = documents.filter((document) => document.document_status === EDocumentStatus.REFUSED).length ?? 0;
		const askedDocuments =
			documents.filter(
				(document) => document.document_status === EDocumentStatus.ASKED || document.document_status === EDocumentStatus.DEPOSITED,
			).length ?? 0;
		const depositedDocuments = totalDocuments - askedDocuments - refusedDocuments;
		const percentage = (depositedDocuments / totalDocuments) * 100;
		return isNaN(percentage) ? 0 : percentage;
	}

	private doesFolderHaveCustomer(): boolean {
		if (!this.state.selectedFolder?.customers) return false;
		return this.state.selectedFolder?.customers!.length > 0;
	}

	private onSelectedFolder(folder: OfficeFolder): void {
		this.setState({ selectedFolder: folder });
	}

	private openArchivedModal(): void {
		if (this.everyDocumentValidated() && this.state.isAnchored) {
			this.setState({ isArchivedModalOpen: true });
		} else {
			this.setState({ isPreventArchiveModalOpen: true });
		}
	}

	private closeArchivedModal(): void {
		this.setState({ isArchivedModalOpen: false });
	}

	private onArchivedDescriptionInputChange(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) {
		this.setState({ inputArchivedDescripton: e.target.value });
	}

	private async onArchivedModalAccepted() {
		if (!this.state.selectedFolder) return;
		const ressourceFolder = OfficeFolder.hydrate<OfficeFolder>(this.state.selectedFolder);
		ressourceFolder.archived_description = this.state.inputArchivedDescripton;
		await Folders.getInstance().archive(this.state.selectedFolder.uid ?? "", ressourceFolder);
		this.closeArchivedModal();
		this.props.router.push(Module.getInstance().get().modules.pages.Folder.props.path);
	}

	private async getFolder(): Promise<OfficeFolder> {
		const query = {
			q: {
				deed: { include: { deed_type: true } },
				office: true,
				customers: {
					include: {
						contact: true,
						documents: {
							include: {
								folder: true,
								document_type: true,
								files: true,
							},
						},
					},
				},
				documents: {
					include: {
						depositor: {
							include: {
								contact: true,
							},
						},
					},
				},
				folder_anchor: true,
			},
		};

		const folder = await Folders.getInstance().getByUid(this.props.selectedFolderUid, query);
		return folder;
	}
}

export default function FolderInformation(props: IProps) {
	const router = useRouter();
	let { folderUid } = router.query;
	folderUid = folderUid as string;
	return <FolderInformationClass {...props} selectedFolderUid={folderUid} router={router} />;
}
