import DragAndDrop, { IDocumentFileWithUid } from "@Front/Components/DesignSystem/DragAndDrop";
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
import { useCallback, useMemo, useState } from "react";

import classes from "./classes.module.scss";
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
import { ToasterService } from "@Front/Components/DesignSystem/Toaster";
import Confirm from "@Front/Components/DesignSystem/OldModal/Confirm";

import FileService from "src/common/Api/LeCoffreApi/sdk/FileService";
import DocumentService from "src/common/Api/LeCoffreApi/sdk/DocumentService";
import { FileBlob, FileData } from "@Front/Api/Entities/types";
import WatermarkService from "@Front/Services/WatermarkService";

type IProps = {
	document: any;
	onChange: () => void;
};

export default function DepositDocumentComponent(props: IProps) {
	const { document, onChange } = props;
	const [isModalOpen, setIsModalOpen] = useState(false);
	const [refused_reason, setRefusedReason] = useState<string | null>(null);

	const defaultFiles: IDocumentFileWithUid[] = useMemo(() => {
		const filesNotArchived = document.files?.filter((file: any) => !file.archived_at) ?? [];
		return filesNotArchived.map((file: any) => ({
			id: file.uid!,
			file: new File([""], file.file_name!, { type: file.file_blob.type }),
			uid: file.uid!,
		}));
	}, [document.files]);

	const addFile = useCallback(
		async (file: File) => {
			try {
				// Add watermark to the file before processing
				const watermarkedFile = await WatermarkService.getInstance().addWatermark(file);
				
				return new Promise<void>(
					(resolve: () => void) => {
						const reader = new FileReader();
						reader.onload = (event) => {
							if (event.target?.result) {
								const arrayBuffer = event.target.result as ArrayBuffer;
								const uint8Array = new Uint8Array(arrayBuffer);

								const fileBlob: FileBlob = {
									type: watermarkedFile.type,
									data: uint8Array
								};

								const fileData: FileData = {
									file_blob: fileBlob,
									file_name: watermarkedFile.name
								};
								const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';

								FileService.createFile(fileData, validatorId).then((processCreated: any) => {
									const fileUid: string = processCreated.processData.uid;

									DocumentService.getDocumentByUid(document.uid!).then((process: any) => {
										if (process) {
											const document: any = process.processData;

											let files: any[] = document.files;
											if (!files) {
												files = [];
											}
											files.push({ uid: fileUid });

											DocumentService.updateDocument(process, { files: files, document_status: EDocumentStatus.DEPOSITED }).then(() => resolve());
										}
									});
								});
							}
						};
						reader.readAsArrayBuffer(watermarkedFile);
					})
					.then(onChange)
					.then(() => ToasterService.getInstance().success({ title: "Succès !", description: "Fichier uploadé avec succès!" }))
					.catch((error) => ToasterService.getInstance().error({ title: "Erreur !", description: error.message }));
			} catch (error) {
				console.error('Error processing file with watermark:', error);
				// If watermarking fails, proceed with original file
				return new Promise<void>(
					(resolve: () => void) => {
						const reader = new FileReader();
						reader.onload = (event) => {
							if (event.target?.result) {
								const arrayBuffer = event.target.result as ArrayBuffer;
								const uint8Array = new Uint8Array(arrayBuffer);

								const fileBlob: FileBlob = {
									type: file.type,
									data: uint8Array
								};

								const fileData: FileData = {
									file_blob: fileBlob,
									file_name: file.name
								};
								const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';

								FileService.createFile(fileData, validatorId).then((processCreated: any) => {
									const fileUid: string = processCreated.processData.uid;

									DocumentService.getDocumentByUid(document.uid!).then((process: any) => {
										if (process) {
											const document: any = process.processData;

											let files: any[] = document.files;
											if (!files) {
												files = [];
											}
											files.push({ uid: fileUid });

											DocumentService.updateDocument(process, { files: files, document_status: EDocumentStatus.DEPOSITED }).then(() => resolve());
										}
									});
								});
							}
						};
						reader.readAsArrayBuffer(file);
					})
					.then(onChange)
					.then(() => ToasterService.getInstance().success({ title: "Succès !", description: "Fichier uploadé avec succès!" }))
					.catch((error) => ToasterService.getInstance().error({ title: "Erreur !", description: error.message }));
			}
		},
		[document.uid, onChange],
	);

	const deleteFile = useCallback(
		(fileUid: string) => {
			return new Promise<void>(
				(resolve: () => void) => {
					FileService.getFileByUid(fileUid).then((res: any) => {
						if (res) {
							FileService.updateFile(res.processId, { isDeleted: 'true' }).then(() => {
								DocumentService.getDocumentByUid(document.uid!).then((process: any) => {
									if (process) {
										const document: any = process.processData;

										let files: any[] = document.files;
										if (!files) {
											files = [];
										}
										files = files.filter((file: any) => file.uid !== fileUid);

										DocumentService.updateDocument(process, { files: files, document_status: EDocumentStatus.ASKED }).then(() => resolve());
									}
								});
							});
						}
					});
				})
				.then(onChange)
				.then(() => ToasterService.getInstance().success({ title: "Succès !", description: "Fichier supprimé avec succès!" }))
				.catch((error) => ToasterService.getInstance().error({ title: "Erreur !", description: error.message }));
		},
		[onChange],
	);

	const onOpenModal = useCallback(async () => {
		if (document.document_status !== "REFUSED") return;
		const refused_reason = document.refused_reason;
		if (!refused_reason) return;
		setRefusedReason(refused_reason);
		setIsModalOpen(true);
	}, [document.document_history]);

	const closeModal = useCallback(() => {
		setIsModalOpen(false);
	}, []);

	return (
		<div className={classes["root"]}>
			<div className={classes["title"]}>
				<Typography typo={ETypo.TEXT_MD_SEMIBOLD} color={ETypoColor.TEXT_PRIMARY}>
					{document.document_type?.name ?? "_"}
				</Typography>
				<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
					Demandé le :{" "}
					<a className={classes["date"]}>{document.created_at ? new Date(document.created_at).toLocaleDateString() : "_"}</a>
				</Typography>
				{document.document_status === "DEPOSITED" && (
					<div>
						<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
							Déposé le :{" "}
							<a className={classes["date"]}>
								{document.updated_at ? new Date(document.updated_at).toLocaleDateString() : "_"}
							</a>
						</Typography>
					</div>
				)}
				{document.document_status === "REFUSED" && (
					<div>
						<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
							Refusé le :{" "}
							<a className={classes["date"]}>
								{document.updated_at ? new Date(document.updated_at).toLocaleDateString() : "_"}
							</a>
						</Typography>
						<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.ERROR_WEAK_CONTRAST} onClick={onOpenModal}>
							Document non-conforme{" : "} <a className={classes["refused-link"]}>Voir le motif de refus</a>
						</Typography>
					</div>
				)}
				{document.document_status === "VALIDATED" && (
					<div>
						<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
							Validé le :{" "}
							<a className={classes["date"]}>
								{document.updated_at ? new Date(document.updated_at).toLocaleDateString() : "_"}
							</a>
						</Typography>
					</div>
				)}
			</div>

			<Confirm
				isOpen={isModalOpen}
				showCancelButton={false}
				onAccept={closeModal}
				onClose={closeModal}
				closeBtn
				header={"Motif de refus"}
				confirmText={"J'ai compris"}>
				<div className={classes["modal-content"]}>
					<Typography typo={ETypo.TEXT_MD_SEMIBOLD} className={classes["text"]}>
						Votre document a été refusé pour la raison suivante :
					</Typography>
					<br />
					<Typography typo={ETypo.TEXT_MD_REGULAR} className={classes["text"]}>
						{refused_reason}
					</Typography>
				</div>
			</Confirm>

			{document.document_status !== "VALIDATED" && (
				<DragAndDrop
					title={"Glisser-déposer ou"}
					description={document.document_type?.public_description ?? undefined}
					defaultFiles={defaultFiles}
					onAddFile={addFile}
					onDelete={deleteFile}
				/>
			)}
		</div>
	);
}
