import "reflect-metadata";

import PlusIcon from "@Assets/Icons/plus.svg";
import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
import Form from "@Front/Components/DesignSystem/Form";
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
import { IOption } from "@Front/Components/DesignSystem/Select";
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import BackArrow from "@Front/Components/Elements/BackArrow";
import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
import { NextRouter, useRouter } from "next/router";
import React from "react";

import BasePage from "../../Base";
import classes from "./classes.module.scss";
import Documents from "@Front/Api/LeCoffreApi/SuperAdmin/Documents/Documents";
import Module from "@Front/Config/Module";
import { OfficeFolder } from "le-coffre-resources/dist/Customer";
import Deeds from "@Front/Api/LeCoffreApi/SuperAdmin/Deeds/Deeds";
import DocumentTypes from "@Front/Api/LeCoffreApi/SuperAdmin/DocumentTypes/DocumentTypes";

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

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

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

		this.onFormSubmit = this.onFormSubmit.bind(this);
		this.closeModal = this.closeModal.bind(this);
		this.openModal = this.openModal.bind(this);
		this.cancel = this.cancel.bind(this);
		this.onVisibleDescriptionChange = this.onVisibleDescriptionChange.bind(this);
		this.onDocumentNameChange = this.onDocumentNameChange.bind(this);
		this.addDocument = this.addDocument.bind(this);
		this.canAddDocument = this.canAddDocument.bind(this);
	}

	public override render(): JSX.Element {
		return (
			<DefaultNotaryDashboard title={"Demander des documents"} onSelectedFolder={() => {}}>
				<div className={classes["root"]}>
					<BackArrow />
					<Typography typo={ITypo.H1} color={ITypoColor.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) => (
									<CheckBox name="document_types" toolTip="Checkbox with tooltip" 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.LINE}
									onClick={this.openModal}>
									Ajouter un document
								</Button>
							</div>
							<div className={classes["buttons-container"]}>
								<Button variant={EButtonVariant.GHOST} onClick={this.cancel}>
									Annuler
								</Button>
								<Button type="submit">Valider</Button>
							</div>
						</div>
					</Form>
					<Confirm
						isOpen={this.state.isCreateDocumentModalVisible}
						onClose={this.closeModal}
						onAccept={this.addDocument}
						canConfirm={this.canAddDocument()}
						closeBtn
						header={"Créer un type de document"}
						cancelText={"Annuler"}
						confirmText={"Ajouter"}>
						<div className={classes["add-document-form-container"]}>
							<InputField
								name="document_name"
								fakeplaceholder="Nom du document à ajouter"
								type="text"
								onChange={this.onDocumentNameChange}
							/>
							<InputField
								name="description"
								fakeplaceholder="Description visible par le client"
								type="text"
								textarea
								onChange={this.onVisibleDescriptionChange}
							/>
						</div>
					</Confirm>
				</div>
			</DefaultNotaryDashboard>
		);
	}

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

	private async loadData(){
		try{
			const folder = await Folders.getInstance().getByUid(this.props.folderUid, {
				q:{
					deed: {
						include: {
							deed_has_document_types: {
								include: {
									document_type: true
								}
							}
						}
					},
					office: true
				}
			});
			if(!folder) return;
			this.setState({
				folder,
				documentTypes: await this.getAvailableDocuments(folder),
			});
		}catch(e){
			console.error(e);
		}
	}
	
	private async getAvailableDocuments(folder: OfficeFolder): Promise<IOption[]>{
		const documentTypes = await Deeds.getInstance().getByUid(folder.deed!.uid!, {
			q: {
					deed_has_document_types: {
						include: {
							document_type: true
						}
					}
				}
		})

		if(!documentTypes) return [];
		
		const documentTypesOptions: IOption[] = documentTypes.deed_has_document_types!.map((documentType) => {
			return {
				label: documentType.document_type!.name!,
				value: documentType.document_type!.uid!,
			};
		});

		return documentTypesOptions

	}

	private canAddDocument() {
		if (this.state.documentName === "" || this.state.visibleDescription === "") {
			return false;
		}
		return true;
	}

	private async addDocument() {
		try{
			const documentType = await DocumentTypes.getInstance().post({
				name: this.state.documentName,
				private_description: this.state.visibleDescription,
				office: {
					uid: this.state.folder?.office!.uid!
				},
				public_description: this.state.visibleDescription
			})

			const oldDocumentsType = this.state.folder?.deed?.deed_has_document_types!;
			const deed = await Deeds.getInstance().put(this.state.folder?.deed?.uid!,{
				deed_has_document_types: [
					...oldDocumentsType,
					{
						document_type: documentType,
					}
				]
			});

			console.log("Deed : ", deed);
			await this.loadData();
			this.setState({
				isCreateDocumentModalVisible: false,
				documentName: "",
				visibleDescription: "",
			});
		}catch(e){
			console.error(e);
		}
	}

	private onVisibleDescriptionChange(e: React.ChangeEvent<HTMLInputElement>) {
		this.setState({
			visibleDescription: e.target.value,
		});
	}

	private onDocumentNameChange(e: React.ChangeEvent<HTMLInputElement>) {
		this.setState({
			documentName: e.target.value,
		});
	}

	private cancel() {
		this.setState({
			visibleDescription: "",
			documentName: "",
		});
	}

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

	private closeModal() {
		this.setState({
			isCreateDocumentModalVisible: false,
			visibleDescription: "",
			documentName: "",
		});
	}

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

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