import { Box, BoxProps, Stack, StackProps, Tooltip } from '@mui/material';
import clsx from 'clsx';
import { isFunction } from 'lodash';

import useDefaultProps from '../../hooks/useDefaultProps';

import fileThumbnailClasses from './classes';
import DownloadButton, { DownloadButtonProps } from './DownloadButton';
import RemoveButton, { RemoveButtonProps } from './RemoveButton';
import { fileData, fileFormat, fileThumb } from './utils';

export interface FileThumbnailProps extends StackProps<'span'> {
	file: File;
	tooltip?: boolean;
	onRemove?: () => void;
	onDownload?: () => void;
	imageView?: boolean;
	slotProps?: {
		img?: Omit<BoxProps<'img'>, 'src'>;
		icon?: BoxProps<'svg'>;
		removeButton?: Omit<RemoveButtonProps, 'onClick'>;
		downloadButton?: Omit<DownloadButtonProps, 'onClick'>;
	};
}

export default function FileThumbnail(inProps: FileThumbnailProps) {
	const { sx, file, tooltip, onRemove, imageView, slotProps, onDownload, className, ...other } = useDefaultProps({
		name: 'RemateFileThumbnail',
		props: inProps
	});

	const previewUrl = typeof file === 'string' ? file : URL.createObjectURL(file);

	const { name, path } = fileData(file);

	const format = fileFormat(path || previewUrl);

	const renderImg = (
		<Box
			{...slotProps?.img}
			component="img"
			src={previewUrl}
			className={clsx(fileThumbnailClasses.img, slotProps?.img?.className)}
			sx={(theme) => ({
				width: 1,
				height: 1,
				objectFit: 'cover',
				borderRadius: 'inherit',
				...(isFunction(slotProps?.img?.sx) ? (slotProps.img.sx as Function)(theme) : slotProps?.img?.sx)
			})}
		/>
	);

	const renderIcon = (
		<Box
			{...slotProps?.icon}
			component={fileThumb(format) as unknown as 'svg'}
			className={clsx(fileThumbnailClasses.icon, slotProps?.icon?.className)}
			sx={(theme) => ({
				width: 1,
				height: 1,
				...(isFunction(slotProps?.icon?.sx) ? (slotProps.icon.sx as Function)(theme) : slotProps?.icon?.sx)
			})}
		/>
	);

	const renderContent = (
		<Stack
			{...other}
			component="span"
			className={clsx(fileThumbnailClasses.root, className)}
			sx={(theme) => ({
				width: 36,
				height: 36,
				flexShrink: 0,
				borderRadius: 1.25,
				alignItems: 'center',
				position: 'relative',
				display: 'inline-flex',
				justifyContent: 'center',
				...(isFunction(sx) ? (sx as Function)(theme) : sx)
			})}
		>
			{format === 'image' && imageView ? renderImg : renderIcon}

			{onRemove && (
				<RemoveButton
					{...slotProps?.removeButton}
					onClick={(e) => {
						e.stopPropagation();

						onRemove();
					}}
					className={clsx(fileThumbnailClasses.removeBtn, slotProps?.removeButton?.className)}
				/>
			)}

			{onDownload && (
				<DownloadButton
					{...slotProps?.downloadButton}
					onClick={onDownload}
					className={clsx(fileThumbnailClasses.downloadBtn, slotProps?.downloadButton?.className)}
				/>
			)}
		</Stack>
	);

	if (tooltip) {
		return (
			<Tooltip
				arrow
				title={name}
				slotProps={{ popper: { modifiers: [{ name: 'offset', options: { offset: [0, -12] } }] } }}
			>
				{renderContent}
			</Tooltip>
		);
	}

	return renderContent;
}

declare module '@mui/material' {
	interface Components {
		RemateFileThumbnail?: {
			defaultProps?: Partial<FileThumbnailProps>;
		};
	}
}
