import DepositDocumentIcon from "@Assets/Icons/deposit-document.svg";
import CrossIcon from "@Assets/Icons/cross.svg";
import DocumentCheckIcon from "@Assets/Icons/document-check.svg";
import PlusIcon from "@Assets/Icons/plus.svg";

import Image from "next/image";
import React from "react";

import Typography, { ETypo, ETypoColor } from "../Typography";
import classes from "./classes.module.scss";
import { Document } from "le-coffre-resources/dist/Customer";
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
import classNames from "classnames";

import Button, { EButtonStyleType, EButtonVariant } from "../Button";
import Confirm from "../Modal/Confirm";
import Documents from "@Front/Api/LeCoffreApi/Customer/Documents/Documents";
import Files from "@Front/Api/LeCoffreApi/Customer/Files/Files";
import Alert from "../Modal/Alert";

type IProps = {
	onChange?: (files: File[]) => void;
	open: boolean;
	onClose?: () => void;
	document: Document;
	customer_uid: string;
	folder_uid: string | string[];
};

type IFile = {
	index: number;
	file: File;
	fileName: string;
};

type IState = {
	files: IFile[];
	isDragOver: boolean;
	currentFiles?: IFile[];
	refusedReason?: string;
	isShowRefusedReasonModalVisible: boolean;
	showFailedUploaded: string | null;
	showFailedDocument: string | null;
	isAddDocumentModalVisible: boolean;
	isLoading: boolean;
};

export default class DepositOtherDocument extends React.Component<IProps, IState> {
	private inputRef = React.createRef<HTMLInputElement>();
	private index = 0;

	public constructor(props: IProps) {
		super(props);

		this.state = {
			isAddDocumentModalVisible: this.props.open,
			files: [],
			isDragOver: false,
			refusedReason: "",
			isShowRefusedReasonModalVisible: false,
			showFailedUploaded: null,
			isLoading: false,
			showFailedDocument: null,
		};

		this.addDocument = this.addDocument.bind(this);
		this.onFileChange = this.onFileChange.bind(this);
		this.removeFile = this.removeFile.bind(this);
		this.onDragOver = this.onDragOver.bind(this);
		this.onDragDrop = this.onDragDrop.bind(this);
		this.onDragLeave = this.onDragLeave.bind(this);
		this.onAccept = this.onAccept.bind(this);
		this.onCloseAlertUpload = this.onCloseAlertUpload.bind(this);
	}

	public override render(): JSX.Element {
		return (
			<div>
				<Confirm
					isOpen={this.state.isAddDocumentModalVisible}
					onClose={this.props.onClose!}
					onAccept={this.onAccept}
					closeBtn
					header={"Ajouter un document"}
					cancelText={"Annuler"}
					confirmText={this.state.isLoading ? "Chargement..." : "Déposer le document"}
					canConfirm={!this.state.isLoading}>
					<div className={classes["modal-content"]}>
						<div className={classes["container"]}>
							<Typography typo={ETypo.TEXT_MD_REGULAR} className={classes["text"]}>
								Vous souhaitez envoyer un autre document à votre notaire ?
							</Typography>
							<Typography typo={ETypo.TEXT_MD_REGULAR} className={classes["text"]}>
								Glissez / Déposez votre document dans la zone prévue à cet effet ou cliquez sur la zone puis sélectionnez le
								document correspondant.
							</Typography>
							<div
								className={classNames(
									classes["root"],
									this.props.document.document_status === EDocumentStatus.VALIDATED && classes["validated"],
								)}
								onDragOver={this.onDragOver}
								onDrop={this.onDragDrop}
								onDragLeave={this.onDragLeave}
								data-drag-over={this.state.isDragOver.toString()}>
								<input type="file" ref={this.inputRef} hidden onChange={this.onFileChange} />
								<div className={classes["top-container"]}>
									<div className={classes["left"]}>
										<Image src={DepositDocumentIcon} alt="Deposit document" />
									</div>
									<div className={classes["separator"]} />
									<div className={classes["right"]}>
										<Typography
											typo={ETypo.TEXT_MD_SEMIBOLD}
											color={ETypoColor.COLOR_GENERIC_BLACK}
											className={classes["title"]}>
											<div
												className={
													this.props.document.document_status === EDocumentStatus.VALIDATED
														? classes["validated"]
														: ""
												}>
												{this.props.document.document_type?.name}
											</div>
										</Typography>
										<Typography color={ETypoColor.COLOR_NEUTRAL_500} typo={ETypo.TEXT_SM_REGULAR}>
											Sélectionnez des documents .jpg, .pdf ou .png
										</Typography>
									</div>
								</div>
								{this.state.currentFiles && this.state.currentFiles.length > 0 && (
									<div className={classes["documents-container"]}>
										{this.state.currentFiles.map((file) => {
											const fileObj = file.file;

											return (
												<div className={classes["file-container"]} key={fileObj.name}>
													<div className={classes["left-part"]}>
														<Image src={DocumentCheckIcon} alt="Document check" />
														<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.COLOR_NEUTRAL_500}>
															{this.shortName(fileObj.name)}
														</Typography>
													</div>
													<Image
														src={CrossIcon}
														alt="Cross icon"
														className={classes["cross"]}
														onClick={this.removeFile}
														data-file={file.index}
													/>
												</div>
											);
										})}
									</div>
								)}
								<div className={classes["bottom-container"]}>
									<Button
										variant={EButtonVariant.PRIMARY}
										styleType={EButtonStyleType.TEXT}
										className={classes["add-button"]}
										onClick={this.addDocument}>
										<Typography
											typo={ETypo.TEXT_MD_SEMIBOLD}
											color={ETypoColor.COLOR_SECONDARY_500}
											className={classes["add-document"]}>
											Ajouter un document <Image src={PlusIcon} alt="Plus icon" />
										</Typography>
									</Button>
								</div>
							</div>
						</div>
					</div>
				</Confirm>
				{this.state.showFailedDocument && (
					<Alert
						onClose={this.onCloseAlertUpload}
						header={"L'ajout de Document n'est plus autorisé"}
						isOpen={!!this.state.showFailedDocument}>
						<div className={classes["modal-content"]}>
							<Typography typo={ETypo.TEXT_MD_REGULAR} className={classes["text"]}>
								{this.state.showFailedDocument}
							</Typography>
						</div>
					</Alert>
				)}
				{this.state.showFailedUploaded && (
					<Alert onClose={this.onCloseAlertUpload} header={"Fichier non autorisé"} isOpen={!!this.state.showFailedUploaded}>
						<div className={classes["modal-content"]}>
							<Typography typo={ETypo.TEXT_MD_REGULAR} className={classes["text"]}>
								{this.state.showFailedUploaded}
							</Typography>
						</div>
					</Alert>
				)}
			</div>
		);
	}

	public override componentDidMount(): void {}

	private onCloseAlertUpload() {
		this.setState({ showFailedUploaded: null });
	}

	private async onAccept() {
		this.setState({
			isLoading: true,
		});
		const filesArray = this.state.currentFiles;

		if (!filesArray) return;
		let documentCreated: Document = {} as Document;
		try {
			documentCreated = await Documents.getInstance().post({
				folder: {
					uid: this.props.folder_uid,
				},
				depositor: {
					uid: this.props.customer_uid,
				},
			});
		} catch (e) {
			this.setState({ showFailedDocument: "Le dossier est vérifié aucune modification n'est acceptée", isLoading: false });
			return;
		}

		for (let i = 0; i < filesArray.length; i++) {
			const formData = new FormData();
			formData.append("file", filesArray[i]!.file, filesArray[i]!.fileName);
			const query = JSON.stringify({ document: { uid: documentCreated.uid } });
			formData.append("q", query);
			try {
				await Files.getInstance().post(formData);
			} catch (e) {
				this.setState({ showFailedUploaded: "Le fichier ne correspond pas aux critères demandés", isLoading: false });
				return;
			}
		}

		this.setState({
			isLoading: false,
		});

		this.props.onClose!();
	}

	private shortName(name: string): string {
		const maxLength = 20;
		if (name.length > maxLength) {
			return name.substring(0, maxLength / 2) + "..." + name.substring(name.length - maxLength / 2, name.length);
		}
		return name;
	}

	private onDragOver(event: React.DragEvent<HTMLDivElement>) {
		if (!this.state.isDragOver) {
			this.setState({
				isDragOver: true,
			});
		}
		event.preventDefault();
	}

	private onDragLeave(event: React.DragEvent<HTMLDivElement>) {
		this.setState({
			isDragOver: false,
		});
		event.preventDefault();
	}

	private async onDragDrop(event: React.DragEvent<HTMLDivElement>) {
		event.preventDefault();
		this.setState({
			isDragOver: false,
		});
		const file = event.dataTransfer.files[0];
		if (file) this.addFile(file);
	}

	private async addFile(file: File) {
		const iFile: IFile = {
			file: file,
			fileName: file.name,
			index: this.index++,
		};
		const tmpArray: IFile[] = this.state.currentFiles || [];
		tmpArray.push(iFile);
		this.setState({
			currentFiles: tmpArray,
		});
		// const formData = new FormData();
		// formData.append("file", file, file.name);
		// const query = JSON.stringify({ document: { uid: this.props.document.uid } });
		// formData.append("q", query);

		// const newFile = await Files.getInstance().post(formData);
		// const newFile: FileCustomer = {
		// 	file_name: file.name,
		// }
		// const files = this.state.currentFiles ? [...this.state.currentFiles, newFile] : [newFile];

		// this.setState({
		// 	currentFiles: files,
		// 	loading: false,
		// 	files: [
		// 		...this.state.files,
		// 		{
		// 			index: this.index++,
		// 			file: file,
		// 			uid: newFile.uid!,
		// 			archived: null,
		// 			fileName: newFile?.file_name ?? "",
		// 		},
		// 	],
		// });

		// if (this.props.onChange) this.props.onChange(this.state.files.map((file) => file.file));
	}

	private async removeFile(e: any) {
		const image = e.target as HTMLElement;
		const indexToRemove = image.getAttribute("data-file");

		if (!indexToRemove) return;
		const file = this.state.currentFiles!.find((file) => file.index === parseInt(indexToRemove));
		if (!file) return;
		this.setState({
			currentFiles: this.state.currentFiles!.filter((file) => file.index !== parseInt(indexToRemove)),
		});

		if (this.props.onChange) this.props.onChange(this.state.currentFiles!.map((file) => file.file));
	}

	private async onFileChange() {
		if (!this.inputRef.current) return;

		const files = this.inputRef.current.files;

		if (!files) {
			return;
		}
		const file = files[0];

		if (file) this.addFile(file);
	}

	private addDocument() {
		if (!this.inputRef.current) return;
		this.inputRef.current.click();
	}

	// private formatDate(date: Date) {
	// 	const dateToConvert = new Date(date);
	// 	return dateToConvert.toLocaleDateString("fr-FR");
	// }
}
