import { useState } from "react";

import { Button, ErrorToast, IconAction, ImageDragAndDrop, Loader, Toast, Tooltip } from "@ax/components";
import { useModal, useToast } from "@ax/hooks";
import type { IGetFolderParams, IImage } from "@ax/types";

import { type Fields, GriddoImageExp } from "@griddo/core";

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

import * as S from "./style";

const ImageModal = (props: IProps) => {
	const {
		image,
		items,
		activeDelete,
		isAllowedToEdit,
		setFile,
		onDelete,
		setFileSelected,
		handleDownload,
		form,
		setForm,
		isDirty,
		resetDirty,
		getParams,
	} = props;

	const { name, id, site } = image;

	const [isDNDVisible, setDNDVisible] = useState(false);
	const [isArrowPrev, setIsArrowPrev] = useState(false);
	const { isVisible, toggleToast, setIsVisible } = useToast();
	const { isOpen: isSaveOpen, toggleModal: toggleSaveModal } = useModal();

	const index = items.indexOf(image.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);
	};

	const handleReplace = () => setDNDVisible((state) => !state);

	const handleUpload = (file: IImage[]) => {
		setFileSelected(file[0]);
		setDNDVisible(false);
		toggleToast();
		resetDirty();
	};

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

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

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

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

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

	return (
		<>
			<S.Wrapper>
				<ErrorToast size="l" />
				<S.LeftPanel>
					<IconAction icon="leftArrow" onClick={handleArrowClick(true)} disabled={index === 0} />
					<S.FilePreview>
						<S.ImageWrapper>
							<S.SpinnerWrapper>
								<Loader name="dots" />
							</S.SpinnerWrapper>
							{/* Fields.Image (Core) y IImage (AX) no son **exactamente** iguales por lo que se ha decidido castearlo (aunque es lo mismo que poner any)...*/}
							<GriddoImageExp key={image.id} image={image as unknown as Fields.Image} widths={["1000"]} />
							{isDNDVisible && (
								<S.DragAndDropWrapper>
									<ImageDragAndDrop
										handleUpload={handleUpload}
										inverse={true}
										replaceData={{ fileID: id }}
										siteID={site || "global"}
										getParams={getParams}
									/>
								</S.DragAndDropWrapper>
							)}
						</S.ImageWrapper>
						<S.FileActions>
							{isAllowedToEdit ? (
								<S.ReplaceWrapper>
									<Tooltip content="Replacement image will appear on all linked pages.">
										<Button type="button" buttonStyle="text" icon="image" onClick={handleReplace}>
											Replace
										</Button>
									</Tooltip>
								</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
					image={image}
					onDelete={onDelete}
					activeDelete={activeDelete}
					isAllowedToEdit={isAllowedToEdit}
					form={form}
					setForm={setForm}
					isDirty={isDirty}
					resetDirty={resetDirty}
					getParams={getParams}
				/>
			</S.Wrapper>
			{isVisible && <Toast {...toastProps} />}
			{isSaveOpen && (
				<NotSavedModal
					isOpen={isSaveOpen}
					toggleModal={toggleSaveModal}
					mainModalAction={mainModalAction}
					secondaryModalAction={secondaryModalAction}
				/>
			)}
		</>
	);
};

interface IProps {
	image: IImage;
	onDelete(fileID: number): Promise<void>;
	items: number[];
	setFile(id: number): void;
	setFileSelected: (file: IImage) => void;
	activeDelete: boolean;
	isAllowedToEdit: boolean;
	handleDownload(fileID: number, fileName: string): void;
	form: IImageFormState;
	setForm(form: IImageFormState): void;
	isDirty: boolean;
	resetDirty(): void;
	getParams(): IGetFolderParams;
}

export default ImageModal;
