import Module from "@Front/Config/Module";
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
import { EDocumentStatus } from "le-coffre-resources/dist/Notary/Document";
import Link from "next/link";
import { NextRouter, useRouter } from "next/router";
import React from "react";

import BlockList, { IBlock } from "../BlockList";
import Button from "../Button";
import SearchBar from "../SearchBar";
import classes from "./classes.module.scss";
import Rules, { RulesMode } from "@Front/Components/Elements/Rules";
import { AppRuleActions, AppRuleNames } from "@Front/Api/Entities/rule";

type IProps = {
	folders: OfficeFolder[];
	isArchived: boolean;
	onSelectedFolder?: (folder: OfficeFolder) => void;
	onCloseLeftSide?: () => void;
};

type IPropsClass = IProps & {
	router: NextRouter;
	selectedFolder: string;
};

type IState = {
	filteredFolders: OfficeFolder[];
	blocks: IBlock[];
};

class FolderListContainerClass extends React.Component<IPropsClass, IState> {
	private redirectPath: string = this.props.isArchived
		? Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.pages.FolderInformation.props.path
		: Module.getInstance().get().modules.pages.Folder.pages.FolderInformation.props.path;
	public constructor(props: IPropsClass) {
		super(props);
		this.state = {
			filteredFolders: this.props.folders,
			blocks: this.getBlocks(this.props.folders),
		};
		this.filterFolders = this.filterFolders.bind(this);
		this.onSelectedFolder = this.onSelectedFolder.bind(this);
	}

	public override render(): JSX.Element {
		const navigatePath = Module.getInstance().get().modules.pages.Folder.pages.CreateFolder.props.path;
		return (
			<div className={classes["root"]}>
				<div className={classes["header"]}>
					<div className={classes["searchbar"]}>
						<SearchBar onChange={this.filterFolders} placeholder="Chercher un dossier" />
					</div>
					<div className={classes["folderlist-container"]}>
						<BlockList blocks={this.state.blocks} onSelectedBlock={this.onSelectedFolder} />
					</div>
				</div>
				{!this.props.isArchived && (
					<div>
						<Rules
							mode={RulesMode.NECESSARY}
							rules={[
								{
									action: AppRuleActions.create,
									name: AppRuleNames.officeFolders,
								},
							]}>
							<Link href={navigatePath}>
								<Button fullwidth={true}>Créer un dossier</Button>
							</Link>
						</Rules>
					</div>
				)}
			</div>
		);
	}

	public override componentDidUpdate(prevProps: Readonly<IPropsClass>, prevState: Readonly<IState>, snapshot?: any): void {
		if (prevProps.selectedFolder !== this.props.selectedFolder) {
			this.setState({ filteredFolders: this.props.folders, blocks: this.getBlocks(this.props.folders) });
		}
	}
	private getBlocks(folders: OfficeFolder[]): IBlock[] {
		const pendingFolders = folders
			.filter((folder) => {
				const pendingDocuments = (folder.documents ?? []).filter(
					(document) => document.document_status === EDocumentStatus.DEPOSITED,
				);
				return pendingDocuments.length >= 1;
			})
			.sort((folder1, folder2) => {
				return folder1.created_at! > folder2.created_at! ? -1 : 1;
			});

		const otherFolders = folders
			.filter((folder) => {
				const pendingDocuments = (folder.documents ?? []).filter(
					(document) => document.document_status === EDocumentStatus.DEPOSITED,
				);
				return pendingDocuments.length === 0;
			})
			.sort((folder1, folder2) => {
				return folder1.created_at! > folder2.created_at! ? -1 : 1;
			});

		return [...pendingFolders, ...otherFolders].map((folder) => {
			return {
				id: folder.uid!,
				name: folder.folder_number! + " - " + folder.name!,
				selected: this.props.selectedFolder === folder.uid,
			};
		});
	}

	private onSelectedFolder(block: IBlock) {
		const folder = this.props.folders.find((folder) => folder.uid === block.id);
		if (!folder) return;
		this.props.onSelectedFolder && this.props.onSelectedFolder(folder);
		const path = this.redirectPath.replace("[folderUid]", folder.uid ?? "");
		this.props.router.push(path);
	}

	private filterFolders(value: string): void {
		const filteredFolders: OfficeFolder[] = this.props.folders.filter((folder) => {
			const name = folder.name.toLowerCase();
			const number = folder.folder_number.toLowerCase();
			value = value.toLowerCase();
			if (folder.customers) {
				const customerNames = folder.customers
					.map((customer) => {
						return `${customer.contact?.first_name.toLowerCase()} ${customer.contact?.last_name.toLowerCase()}`;
					})
					.join(", ");

				return name.includes(value) || number.includes(value) || customerNames.includes(value);
			}

			return name.includes(value) || number.includes(value);
		});

		this.setState({ filteredFolders, blocks: this.getBlocks(filteredFolders) });
	}
}

export default function FolderListContainer(props: IProps) {
	const router = useRouter();
	const { folderUid } = router.query;
	return <FolderListContainerClass {...props} router={router} selectedFolder={folderUid as string} />;
}
