import { useState } from "react";

import { Button, FloatingMenu, IconAction, Toast, Tooltip } from "@ax/components";
import { getFileIcon } from "@ax/helpers";
import { useModal, useToast } from "@ax/hooks";
import type { IFile } from "@ax/types";

import type { IFileFormState } from "..";
import { NotSavedModal } from "../atoms";
import FileDragAndDrop from "../FileDragAndDrop";
import DetailPanel from "./DetailPanel";

import * as S from "./style";

const FileModal = (props: IProps) => {
	const {
		file,
		items,
		activeDelete,
		isAllowedToEdit,
		setFile,
		toggleModal,
		onDelete,
		setFileSelected,
		handleDownload,
		form,
		setForm,
		isDirty,
		resetDirty,
	} = props;

	const { fileType, fileName, id, site } = file;

	const [replaceType, setReplaceType] = useState<"full" | "partial" | null>(null);
	const [isDNDVisible, setDNDVisible] = useState(false);
	const [isArrowPrev, setIsArrowPrev] = useState(false);
	const { isVisible, toggleToast, setIsVisible } = useToast();
	const { isOpen: isSaveOpen, toggleModal: toggleSaveModal } = useModal();

	const iconUrl = `/img/icons/${getFileIcon(fileType)}`;
	const index = items.indexOf(file.id);

	const handleArrowClick = (isPrev: boolean) => () => {
		if (isDirty) {
			setIsArrowPrev(isPrev);
			toggleSaveModal();
		} else {
			resetDirty();
			changeFile(isPrev);
		}
	};

	const changeFile = (isPrev: boolean) => {
		isPrev ? setFile(items[index - 1]) : setFile(items[index + 1]);
		setDNDVisible(false);
		setReplaceType(null);
	};

	const OptionsButton = () => (
		<Tooltip content="Replacement file will appear on all linked pages.">
			<Button type="button" buttonStyle="text" icon="page" backIcon="downArrow">
				Replace
			</Button>
		</Tooltip>
	);

	const handleReplaceType = (type: "full" | "partial") => {
		setReplaceType(type);
		setDNDVisible(true);
	};

	const textReplaceType =
		replaceType === "full"
			? "Replace file and its URL"
			: replaceType === "partial"
				? "Replace file and keep its original URL"
				: "";

	const handleUpload = (file: IFile[]) => {
		setFileSelected(file[0]);
		setDNDVisible(false);
		setReplaceType(null);
		toggleToast();
	};

	const handleFileDownload = () => handleDownload(id, fileName);

	const toastProps = {
		setIsVisible,
		message: "1 file replaced",
	};

	const handleMainAction = () => {
		toggleSaveModal();
		resetDirty();
		changeFile(isArrowPrev);
	};

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

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

	return (
		<>
			<S.Wrapper>
				<S.LeftPanel>
					<IconAction icon="leftArrow" onClick={handleArrowClick(true)} disabled={index === 0} />
					<S.FilePreview>
						<S.ImageWrapper>
							<S.IconWrapper>
								<div>
									<img src={iconUrl} alt={`${fileType} Icon`} />
								</div>
								{isDNDVisible && (
									<S.DragAndDropWrapper>
										<FileDragAndDrop
											handleUpload={handleUpload}
											inverse={true}
											replaceData={{ fileID: id, keepURL: replaceType !== "full" }}
											siteID={site || "global"}
										/>
									</S.DragAndDropWrapper>
								)}
							</S.IconWrapper>
						</S.ImageWrapper>
						<S.FileName data-testid="file-name">{fileName}</S.FileName>
						<S.FileActions>
							{isAllowedToEdit ? (
								<S.ReplaceWrapper>
									<FloatingMenu Button={OptionsButton} position="left">
										<S.ActionMenu>
											<S.ActionItem onClick={() => handleReplaceType("full")}>Replace file and its URL</S.ActionItem>
											<S.ActionItem onClick={() => handleReplaceType("partial")}>
												Replace file and keep its original URL
											</S.ActionItem>
										</S.ActionMenu>
									</FloatingMenu>
									<S.TextType>{textReplaceType}</S.TextType>
								</S.ReplaceWrapper>
							) : (
								<></>
							)}
							<Button type="button" buttonStyle="text" icon="download" onClick={handleFileDownload}>
								Download
							</Button>
						</S.FileActions>
					</S.FilePreview>
					<IconAction icon="rightArrow" onClick={handleArrowClick(false)} disabled={index === items.length - 1} />
				</S.LeftPanel>
				<DetailPanel
					file={file}
					toggleModal={toggleModal}
					onDelete={onDelete}
					activeDelete={activeDelete}
					isAllowedToEdit={isAllowedToEdit}
					form={form}
					setForm={setForm}
					isDirty={isDirty}
					resetDirty={resetDirty}
				/>
			</S.Wrapper>
			{isVisible && <Toast {...toastProps} />}
			{isSaveOpen && (
				<NotSavedModal
					isOpen={isSaveOpen}
					toggleModal={toggleSaveModal}
					mainModalAction={mainModalAction}
					secondaryModalAction={secondaryModalAction}
				/>
			)}
		</>
	);
};

interface IProps {
	file: IFile;
	toggleModal(): void;
	onDelete(fileID: number): void;
	items: number[];
	setFile(id: number): void;
	setFileSelected: (file: IFile) => void;
	activeDelete: boolean;
	isAllowedToEdit: boolean;
	handleDownload(fileID: number, fileName: string): void;
	form: IFileFormState;
	setForm(form: IFileFormState): void;
	isDirty: boolean;
	resetDirty(): void;
}

export default FileModal;
