import PlusIcon from "@Assets/Icons/plus.svg";
import Documents from "@Front/Api/LeCoffreApi/Notary/Documents/Documents";
import Folders from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
import Button, { EButtonStyleType, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
import Form from "@Front/Components/DesignSystem/Form";
import { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import BackArrow from "@Front/Components/Elements/BackArrow";
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
import Module from "@Front/Config/Module";
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
import { NextRouter, useRouter } from "next/router";
import React from "react";

import BasePage from "../../Base";
import classes from "./classes.module.scss";
import ParameterDocuments from "./ParameterDocuments";

type IProps = {};
type IPropsClass = IProps & {
	router: NextRouter;
	folderUid: string;
	customerUid: string;
};
type IState = {
	isCreateDocumentModalVisible: boolean;
	documentTypes: IOption[];
	folder: OfficeFolder | null;
};

class AskDocumentsClass extends BasePage<IPropsClass, IState> {
	public constructor(props: IPropsClass) {
		super(props);

		this.state = {
			isCreateDocumentModalVisible: false,
			documentTypes: [],
			folder: null,
		};

		this.onFormSubmit = this.onFormSubmit.bind(this);
		this.closeModal = this.closeModal.bind(this);
		this.openModal = this.openModal.bind(this);
	}

	public override render(): JSX.Element {
		const backUrl = Module.getInstance()
			.get()
			.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid);

		return (
			<DefaultNotaryDashboard title={"Demander des documents"} onSelectedFolder={() => {}}>
				<div className={classes["root"]}>
					<BackArrow url={backUrl} />
					<Typography typo={ITypo.DISPLAY_LARGE} color={ITypoColor.COLOR_GENERIC_BLACK} className={classes["title"]}>
						Demander des documents
					</Typography>
					<Form onSubmit={this.onFormSubmit}>
						<div className={classes["form-container"]}>
							<div className={classes["checkbox-container"]}>
								{this.state.documentTypes.map((documentType) => {
									if (documentType.description && documentType.description.length > 1) {
										return (
											<CheckBox
												name="document_types"
												toolTip={documentType.description}
												option={documentType}
												key={documentType.value as string}
											/>
										);
									}
									return <CheckBox name="document_types" option={documentType} key={documentType.value as string} />;
								})}
							</div>
							<div className={classes["add-document-container"]}>
								<Button
									icon={PlusIcon}
									iconposition={"right"}
									iconstyle={{ transform: "rotate(180deg)", width: "22px", height: "22px" }}
									variant={EButtonVariant.PRIMARY}
									styleType={EButtonStyleType.TEXT}
									onClick={this.openModal}>
									Ajouter un document
								</Button>
							</div>
							<div className={classes["buttons-container"]}>
								<a href={backUrl}>
									<Button variant={EButtonVariant.PRIMARY} styleType={EButtonStyleType.OUTLINED} onClick={this.cancel}>
										Annuler
									</Button>
								</a>
								<Button type="submit">Valider</Button>
							</div>
						</div>
					</Form>
				</div>
				{this.state.folder && (
					<ParameterDocuments
						folder={this.state.folder}
						closeModal={this.closeModal}
						isCreateDocumentModalVisible={this.state.isCreateDocumentModalVisible}
					/>
				)}
			</DefaultNotaryDashboard>
		);
	}

	public override async componentDidMount(): Promise<void> {
		this.loadData();
	}

	private cancel() {}

	private async loadData() {
		try {
			const folder = await Folders.getInstance().getByUid(this.props.folderUid, {
				q: {
					deed: {
						include: {
							document_types: true,
						},
					},
					office: true,
					documents: {
						include: {
							depositor: true,
							document_type: true,
						},
					},
				},
			});
			if (!folder) return;
			this.setState({
				folder,
				documentTypes: await this.getAvailableDocuments(folder),
			});
		} catch (e) {
			console.error(e);
		}
	}

	private async getAvailableDocuments(folder: OfficeFolder): Promise<IOption[]> {
		// Getting already asked documents UIDs in an array
		const userDocumentTypesUids = folder
			.documents!.filter((document) => document.depositor!.uid! === this.props.customerUid!)
			.map((document) => {
				return document.document_type!.uid!;
			});

		// If those UIDs are already asked, filter them to not show them in the list and only
		// show the documents that are not asked yet
		const documentTypes = folder.deed!.document_types!.filter((documentType) => {
			if (userDocumentTypesUids.includes(documentType!.uid!)) return false;
			return true;
		});

		// If there is none document type available, return an empty array
		if (!documentTypes) return [];

		// Else, return an array document types formatted as IOPtions
		const documentTypesOptions: IOption[] = documentTypes.map((documentType) => {
			return {
				label: documentType!.name!,
				value: documentType!.uid!,
				description: documentType!.private_description!,
			};
		});

		documentTypesOptions.sort((a, b) => (a.label > b.label ? 1 : -1));

		return documentTypesOptions;
	}

	private openModal() {
		this.setState({
			isCreateDocumentModalVisible: true,
		});
	}

	private closeModal() {
		this.loadData();
		this.setState({
			isCreateDocumentModalVisible: false,
		});
	}

	private async onFormSubmit(
		e: React.FormEvent<HTMLFormElement> | null,
		values: {
			[key: string]: any;
		},
	) {
		try {
			const documentAsked: [] = values["document_types"] as [];
			for (let i = 0; i < documentAsked.length; i++) {
				await Documents.getInstance().post({
					folder: {
						uid: this.props.folderUid,
					},
					depositor: {
						uid: this.props.customerUid,
					},
					document_type: {
						uid: documentAsked[i],
					},
				});
			}

			this.props.router.push(
				Module.getInstance()
					.get()
					.modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid),
			);
		} catch (e) {
			console.error(e);
		}
	}
}

export default function AskDocuments(props: IProps) {
	const router = useRouter();
	let { folderUid, customerUid } = router.query;
	folderUid = folderUid as string;
	customerUid = customerUid as string;
	return <AskDocumentsClass folderUid={folderUid} customerUid={customerUid} router={router} />;
}
