import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
import { connect } from "react-redux";

import {
	BackFolder,
	Button,
	EmptyState,
	ErrorToast,
	FilterTagsBar,
	Icon,
	IconAction,
	Loading,
	MainWrapper,
	Modal,
	SearchField,
	SearchTagsBar,
	TableList,
	Tabs,
	Toast,
	Tooltip,
} from "@ax/components";
import { VALID_FILE_FORMATS } from "@ax/constants";
import { fileDriveActions } from "@ax/containers/FileDrive";
import { useBulkSelection, useIsDirty, useModal, usePermission, useResizable, useToast } from "@ax/hooks";
import type {
	IBulkAction,
	IFile,
	IFilesFolder,
	IFolder,
	IFolderTree,
	IGetFolderParams,
	IQueryValue,
	IRootState,
} from "@ax/types";

import { DeleteFileModal, MoveItemModal, NewFolderModal, NotSavedModal } from "./atoms";
import Breadcrumb from "./Breadcrumb";
import BulkGridHeader from "./BulkGridHeader";
import BulkListHeader from "./BulkListHeader";
import FileDragAndDrop from "./FileDragAndDrop";
import SortBy from "./FileFilters/SortBy";
import Type from "./FileFilters/Type";
import FileModal from "./FileModal";
import FolderItem from "./FolderItem";
import FolderTree from "./FolderTree";
import GridItem from "./GridItem";
import { useFilterQuery, useSortedListStatus } from "./hooks";
import ListItem from "./ListItem";
import UploadItem from "./UploadItem";
import { getSortedListStatus } from "./utils";

import * as S from "./style";

const FileDrive = (props: IProps) => {
	const {
		currentFolderContent,
		currentFolderID,
		currentSiteID,
		getFolderContent,
		getFoldersTree,
		updateCurrentFolder,
		createNewFolder,
		deleteFolder,
		deleteFile,
		moveFile,
		updateDisplayMode,
		updateTab,
		downloadFiles,
		uploadFile,
		breadcrumb,
		isLoading,
		isSaving,
		displayMode,
		selectedTab,
	} = props;

	const {
		files: { totalItems, items },
		folders,
	} = currentFolderContent || { files: { totalItems: 0, items: [] }, folders: [] };

	const [isBulkLoading, setIsBulkLoading] = useState(false);
	const [isPanelOpen, setPanelOpen] = useState(false);
	const [fileSelected, setFileSelected] = useState<IFile | null>(null);
	const [selectedFolder, setSelectedFolder] = useState<number>(currentFolderID || 0);
	const filesIds: number[] = items.map((file) => file.id) || [];
	const [galleryItems, setGalleryItems] = useState<number[]>(filesIds);
	const [galleryDelete, setGalleryDelete] = useState(true);
	const [numDocs, setNumDocs] = useState(1);
	const [progressItems, setProgressItems] = useState<number[]>([]);
	const [wrapperWidth, setWrapperWidth] = useState<number>();
	const tableRef = useRef<HTMLDivElement>(null);
	const wrapperRef = useRef<HTMLDivElement>(null);
	const { isOpen: isNewOpen, toggleModal: toggleNewModal } = useModal();
	const { isOpen: isUploadOpen, toggleModal: toggleUploadModal } = useModal();
	const { isOpen: isDeleteOpen, toggleModal: toggleDeleteModal } = useModal();
	const { isOpen: isMoveOpen, toggleModal: toggleMoveModal } = useModal();
	const { isOpen: isSaveOpen, toggleModal: toggleSaveModal } = useModal();
	const { isOpen, toggleModal } = useModal();
	const { isVisible, toggleToast, setIsVisible } = useToast();
	const { isVisible: isNewVisible, toggleToast: toggleNewToast, setIsVisible: setIsNewVisible } = useToast();
	const { isVisible: isDeleteVisible, toggleToast: toggleDeleteToast, setIsVisible: setIsDeleteVisible } = useToast();
	const { isVisible: isMoveVisible, toggleToast: toggleMoveToast, setIsVisible: setIsMoveVisible } = useToast();
	const {
		isVisible: isMoveFolderVisible,
		toggleToast: toggleMoveFolderToast,
		setIsVisible: setIsMoveFolderVisible,
	} = useToast();

	const [ref] = useResizable();

	const initFolderState = { name: "", folderID: currentFolderID };
	const [folderForm, setFolderForm] = useState<IFolderFormState>(initFolderState);
	const { setFiltersSelection, resetFilterQuery, filterValues, filterQuery } = useFilterQuery();
	const { sortedListStatus, setSortedListStatus } = useSortedListStatus();
	const [searchQuery, setSearchQuery] = useState<string>("");
	const isSearching = searchQuery.length > 0;

	const initFileState: IFileFormState = { title: "", alt: "", tags: [] };
	const [fileForm, setFileForm] = useState(initFileState);
	const { isDirty, resetDirty } = useIsDirty(fileForm);

	const isSiteView = !!currentSiteID;
	const isTabGlobal = selectedTab === "global";
	const siteID: number | "global" = !isSiteView || isTabGlobal ? "global" : currentSiteID;
	const hasFolders = !!folders.length;
	const isRoot = !breadcrumb.length;
	const isGrid = displayMode === "grid";

	const allowedToAccessGlobalFromSite = usePermission("mediaGallery.accessToGlobalFileDriveFromSite");

	const allowedToAddSiteFile = usePermission("mediaGallery.addFiles");
	const allowedToAddGlobalFile = usePermission("global.mediaGallery.addGlobalFiles");
	const allowedToAddGlobalFileFromSite = usePermission("mediaGallery.addGlobalFilesFromSite");
	const allowedToAddFile = !isSiteView
		? allowedToAddGlobalFile
		: isTabGlobal
			? allowedToAddGlobalFileFromSite
			: allowedToAddSiteFile;

	const allowedToEditSiteFile = usePermission("mediaGallery.editFiles");
	const allowedToEditGlobalFile = usePermission("global.mediaGallery.editGlobalFiles");
	const allowedToEditGlobalFileFromSite = usePermission("mediaGallery.editGlobalFilesInSite");
	const allowedToEditFile = !isSiteView
		? allowedToEditGlobalFile
		: isTabGlobal
			? allowedToEditGlobalFileFromSite
			: allowedToEditSiteFile;

	const allowedToDeleteSiteFile = usePermission("mediaGallery.deleteFiles");
	const allowedToDeleteGlobalFile = usePermission("global.mediaGallery.deleteGlobalFiles");
	const allowedToDeleteGlobalFileFromSite = usePermission("mediaGallery.deleteGlobalFilesInSite");
	const allowedToDeleteFile = !isSiteView
		? allowedToDeleteGlobalFile
		: isTabGlobal
			? allowedToDeleteGlobalFileFromSite
			: allowedToDeleteSiteFile;

	const getParams = useCallback(() => {
		const params = {
			siteID,
			folderID: currentFolderID,
			search: searchQuery,
			query: filterQuery,
			loading: true,
		};

		return params;
	}, [currentFolderID, searchQuery, filterQuery, siteID]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useLayoutEffect(() => {
		return () => {
			updateCurrentFolder(null);
			updateTab("site");
		};
	}, []);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		const handleGetContent = async () => {
			const params = getParams();
			await getFolderContent(params);
		};
		const handleGetTree = async () => await getFoldersTree(siteID);
		handleGetTree();
		handleGetContent();
	}, [getParams, selectedTab]);

	useEffect(() => {
		const filesIds = items.map((file) => file.id) || [];
		setGalleryItems(filesIds);
	}, [items]);

	// biome-ignore lint/correctness/useExhaustiveDependencies: TODO: fix this
	useEffect(() => {
		const handleResize = () => {
			if (wrapperRef.current) {
				setWrapperWidth(wrapperRef.current.offsetWidth);
			}
		};
		handleResize();

		window.addEventListener("resize", handleResize);
		return () => window.removeEventListener("resize", handleResize);
	}, [wrapperRef.current]);

	const {
		resetBulkSelection,
		selectedItems,
		isSelected,
		areItemsSelected,
		checkState,
		addToBulkSelection,
		selectAllItems,
		setHoverCheck,
	} = useBulkSelection(filesIds);

	const handleSelectedTab = (tab: "site" | "global") => {
		if (tab !== selectedTab) {
			setSearchQuery("");
			updateCurrentFolder(null);
			updateTab(tab);
		}
	};

	const handleNewFolder = () => {
		setFolderForm(initFolderState);
		!isNewOpen && toggleNewModal();
	};

	const changeDisplayMode = (mode: "grid" | "list") => updateDisplayMode(mode);

	const selectItems = () => (checkState.isAllSelected ? resetBulkSelection() : selectAllItems());

	const handleBackClick = () => {
		const parentID = breadcrumb.length >= 2 ? breadcrumb[breadcrumb.length - 2].id : null;
		updateCurrentFolder(parentID);
	};

	const togglePanel = () => setPanelOpen(!isPanelOpen);

	const handleCreateNewFolder = async () => {
		const isCreated = await createNewFolder({
			site: siteID,
			folderName: folderForm.name,
			parentId: folderForm.folderID || undefined,
		});
		if (isCreated) {
			isNewOpen && toggleNewModal();
			toggleNewToast();
		}
	};

	const handleDeleteFolder = async (folder: IFolder) => {
		const isDeleted = await deleteFolder(folder);
		if (isDeleted) {
			toggleToast();
		}
	};

	const handleClick = (file: IFile) => {
		setFileSelected(file);
		toggleModal();
	};

	const handleUpload = async (files: IFile[]) => {
		setFileSelected(files[0]);
		isUploadOpen && toggleUploadModal();
		toggleModal();
		const params = getParams();
		await getFolderContent(params);
	};

	const uploadMultipleFiles = async (files: File[]) => {
		try {
			let index = 0;
			while (files.length) {
				const handleProgress = (progress: number) => {
					setProgressItems((prevState) => [...prevState.slice(0, index), progress, ...prevState.slice(index + 1)]);
				};

				const file = files.shift();
				file && (await uploadFile(file, currentFolderID, siteID || "global", handleProgress));
				index = index + 1;
			}
		} catch (error) {
			console.log(error);
		}
	};

	const handleMultipleUpload = async (files: File[]) => {
		isUploadOpen && toggleUploadModal();

		const initialProgress = files.map(() => 0);
		setProgressItems(initialProgress);

		await uploadMultipleFiles(files);

		setProgressItems([]);
		const params = getParams();
		await getFolderContent(params);
	};

	const handleCloseModal = () => {
		if (isDirty) {
			toggleSaveModal();
		} else {
			resetFileModal();
		}
	};

	const resetFileModal = () => {
		setFileSelected(null);
		setGalleryItems(filesIds);
		setGalleryDelete(true);
		resetDirty();
		toggleModal();
	};

	const handleDeleteFile = async (fileID: number) => {
		const isDeleted = await deleteFile(fileID, siteID);
		if (isDeleted) {
			setNumDocs(1);
			toggleDeleteToast();
		}
	};

	const handleBulkDeleteFile = async () => {
		setIsBulkLoading(true);
		const isDeleted = await deleteFile(selectedItems.all, siteID);
		if (isDeleted) {
			setNumDocs(selectedItems.all.length);
			toggleDeleteModal();
			toggleDeleteToast();
			resetBulkSelection();
		}
		setIsBulkLoading(false);
	};

	const handleMoveFile = async (fileID: number, folderID: number) => {
		const isMoved = await moveFile(fileID, folderID, siteID);
		if (isMoved) {
			setNumDocs(1);
			toggleMoveToast();
		}
	};

	const handleBulkMoveFile = async () => {
		setIsBulkLoading(true);
		const isMoved = await moveFile(selectedItems.all, selectedFolder, siteID);
		if (isMoved) {
			setNumDocs(selectedItems.all.length);
			toggleMoveModal();
			toggleMoveToast();
			setSelectedFolder(0);
			resetBulkSelection();
		}
		setIsBulkLoading(false);
	};

	const handleBulkEditFile = () => {
		const currentFile = items.find((file: IFile) => file.id === selectedItems.all[0]);
		if (currentFile) {
			setGalleryItems(selectedItems.all);
			setFileSelected(currentFile);
			setGalleryDelete(false);
			toggleModal();
		}
	};

	const handleModalClose = () => {
		setSelectedFolder(0);
		isMoveOpen && toggleMoveModal();
	};

	const handleSelectFile = (id: number) => {
		const currentFile = items.find((file: IFile) => file.id === id);
		if (currentFile) {
			setFileSelected(currentFile);
		}
	};

	const handleDownloadBulk = async () => {
		setIsBulkLoading(true);
		await downloadFiles(selectedItems.all, true);
		resetBulkSelection();
		setIsBulkLoading(false);
	};

	const handleUpdateCurrentFolder = (folderID: number | null) => {
		setSearchQuery("");
		updateCurrentFolder(folderID);
	};

	const handleDownload = async (fileID: number, fileName: string) => await downloadFiles(fileID, false, fileName);

	const sortItems = (orderPointer: IQueryValue[], isAscending: boolean) => {
		const sortedState = getSortedListStatus(orderPointer[0].value.toString(), isAscending);
		setSortedListStatus(sortedState);
		setFiltersSelection("order", orderPointer, isAscending);
	};

	const filterItems = (filterPointer: string, filtersSelected: IQueryValue[]) =>
		setFiltersSelection(filterPointer, filtersSelected);

	let bulkActions: IBulkAction[] = [];

	if (allowedToEditFile) {
		bulkActions = [
			{
				icon: "edit",
				text: "edit",
				action: handleBulkEditFile,
			},
			{
				icon: "change",
				text: "Move to",
				action: toggleMoveModal,
			},
		];
	}

	bulkActions = [
		...bulkActions,
		{
			icon: "download",
			text: "download",
			action: handleDownloadBulk,
		},
	];

	if (allowedToDeleteFile) {
		bulkActions = [
			...bulkActions,
			{
				icon: "delete",
				text: "delete",
				action: toggleDeleteModal,
			},
		];
	}

	const Header = (
		<BulkListHeader
			showBulk={areItemsSelected(filesIds)}
			checkState={checkState}
			selectAllItems={selectItems}
			totalItems={totalItems}
			selectItems={selectItems}
			bulkActions={bulkActions}
			isSearching={isSearching}
			setHoverCheck={setHoverCheck}
			selectedItems={selectedItems}
			isLoading={isBulkLoading}
		/>
	);

	const gridList = (
		<S.GridWrapper isSearching={isSearching}>
			{progressItems.map((progress: number, index: number) => (
				<UploadItem uploadPercentage={progress} grid={true} key={index} />
			))}
			{items.map((file: IFile) => {
				const isItemSelected = isSelected(file.id);
				return (
					<GridItem
						file={file}
						isSelected={isItemSelected}
						onChange={addToBulkSelection}
						key={`${file.fileName}${file.id}`}
						onClick={handleClick}
						onDelete={handleDeleteFile}
						onMove={handleMoveFile}
						currentFolderID={currentFolderID}
						isAllowedToDelete={allowedToDeleteFile}
						isAllowedToEdit={allowedToEditFile}
						isAllowedToMove={!isRoot || (isRoot && (folders.length > 0 || isSearching))}
						isSearching={isSearching}
					/>
				);
			})}
		</S.GridWrapper>
	);

	const listTable = (
		<TableList tableHeader={Header} hasFixedHeader={true} tableRef={tableRef} className="no-padding">
			<>
				{progressItems.map((progress: number, index: number) => (
					<UploadItem uploadPercentage={progress} grid={false} key={index} />
				))}
				{items.map((file: IFile) => {
					const isItemSelected = isSelected(file.id);
					return (
						<ListItem
							file={file}
							isSelected={isItemSelected}
							onChange={addToBulkSelection}
							key={`${file.fileName}${file.id}`}
							onClick={handleClick}
							onDelete={handleDeleteFile}
							onMove={handleMoveFile}
							currentFolderID={currentFolderID}
							isAllowedToDelete={allowedToDeleteFile}
							isAllowedToEdit={allowedToEditFile}
							isAllowedToMove={!isRoot || (isRoot && (folders.length > 0 || isSearching))}
							isSearching={isSearching}
							hoverCheck={checkState.hoverCheck}
						/>
					);
				})}
			</>
		</TableList>
	);

	const toastDeleteFolderProps = {
		setIsVisible,
		message: "1 folder deleted",
	};

	const toastNewProps = {
		setIsVisible: setIsNewVisible,
		message: "1 new folder created",
	};

	const toastDeleteFileProps = {
		setIsVisible: setIsDeleteVisible,
		message: `${numDocs} Document${numDocs > 1 ? "s" : ""} deleted`,
	};

	const toastMoveFileProps = {
		setIsVisible: setIsMoveVisible,
		message: `${numDocs} Document${numDocs > 1 ? "s" : ""} moved to a folder`,
	};

	const toastMoveFolderProps = {
		setIsVisible: setIsMoveFolderVisible,
		message: "1 Folder moved to another folder",
	};

	const rightButtonProps = allowedToAddFile
		? {
				label: "Upload",
				action: () => toggleUploadModal(),
			}
		: undefined;

	const emptyProps = {
		message: allowedToAddFile ? "To start using files in your site, upload as many documents as you need" : "",
		button: allowedToAddFile ? "Upload file" : undefined,
		action: () => toggleUploadModal(),
	};

	const emptySearchStateProps = {
		icon: "search",
		title: "Oh! No Results Found",
		message: "We couldn’t find what you are looking for. Please, try another search.",
	};

	const mainNewModalAction = {
		title: isSaving ? "Saving..." : "Create New Folder",
		onClick: () => handleCreateNewFolder(),
		disabled: folderForm.name.trim().length === 0 || isSaving,
	};

	const secondaryNewModalAction = { title: "Cancel", onClick: toggleNewModal };

	const mainDeleteModalAction = {
		title: isBulkLoading ? "Deleting" : "Delete",
		onClick: () => handleBulkDeleteFile(),
		disabled: isBulkLoading,
	};

	const secondaryDeleteModalAction = { title: "Cancel", onClick: toggleDeleteModal };

	const mainMoveModalAction = {
		title: "Move",
		onClick: () => handleBulkMoveFile(),
	};

	const secondaryMoveModalAction = { title: "Cancel", onClick: handleModalClose };

	const handleMainAction = () => {
		toggleSaveModal();
		resetFileModal();
	};

	const mainSaveModalAction = {
		title: "Yes, discard changes",
		onClick: () => handleMainAction(),
	};

	const secondarySaveModalAction = { title: "Cancel", onClick: toggleSaveModal };

	const foldersIcon = isPanelOpen ? <Icon name="closePanel" size="24" /> : <Icon name="openPanel" size="24" />;

	const tabs = ["site", "global"];

	const NewFolderButton = () =>
		allowedToAddFile ? (
			<S.ButtonWrapper>
				<Button type="button" onClick={handleNewFolder} buttonStyle="line" icon="NewFolder">
					New Folder
				</Button>
			</S.ButtonWrapper>
		) : (
			<></>
		);

	const filters = (
		<S.Filters>
			<Type filterItems={filterItems} value={filterValues.filterType} />
			<SortBy sortItems={sortItems} sortedState={sortedListStatus} />
		</S.Filters>
	);

	return (
		<MainWrapper backLink={false} title="File Drive Manager" rightButton={rightButtonProps}>
			<S.Wrapper ref={wrapperRef}>
				<S.FolderPanel
					isOpen={isPanelOpen}
					ref={ref}
					style={{ width: isPanelOpen ? "240px" : "0" }}
					maxWidth={wrapperWidth}
				>
					<S.FolderPanelContent>
						<FolderTree
							folderID={currentFolderID || 0}
							onClick={handleUpdateCurrentFolder}
							title="Folders"
							createAction={allowedToAddFile ? handleNewFolder : undefined}
						/>
					</S.FolderPanelContent>
					<S.ResizeHandle className="resizer" />
				</S.FolderPanel>
				<S.ContentWrapper>
					<ErrorToast />
					<S.FiltersBar isSite={isSiteView && allowedToAccessGlobalFromSite}>
						{isSiteView && allowedToAccessGlobalFromSite && (
							<S.TabsWrapper>
								<Tabs tabs={tabs} active={selectedTab} setSelectedTab={handleSelectedTab} noMargins />
							</S.TabsWrapper>
						)}
						{!isSiteView && filters}
						<S.DisplayModeWrapper>
							<IconAction icon="Grid2" onClick={() => changeDisplayMode("grid")} active={displayMode === "grid"} />
							<IconAction icon="BulletList" onClick={() => changeDisplayMode("list")} active={displayMode === "list"} />
						</S.DisplayModeWrapper>
					</S.FiltersBar>
					<S.FiltersBar isSite={false}>
						{isSiteView && filters}
						<SearchField onChange={setSearchQuery} placeholder="Search" value={searchQuery} focus={false} />
					</S.FiltersBar>
					{isLoading ? (
						<Loading />
					) : (
						<S.FolderContent>
							<S.SearchTags>
								<SearchTagsBar query={searchQuery} setQuery={setSearchQuery} />
								<FilterTagsBar
									filters={filterValues}
									setFilters={setFiltersSelection}
									labels={{ filterType: "Type" }}
									resetFilters={resetFilterQuery}
								/>
							</S.SearchTags>
							{!isRoot && <Breadcrumb breadcrumb={breadcrumb} onClick={handleUpdateCurrentFolder} />}
							{(hasFolders || !isRoot) && (
								<S.SectionWrapper>
									<S.SectionHeader>
										<S.SectionTitle>
											<div>Folders</div>
											<S.FoldersIconWrapper onClick={togglePanel}>
												<Tooltip content="Open folder panel">{foldersIcon}</Tooltip>
											</S.FoldersIconWrapper>
										</S.SectionTitle>
										<NewFolderButton />
									</S.SectionHeader>
									<S.FoldersWrapper>
										{!isRoot && <BackFolder onClick={handleBackClick} />}
										<S.FoldersGrid>
											{folders.map((folder: IFolder) => (
												<FolderItem
													folder={folder}
													onClick={handleUpdateCurrentFolder}
													onDelete={handleDeleteFolder}
													key={`${folder.folderName}${folder.id}`}
													toggleToast={toggleMoveFolderToast}
													isAllowedToDelete={allowedToDeleteFile}
													isAllowedToEdit={allowedToEditFile}
													isAllowedToMove={!isRoot || (isRoot && (folders.length > 1 || isSearching))}
												/>
											))}
										</S.FoldersGrid>
									</S.FoldersWrapper>
								</S.SectionWrapper>
							)}
							<S.BigSectionWrapper>
								<S.SectionHeader>
									{totalItems > 0 && <S.SectionTitle>Documents</S.SectionTitle>}
									{totalItems > 0 && isGrid && (
										<BulkGridHeader
											showBulk={areItemsSelected(filesIds)}
											checkState={checkState}
											selectAllItems={selectItems}
											totalItems={totalItems}
											selectItems={selectItems}
											bulkActions={bulkActions}
											selectedItems={selectedItems}
											isLoading={isBulkLoading}
										/>
									)}
									{!hasFolders && isRoot && !isSearching && <NewFolderButton />}
								</S.SectionHeader>
								<S.DocumentsWrapper>{isGrid ? gridList : listTable}</S.DocumentsWrapper>
								{totalItems === 0 && !hasFolders && (
									<S.EmptyStateWrapper data-testid="empty-state" margin={!isRoot}>
										{isSearching ? <EmptyState {...emptySearchStateProps} /> : <EmptyState {...emptyProps} />}
									</S.EmptyStateWrapper>
								)}
							</S.BigSectionWrapper>
						</S.FolderContent>
					)}
				</S.ContentWrapper>
			</S.Wrapper>
			{isNewOpen && (
				<NewFolderModal
					isOpen={isNewOpen}
					toggleModal={toggleNewModal}
					mainModalAction={mainNewModalAction}
					secondaryModalAction={secondaryNewModalAction}
					form={folderForm}
					setForm={setFolderForm}
				/>
			)}
			<Modal isOpen={isUploadOpen} hide={toggleUploadModal} size="XL" title="Upload file">
				{isUploadOpen && (
					<FileDragAndDrop
						folderID={currentFolderID}
						handleUpload={handleUpload}
						handleMultipleUpload={handleMultipleUpload}
						siteID={siteID}
					/>
				)}
			</Modal>
			<Modal isOpen={isOpen} hide={handleCloseModal} size="XL" title="Document details">
				{isOpen && fileSelected && (
					<FileModal
						file={fileSelected}
						toggleModal={handleCloseModal}
						onDelete={handleDeleteFile}
						items={galleryItems}
						setFile={handleSelectFile}
						activeDelete={galleryDelete && allowedToDeleteFile}
						setFileSelected={setFileSelected}
						isAllowedToEdit={allowedToEditFile}
						handleDownload={handleDownload}
						form={fileForm}
						setForm={setFileForm}
						isDirty={isDirty}
						resetDirty={resetDirty}
					/>
				)}
			</Modal>
			{isDeleteOpen && (
				<DeleteFileModal
					isOpen={isDeleteOpen}
					toggleModal={toggleDeleteModal}
					mainModalAction={mainDeleteModalAction}
					secondaryModalAction={secondaryDeleteModalAction}
					title="these documents"
				/>
			)}
			{isMoveOpen && (
				<MoveItemModal
					isOpen={isMoveOpen}
					toggleModal={handleModalClose}
					mainModalAction={mainMoveModalAction}
					secondaryModalAction={secondaryMoveModalAction}
					folder={selectedFolder}
					setFolder={setSelectedFolder}
				/>
			)}
			{isSaveOpen && (
				<NotSavedModal
					isOpen={isSaveOpen}
					toggleModal={toggleSaveModal}
					mainModalAction={mainSaveModalAction}
					secondaryModalAction={secondarySaveModalAction}
				/>
			)}
			{isVisible && <Toast {...toastDeleteFolderProps} />}
			{isDeleteVisible && <Toast {...toastDeleteFileProps} />}
			{isNewVisible && <Toast {...toastNewProps} />}
			{isMoveVisible && <Toast {...toastMoveFileProps} />}
			{isMoveFolderVisible && <Toast {...toastMoveFolderProps} />}
		</MainWrapper>
	);
};

interface IProps {
	isLoading: boolean;
	isSaving: boolean;
	currentFolderContent: IFilesFolder | null;
	currentFolderID: number | null;
	currentSiteID: number | null;
	breadcrumb: IFolderTree[];
	displayMode: "grid" | "list";
	selectedTab: "site" | "global";
	getFolderContent(params: IGetFolderParams): Promise<void>;
	getFoldersTree(siteID: number | "global"): Promise<void>;
	updateCurrentFolder(folderID: number | null): void;
	createNewFolder(data: { folderName: string; site: number | "global"; parentId?: number }): Promise<boolean>;
	deleteFolder(folder: IFolder): Promise<boolean>;
	deleteFile(fileID: number | number[], siteID: number | "global"): Promise<boolean>;
	moveFile(fileID: number | number[], folderID: number, siteID: number | "global"): Promise<boolean>;
	updateDisplayMode(displayMode: "grid" | "list"): Promise<void>;
	updateTab(tab: "site" | "global"): Promise<void>;
	downloadFiles(fileID: number | number[], zip: boolean, fileName?: string): Promise<void>;
	uploadFile: (
		docFiles: File | File[],
		folderID: number | null,
		siteID: number | "global",
		setProgress?: (progress: number) => void,
	) => Promise<IFile | null>;
}

export interface IFolderFormState {
	name: string;
	folderID: number | null;
}

export interface IFileFormState {
	title: string;
	alt: string;
	tags: string[];
}

const mapDispatchToProps = {
	getFolderContent: fileDriveActions.getFolderContent,
	getFoldersTree: fileDriveActions.getFoldersTree,
	updateCurrentFolder: fileDriveActions.updateCurrentFolder,
	createNewFolder: fileDriveActions.createNewFolder,
	deleteFolder: fileDriveActions.deleteFolder,
	deleteFile: fileDriveActions.deleteFile,
	moveFile: fileDriveActions.moveFile,
	updateDisplayMode: fileDriveActions.updateDisplayMode,
	updateTab: fileDriveActions.updateTab,
	downloadFiles: fileDriveActions.downloadFiles,
	uploadFile: fileDriveActions.uploadFile,
};

const mapStateToProps = (state: IRootState) => ({
	isLoading: state.app.isLoading,
	isSaving: state.app.isSaving,
	currentFolderContent: state.fileDrive.currentFolderContent,
	currentFolderID: state.fileDrive.currentFolderID,
	breadcrumb: state.fileDrive.breadcrumb,
	currentSiteID: state.sites.currentSiteInfo?.id ?? null,
	displayMode: state.fileDrive.displayMode,
	selectedTab: state.fileDrive.selectedTab,
});

export default connect(mapStateToProps, mapDispatchToProps)(FileDrive);
