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

import Button, { EButtonVariant } from "../Button";
import Tooltip from "../ToolTip";
import Typography, { ITypo, ITypoColor } from "../Typography";
import classes from "./classes.module.scss";
import { File as FileCustomer } from "le-coffre-resources/dist/Customer";

type IProps = {
	title: string;
	dateAsked: Date;
	defaultFiles?: FileCustomer[];
	onChange?: (files: File[]) => void;
};

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

type IState = {
	files: IFile[];
	isDragOver: boolean;
};

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

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

		this.state = {
			files: [],
			isDragOver: false,
		};

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

	public override render(): JSX.Element {
		return (
			<div
				className={classes["root"]}
				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={ITypo.P_SB_16} color={ITypoColor.BLACK} className={classes["title"]}>
							{this.props.title} <Tooltip text={"Blabla"} />
						</Typography>
						<Typography typo={ITypo.CAPTION_14} color={ITypoColor.GREY}>
							Demandé par le notaire le {this.formatDate(this.props.dateAsked)}
						</Typography>
					</div>
				</div>
				{this.state.files.length > 0 && (
					<div className={classes["documents-container"]}>
						{this.state.files.map((file) => {
							const fileObj = file.file;
							return (
								<div className={classes["file-container"]} key={fileObj.name + file.index}>
									<div className={classes["left-part"]}>
										<Image src={DocumentCheckIcon} alt="Document check" />
										<Typography typo={ITypo.P_16} color={ITypoColor.GREY}>
											{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.LINE} className={classes["add-button"]} onClick={this.addDocument}>
						<Typography typo={ITypo.P_SB_16} color={ITypoColor.PINK_FLASH} className={classes["add-document"]}>
							Ajouter un document <Image src={PlusIcon} alt="Plus icon" />
						</Typography>
					</Button>
				</div>
			</div>
		);
	}

	public override componentDidMount(): void {
		if (this.props.defaultFiles) {
			this.setState({
				files: this.props.defaultFiles.map((file) => ({
					index: this.index++,
					file: new File([""], file.file_path, {}),
				})),
			});
		}
	}

    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 addFile(file: File) {
		this.setState({
			files: [
				...this.state.files,
				{
					index: this.index++,
					file: file,
				},
			],
		});

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

	private removeFile(e: any) {
		const image = e.target as HTMLElement;
		const indexToRemove = image.getAttribute("data-file");
		if (!indexToRemove) return;
		this.setState({
			files: this.state.files.filter((file) => file.index !== parseInt(indexToRemove)),
		});

		if (this.props.onChange) this.props.onChange(this.state.files.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) {
		return date.toLocaleDateString("fr-FR");
	}
}
