import Button, { EButtonSize, EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import IconButton from "@Front/Components/DesignSystem/IconButton";
import Table from "@Front/Components/DesignSystem/Table";
import { IHead, IRowProps } from "@Front/Components/DesignSystem/Table/MuiTable";
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
import BackArrow from "@Front/Components/Elements/BackArrow";
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
import Module from "@Front/Config/Module";
// import JwtService, { ICustomerJwtPayload } from "@Front/Services/JwtService/JwtService";
import { ArrowDownTrayIcon, EyeIcon } from "@heroicons/react/24/outline";
import { saveAs } from "file-saver";
import JSZip from "jszip";
import { useRouter } from "next/router";
import React, { useCallback, useEffect, useState } from "react";
import classes from "./classes.module.scss";
import Link from "next/link";
import Customer from "le-coffre-resources/dist/Customer";
import { DocumentNotary } from "le-coffre-resources/dist/Notary";

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

const header: readonly IHead[] = [
	{
		key: "name",
		title: "Nom",
	},
	{
		key: "sentAt",
		title: "Envoyé le",
	},
	{
		key: "actions",
		title: "Action",
	},
];

export default function ReceivedDocuments() {
	const router = useRouter();
	let { folderUid } = router.query;
	const [documentsNotary, setDocumentsNotary] = useState<DocumentNotary[]>([]);
	const [customer, setCustomer] = useState<Customer | null>(null);

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

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

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

		setCustomer(customer);

		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");

		setCustomer(customer);

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

	useEffect(() => {
		fetchFolderAndCustomer();
	}, [folderUid]); // Ne dépend que de folderUid

	// Effet séparé pour charger les documents lorsque customer change
	useEffect(() => {
		const customerUid = customer?.uid;
		if (!folderUid || !customerUid) return;

		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]);

	const onDownload = useCallback((doc: any) => {
		const file = doc.files?.[0];
		if (!file) return;

		return new Promise<void>((resolve: () => void) => {
			const blob = new Blob([file.file_blob.data], { type: file.file_blob.type });
			const url = URL.createObjectURL(blob);
			const a = document.createElement('a');
			a.href = url;
			a.download = file.file_name;
			document.body.appendChild(a);
			a.click();
			document.body.removeChild(a);
			URL.revokeObjectURL(url);

			resolve();
		}).catch((e) => console.warn(e));
	}, []);

	const onDownloadAll = useCallback(async () => {
		if (documentsNotary.length === 0) return;

		const zip = new JSZip();
		const folder = zip.folder("documents") || zip;

		documentsNotary.map((doc: any) => {
			const file = doc.files?.[0];
			if (file) {
				const blob = new Blob([file.file_blob.data], { type: file.file_blob.type });
				folder.file(file.file_name ?? "file", blob);
			}
		});

		zip.generateAsync({ type: "blob" })
			.then((blob: any) => {
				saveAs(blob, "documents.zip");
			})
			.catch((error: any) => {
				console.error("Error generating ZIP file: ", error);
			});
	}, [documentsNotary]);

	return (
		<DefaultTemplate title={"Documents reçus"} isPadding={false}>
			<div className={classes["root"]}>
				<BackArrow
					text="Retour aux dossiers"
					url={Module.getInstance()
						.get()
						.modules.pages.ClientDashboard.props.path.replace("[folderUid]", folderUid as string)}
				/>
				<Typography typo={ETypo.TITLE_H1} color={ETypoColor.TEXT_PRIMARY}>
					Un document vous a été envoyé
				</Typography>
				<Table className={classes["table"]} header={header} rows={buildRows(documentsNotary, folderUid!, onDownload)} />
				<Button
					variant={EButtonVariant.PRIMARY}
					size={EButtonSize.LG}
					styletype={EButtonstyletype.CONTAINED}
					leftIcon={<ArrowDownTrayIcon />}
					onClick={onDownloadAll}>
					Tout télécharger
				</Button>
			</div>
		</DefaultTemplate>
	);
}

function buildRows(
	documentsNotary: DocumentNotary[],
	folderUid: string | string[],
	onDownloadFileNotary: (doc: DocumentNotary) => void,
): IRowProps[] {
	return documentsNotary.map((documentNotary) => ({
		key: documentNotary.uid ?? "",
		name: documentNotary.files?.[0]?.file_name?.split(".")?.[0] || "_",
		sentAt: new Date(documentNotary.created_at!).toLocaleDateString(),
		// actions: <IconButton onClick={() => onDownloadFileNotary(documentNotary)} icon={<ArrowDownTrayIcon />} />,
		actions: {
			sx: { width: 76 },
			content: (
				<div className={classes["actions"]}>
					<Link
						href={Module.getInstance()
							.get()
							.modules.pages.ClientDashboard.pages.ViewDocuments.props.path.replace("[folderUid]", folderUid as string)
							.replace("[documentUid]", documentNotary.uid ?? "")}>
						<IconButton icon={<EyeIcon />} />
					</Link>
					<IconButton onClick={() => onDownloadFileNotary(documentNotary)} icon={<ArrowDownTrayIcon />} />
				</div>
			),
		},
	}));
}
