import ChevronIcon from "@Assets/Icons/chevron.svg";
import Folders from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
import Button, { EButtonStyleType, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import FolderBoxInformation, { EFolderBoxInformationType } from "@Front/Components/DesignSystem/FolderBoxInformation";
import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar";
import Typography, { ETypo, ETypoColor } 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 { NextRouter, useRouter } from "next/router";

import BasePage from "../../Base";
import classes from "./classes.module.scss";
import ClientSection from "./ClientSection";
import Link from "next/link";
import { AnchorStatus } from "../../Folder/FolderInformation";
import { useCallback, useEffect, useState } from "react";
import OfficeFolderAnchors from "@Front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors";
import Loader from "@Front/Components/DesignSystem/Loader";

type IProps = {};

type IPropsClass = IProps & {
	router: NextRouter;
	selectedFolderUid: string;
	isLoading: boolean;
	selectedFolder: OfficeFolder | null;
	isAnchored: AnchorStatus;
	getFolderCallback: () => Promise<void>;
};

type IState = {
	selectedFolder: OfficeFolder | null;
	isArchivedModalOpen: boolean;
	loadingAnchoring: boolean;
};
class FolderInformationClass extends BasePage<IPropsClass, IState> {
	public constructor(props: IPropsClass) {
		super(props);
		this.state = {
			selectedFolder: null,
			isArchivedModalOpen: false,
			loadingAnchoring: false,
		};
		this.onSelectedFolder = this.onSelectedFolder.bind(this);
		this.openArchivedModal = this.openArchivedModal.bind(this);
		this.closeArchivedModal = this.closeArchivedModal.bind(this);
		this.restoreFolder = this.restoreFolder.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={true}>
				{!this.props.isLoading && (
					<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={ETypo.TITLE_H1}>Informations du dossier</Typography>
										</div>
										<Link href={redirectPathEditCollaborators}>
											<Button variant={EButtonVariant.PRIMARY} styleType={EButtonStyleType.TEXT} icon={ChevronIcon}>
												Modifier les collaborateurs
											</Button>
										</Link>
									</div>
									<FolderBoxInformation
										anchorStatus={this.props.isAnchored}
										folder={this.state.selectedFolder}
										isArchived
										type={EFolderBoxInformationType.INFORMATIONS}
									/>
									<div className={classes["second-box"]}>
										<FolderBoxInformation
											anchorStatus={this.props.isAnchored}
											folder={this.state.selectedFolder}
											isArchived
											type={EFolderBoxInformationType.DESCRIPTION}
										/>
									</div>
									<div className={classes["second-box"]}>
										<FolderBoxInformation
											anchorStatus={this.props.isAnchored}
											folder={this.state.selectedFolder}
											isArchived
											type={EFolderBoxInformationType.ARCHIVED_DESCRIPTION}
										/>
									</div>

									<div className={classes["progress-bar"]}>
										<QuantityProgressBar title="Complétion du dossier" total={100} currentNumber={0} />
									</div>
									{this.doesFolderHaveCustomer() && (
										<ClientSection
											folder={this.state.selectedFolder}
											anchorStatus={this.props.isAnchored}
											getFolderCallback={this.props.getFolderCallback}
										/>
									)}
								</div>

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

								<div className={classes["button-container"]}>
									<Button
										variant={EButtonVariant.PRIMARY}
										styleType={EButtonStyleType.OUTLINED}
										onClick={this.restoreFolder}>
										Restaurer le dossier
									</Button>
									{this.props.isAnchored === AnchorStatus.VERIFIED_ON_CHAIN && (
										<Button
											variant={EButtonVariant.PRIMARY}
											onClick={() => this.downloadAnchoringProof(this.props.selectedFolder?.uid)}
											disabled={this.state.loadingAnchoring}>
											Télécharger la preuve d'ancrage
											{this.state.loadingAnchoring && (
												<div className={classes["loader-container"]}>
													<div className={classes["loader"]}>
														<Loader />
													</div>
												</div>
											)}
										</Button>
									)}
								</div>
							</div>
						) : (
							<div className={classes["no-folder-selected"]}>
								<Typography typo={ETypo.TITLE_H1}>Informations du dossier</Typography>
								<div className={classes["choose-a-folder"]}>
									<Typography typo={ETypo.TEXT_LG_REGULAR} color={ETypoColor.COLOR_NEUTRAL_500}>
										Aucun dossier sélectionné
									</Typography>
								</div>
							</div>
						)}
					</div>
				)}
				{this.props.isLoading && (
					<div className={classes["loader-container"]}>
						<div className={classes["loader"]}>
							<Loader />
						</div>
					</div>
				)}
			</DefaultNotaryDashboard>
		);
	}
	public override async componentDidMount() {
		const folder = await this.getFolder();
		this.setState({ selectedFolder: folder });
	}

	private doesFolderHaveCustomer(): boolean {
		return this.state.selectedFolder?.customers !== undefined;
	}

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

	private async restoreFolder() {
		if (!this.state.selectedFolder) return;
		await Folders.getInstance().restore(this.state.selectedFolder.uid ?? "");
		this.props.router.push(
			Module.getInstance()
				.get()
				.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.selectedFolderUid),
		);
	}

	private openArchivedModal(): void {
		this.setState({ isArchivedModalOpen: true });
	}

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

	private async downloadAnchoringProof(uid?: string) {
		if (!uid) return;
		this.setState({ loadingAnchoring: true });
		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.props.selectedFolder?.folder_number}_${this.props.selectedFolder?.name}.zip`;
			document.body.appendChild(a);
			a.click();
			window.URL.revokeObjectURL(url);
			this.setState({ loadingAnchoring: false });
		} catch (e) {
			this.setState({ loadingAnchoring: false });
			console.error(e);
		}
	}

	private async getFolder(): Promise<OfficeFolder> {
		const query = {
			q: {
				deed: { include: { deed_type: "true" } },
				office: "true",
				customers: { include: { contact: true } },
				notes: "true",
			},
		};
		const folder = await Folders.getInstance().getByUid(this.props.selectedFolderUid, query);
		return folder;
	}
}

export default function FolderInformation(props: IProps) {
	const router = useRouter();
	const [isAnchored, setIsAnchored] = useState<AnchorStatus>(AnchorStatus.NOT_ANCHORED);
	const [isLoading, setIsLoading] = useState<boolean>(true);
	const [selectedFolder, setSelectedFolder] = useState<OfficeFolder | null>(null);

	let { folderUid } = router.query;
	folderUid = folderUid as string;

	const getAnchoringStatus = useCallback(async () => {
		if (!folderUid) return;
		setIsLoading(true);
		try {
			const anchorStatus = await OfficeFolderAnchors.getInstance().getByUid(folderUid as string);
			setIsAnchored(anchorStatus.status === "VERIFIED_ON_CHAIN" ? AnchorStatus.VERIFIED_ON_CHAIN : AnchorStatus.ANCHORING);
		} catch (e) {
			setIsAnchored(AnchorStatus.NOT_ANCHORED);
		}
		setIsLoading(false);
	}, [folderUid]);

	const getFolder = useCallback(async () => {
		if (!folderUid) return;
		setIsLoading(true);
		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(folderUid as string, query);
		if (folder) {
			setSelectedFolder(folder);
			getAnchoringStatus();
		}

		setIsLoading(false);
	}, [folderUid, getAnchoringStatus]);

	useEffect(() => {
		setIsLoading(true);
		getFolder();
	}, [getFolder]);

	return (
		<FolderInformationClass
			{...props}
			selectedFolderUid={folderUid}
			selectedFolder={selectedFolder}
			router={router}
			isLoading={isLoading}
			isAnchored={isAnchored}
			getFolderCallback={getFolder}
		/>
	);
}
