import { LazyLoadImage } from 'react-lazy-load-image-component';
import { Box } from '@mui/material';
import clsx from 'clsx';
import { isFunction } from 'lodash';

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

import imageClasses from './classes';
import ImageWrapper from './ImageWrapper';
import Overlay from './Overlay';
import { defaultPlaceholder, defaultTransparentPlaceholder } from './placeholders';
import { ImageProps } from './types';

export default function Image(inProps: ImageProps) {
	const {
		ref,
		aspectRatio,
		disabledEffect = false,
		alt,
		src,
		delayTime,
		threshold,
		beforeLoad,
		delayMethod,
		placeholder,
		wrapperProps,
		scrollPosition,
		effect = 'blur',
		visibleByDefault,
		wrapperClassName,
		useIntersectionObserver,

		width,
		height,
		slotProps,
		sx,
		srcSet,
		placeholderSrc,
		objectFit = 'cover',
		className,
		...other
	} = useDefaultProps({
		name: 'ReevolveImage',
		props: inProps
	});

	return (
		<ImageWrapper
			component="span"
			{...other}
			ref={ref}
			className={clsx(imageClasses.root, className)}
			sx={(theme) => ({
				width,
				height,
				...(!!aspectRatio && { width: width ?? 1 }),
				...(isFunction(sx) ? (sx as Function)(theme) : sx)
			})}
		>
			{slotProps?.overlay && (
				<Overlay
					className={clsx(imageClasses.overlay, slotProps?.overlay?.className)}
					sx={slotProps?.overlay}
				/>
			)}

			<Box
				{...slotProps?.img}
				component={LazyLoadImage}
				alt={alt}
				src={src}
				width={width}
				height={height}
				delayTime={delayTime}
				threshold={threshold}
				beforeLoad={beforeLoad}
				delayMethod={delayMethod}
				placeholder={placeholder}
				wrapperProps={wrapperProps}
				scrollPosition={scrollPosition}
				visibleByDefault={visibleByDefault}
				effect={visibleByDefault || disabledEffect ? undefined : effect}
				useIntersectionObserver={useIntersectionObserver}
				wrapperClassName={wrapperClassName || imageClasses.wrapper}
				srcSet={srcSet}
				placeholderSrc={
					visibleByDefault || disabledEffect ? defaultTransparentPlaceholder : (placeholderSrc ?? defaultPlaceholder)
				}
				sx={(theme) => ({
					width: 1,
					height: 1,
					objectFit,
					aspectRatio,
					...(isFunction(slotProps?.img?.sx) ? (slotProps.img.sx as Function)(theme) : slotProps?.img?.sx)
				})}
			/>
		</ImageWrapper>
	);
}
