"use client";

import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";

import Customer, { Document, DocumentType } from "le-coffre-resources/dist/Customer";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { DocumentNotary, OfficeFolder as OfficeFolderNotary } from "le-coffre-resources/dist/Notary";

import classes from "./classes.module.scss";
import { useRouter } from "next/router";
import JwtService, { ICustomerJwtPayload } from "@Front/Services/JwtService/JwtService";

import Tag, { ETagColor } from "@Front/Components/DesignSystem/Tag";
import DefaultCustomerDashboard from "@Front/Components/LayoutTemplates/DefaultCustomerDashboard";

import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import DepositDocumentComponent from "./DepositDocumentComponent";
import Module from "@Front/Config/Module";
import Separator, { ESeperatorColor, ESeperatorDirection } from "@Front/Components/DesignSystem/Separator";
import NotificationBox from "@Front/Components/DesignSystem/NotificationBox";
import ContactBox from "./ContactBox";
import { EDocumentNotaryStatus } from "le-coffre-resources/dist/Notary/DocumentNotary";
import DepositOtherDocument from "@Front/Components/DesignSystem/DepositOtherDocument";

import Modal from "@Front/Components/DesignSystem/Modal";
import TextField from "@Front/Components/DesignSystem/Form/TextField";

import AuthModal from "src/sdk/AuthModal";

import FolderService from "src/common/Api/LeCoffreApi/sdk/FolderService";
import DocumentService from "src/common/Api/LeCoffreApi/sdk/DocumentService";
import DocumentTypeService from "src/common/Api/LeCoffreApi/sdk/DocumentTypeService";
import FileService from "src/common/Api/LeCoffreApi/sdk/FileService";
import LoaderService from "src/common/Api/LeCoffreApi/sdk/Loader/LoaderService";

type IProps = {};

export default function ClientDashboard(props: IProps) {
	const router = useRouter();
	let { folderUid, profileUid } = router.query;
	const [documents, setDocuments] = useState<Document[] | null>(null);

	const [customer, setCustomer] = useState<Customer | null>(null);
	const [folder, setFolder] = useState<OfficeFolderNotary | null>(null);

	const [documentsNotary, setDocumentsNotary] = useState<DocumentNotary[]>([]);
	const [isAddDocumentModalVisible, setIsAddDocumentModalVisible] = useState<boolean>(false);

	const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
	const [isSmsModalOpen, setIsSmsModalOpen] = useState(false);
	const [smsCode, setSmsCode] = useState("");
	const [smsError, setSmsError] = useState("");

	const verifySmsCode = useCallback(() => {
		if (smsCode === "1234") {
			setIsSmsModalOpen(false);
		} else {
			setSmsError("Code incorrect. Le code valide est 1234.");
		}
	}, [smsCode]);

	useEffect(() => {
		const handleKeyPress = (e: KeyboardEvent) => {
			if (e.key === "Enter" && isSmsModalOpen) {
				verifySmsCode();
			}
		};

		window.addEventListener("keypress", handleKeyPress);
		return () => {
			window.removeEventListener("keypress", handleKeyPress);
		};
	}, [isSmsModalOpen, smsCode, verifySmsCode]);

	const fetchFolderAndCustomer = useCallback(async () => {
		let jwt: ICustomerJwtPayload | undefined;
		if (typeof document !== "undefined") {
			jwt = JwtService.getInstance().decodeCustomerJwt();
		}

		// TODO: review
		LoaderService.getInstance().show();
		const { folder, customer } = await new Promise<any>((resolve) => {
			FolderService.getFolderByUid(folderUid as string).then((process: any) => {
				if (process) {
					const folder: any = process.processData;

					const customers: any[] = folder.customers;
					const customer: any = customers.find((customer: any) => customer.uid === profileUid as string);
					if (customer) {
						resolve({ folder: folder, customer });
					}
				}
			});
		});

		setCustomer(customer);
		setFolder(folder);

		setIsAuthModalOpen(true);
		LoaderService.getInstance().hide();

		return { folder, customer };

		/*
		const folder = await Folders.getInstance().getByUid(folderUid as string, {
			q: {
				office: true,
				customers: true,
				notes: {
					include: {
						customer: true,
					},
				},
				stakeholders: {
					include: {
						contact: true,
						office_role: true,
					},
				},
				deed: {
					include: {
						deed_type: true,
					},
				},
			},
		});

		const customer = folder?.customers?.find((customer) => customer.contact?.email === jwt?.email);
		if (!customer) throw new Error("Customer not found");

		setFolder(folder);
		setCustomer(customer);

		return { folder, customer };
		*/
	}, [folderUid]);

	const fetchDocuments = useCallback(
		async (customerUid: string | undefined) => {
			LoaderService.getInstance().show();
			return new Promise<void>((resolve: () => void) => {
				DocumentService.getDocuments().then(async (processes: any[]) => {
					if (processes.length > 0) {
						let documents: any[] = processes.map((process: any) => process.processData);

						// FilterBy folder.uid & depositor.uid
						documents = documents.filter((document: any) => document.folder.uid === folderUid && document.depositor && document.depositor.uid === customerUid);

						for (const document of documents) {
							if (document.document_type) {
								document.document_type = (await DocumentTypeService.getDocumentTypeByUid(document.document_type.uid)).processData;
							}

							if (document.files && document.files.length > 0) {
								const files: any[] = [];
								for (const file of document.files) {
									files.push((await FileService.getFileByUid(file.uid)).processData);
								}
								document.files = files;
							}
						}

						setDocuments(documents);
					}
					LoaderService.getInstance().hide();
					resolve();
				});
			});
		},
		[folderUid],
	);

	useEffect(() => {
		fetchFolderAndCustomer().then(({ customer }) => fetchDocuments(customer.uid));
	}, [fetchDocuments, fetchFolderAndCustomer]);

	useEffect(() => {
		const customerUid = customer?.uid;
		if (!folderUid || !customerUid) return;

		LoaderService.getInstance().show();
		DocumentService.getDocuments().then(async (processes: any[]) => {
			if (processes.length > 0) {
				let documents: any[] = processes.map((process: any) => process.processData);

				// FilterBy folder.uid & customer.uid
				documents = documents.filter((document: any) => document.folder.uid === folderUid && document.customer && document.customer.uid === customerUid);

				for (const document of documents) {
					if (document.files && document.files.length > 0) {
						const files: any[] = [];
						for (const file of document.files) {
							files.push((await FileService.getFileByUid(file.uid)).processData);
						}
						document.files = files;
					}
				}

				setDocumentsNotary(documents);
				LoaderService.getInstance().hide();
			}
		});
	}, [folderUid, customer?.uid]);

	const documentsNotaryNotRead = useMemo(
		() => documentsNotary.filter((doc) => doc.document_status === EDocumentNotaryStatus.SENT),
		[documentsNotary],
	);

	const onCloseModalAddDocument = useCallback(() => {
		setIsAddDocumentModalVisible(false);
		fetchFolderAndCustomer();
	}, [fetchFolderAndCustomer]);

	const onOpenModalAddDocument = useCallback(() => {
		setIsAddDocumentModalVisible(true);
	}, []);

	const renderBox = useCallback(() => {
		return (
			<DepositOtherDocument
				folder_uid={folderUid!}
				customer_uid={customer!.uid!}
				open={isAddDocumentModalVisible}
				onClose={onCloseModalAddDocument}
				document={Document.hydrate<Document>({
					document_type: DocumentType.hydrate<DocumentType>({
						name: "Autres documents",
						office: folder!.office!,
					}),
				})}
			/>
		);
	}, [customer, folderUid, isAddDocumentModalVisible, onCloseModalAddDocument, folder]);

	return (
		<DefaultCustomerDashboard>
			<div className={classes["root"]}>
				<div className={classes["top"]}>
					<div className={classes["folder-info-container"]}>
						<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
							Dossier {folder?.folder_number} - {folder?.name}
						</Typography>
						<Typography typo={ETypo.TITLE_H4} color={ETypoColor.TEXT_PRIMARY}>
							Bonjour {customer?.contact?.first_name.concat(" ", customer?.contact?.last_name)}
						</Typography>
						<Tag color={ETagColor.INFO} label={folder?.deed?.deed_type?.name ?? ""} />
						<div className={classes["office-container"]}>
							<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
								Office
							</Typography>

							<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_ACCENT}>
								{folder?.office?.name}
							</Typography>
						</div>
					</div>
					<Separator
						className={classes["desktop-separator"]}
						direction={ESeperatorDirection.VERTICAL}
						size={142}
						color={ESeperatorColor.LIGHT}
					/>
					{(documentsNotaryNotRead?.length ?? 0) > 0 && (
						<NotificationBox
							text={`${documentsNotaryNotRead?.length} Nouveaux document(s) envoyé(s) par votre notaire`}
							button={{
								children: "Consulter les documents",
								variant: EButtonVariant.SECONDARY,
								styletype: EButtonstyletype.OUTLINED,
								onClick: () =>
									router.push(
										Module.getInstance()
											.get()
											.modules.pages.ClientDashboard.pages.ReceiveDocuments.props.path.replace(
												"[folderUid]",
												folderUid as string,
											),
									),
							}}
							read={false}
						/>
					)}
					{(documentsNotaryNotRead?.length ?? 0) === 0 && (documentsNotary?.length ?? 0) > 0 && (
						<NotificationBox
							text={`Consultez les documents envoyés par votre notaire`}
							button={{
								children: "Consulter les documents",
								variant: EButtonVariant.SECONDARY,
								styletype: EButtonstyletype.OUTLINED,
								onClick: () =>
									router.push(
										Module.getInstance()
											.get()
											.modules.pages.ClientDashboard.pages.ReceiveDocuments.props.path.replace(
												"[folderUid]",
												folderUid as string,
											),
									),
							}}
							read={true}
						/>
					)}
				</div>

				{customer && folder && <ContactBox customer={customer} folder={folder} />}

				<div className={classes["documents"]}>
					<Typography typo={ETypo.TEXT_LG_BOLD} color={ETypoColor.TABLE_COLUMN_CONTRAST}>
						Documents à envoyer
					</Typography>
					<div className={classes["content"]}>
						{documents?.map((document) => (
							<DepositDocumentComponent
								key={document.uid}
								document={document}
								onChange={() => fetchDocuments(customer?.uid)}
							/>
						))}
					</div>
				</div>
				<Typography typo={ETypo.TITLE_H3}>Documents supplémentaires (facultatif)</Typography>
				<Typography typo={ETypo.TEXT_MD_REGULAR} className={classes["text"]}>
					Vous souhaitez envoyer d'autres documents à votre notaire ?
				</Typography>
				<Button
					variant={EButtonVariant.PRIMARY}
					styletype={EButtonstyletype.OUTLINED}
					className={classes["button"]}
					onClick={onOpenModalAddDocument}>
					Ajouter d'autres documents
				</Button>
				{isAddDocumentModalVisible && renderBox()}

				{isAuthModalOpen && <AuthModal
					isOpen={isAuthModalOpen}
					onClose={() => {
						setIsAuthModalOpen(false);
						setIsSmsModalOpen(true);
					}}
				/>}

				{isSmsModalOpen && (
					<Modal
						isOpen={isSmsModalOpen}
						onClose={() => setIsSmsModalOpen(false)}
						title="Vérification SMS"
					>
						<div className={classes["sms-modal-content"]}>
							<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_PRIMARY}>
								Veuillez saisir le code à 4 chiffres que vous avez reçu par SMS
							</Typography>

							<TextField
								name="smsCode"
								placeholder="Code SMS à 4 chiffres"
								value={smsCode}
								onChange={(e) => {
									const value = e.target.value;
									// Only allow digits
									if (value === "" || /^\d+$/.test(value)) {
										setSmsCode(value);
										setSmsError("");
									}
								}}
							/>

							{smsError && (
								<Typography typo={ETypo.TEXT_SM_REGULAR} color={ETypoColor.TEXT_ACCENT}>
									{smsError}
								</Typography>
							)}

							<div style={{ marginTop: "20px" }}>
								<Button
									variant={EButtonVariant.PRIMARY}
									onClick={verifySmsCode}
								>
									Vérifier
								</Button>
							</div>
						</div>
					</Modal>
				)}
			</div>
		</DefaultCustomerDashboard>
	);
}
