import { Fade } from '@mui/material';
import { Box } from '@mui/material';

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

export interface SpinProps {
	spinning?: boolean;
	indicator?: React.ReactNode;
	children: React.ReactNode;
}

const Spin = (inProps: SpinProps) => {
	const {
		spinning = true,
		indicator = (
			<Box
				sx={{
					'@-webkit-keyframes spin-bouncedelay': {
						'0%, 80%, 100%': {
							WebkitTransform: 'scale(0)'
						},
						'40%': {
							WebkitTransform: 'scale(1.0)'
						}
					},

					'@keyframes spin-bouncedelay': {
						'0%, 80%, 100%': {
							WebkitTransform: 'scale(0)',
							transform: 'scale(0)'
						},
						'40%': {
							WebkitTransform: 'scale(1.0)',
							transform: 'scale(1.0)'
						}
					},
					'& > div': {
						backgroundColor: 'primary.main',
						margin: '4px',
						width: 8,
						height: 8,
						borderRadius: '100%',
						display: 'inline-block',
						WebkitAnimation: 'spin-bouncedelay 1s infinite ease-in-out both',
						animation: 'spin-bouncedelay 1s infinite ease-in-out both',
						'&.spin-bounce1': {
							WebkitAnimationDelay: '-0.32s',
							animationDelay: '-0.32s'
						},

						'&.spin-bounce2': {
							WebkitAnimationDelay: '-0.16s',
							animationDelay: '-0.16s'
						}
					}
				}}
			>
				<Box className="spin-bounce1" />
				<Box className="spin-bounce2" />
				<Box className="spin-bounce3" />
			</Box>
		),
		children
	} = useDefaultProps({
		name: 'ReevolveSpin',
		props: inProps
	});

	return (
		<Box sx={{ position: 'relative' }}>
			<Fade in={spinning}>
				<Box
					sx={{
						position: 'absolute',
						inset: 0,
						zIndex: 4,
						opacity: 1,
						display: 'block',
						width: '100%',
						height: '100%',
						maxHeight: 400
					}}
				>
					<Box
						sx={{
							position: 'absolute',
							top: '50%',
							left: '50%',
							transform: 'translate(-50%,-50%)',
							display: 'flex',
							alignItems: 'center',
							justifyContent: 'center'
						}}
					>
						{indicator}
					</Box>
				</Box>
			</Fade>
			<Box
				sx={(theme) => ({
					position: 'relative',
					transition: `all 250ms ${theme.transitions.easing.easeInOut}`,
					opacity: spinning ? 0.3 : 1,
					userSelect: spinning ? 'none' : undefined,
					pointerEvents: spinning ? 'none' : 'auto',
					'&::after': {
						position: 'absolute',
						inset: 0,
						zIndex: 10,
						height: '100%',
						opacity: spinning ? 0.3 : 0,
						visibility: spinning ? 'visible' : 'hidden',
						transition: `all 250ms ${theme.transitions.easing.easeInOut}`,
						content: '""',
						pointerEvents: spinning ? 'none' : 'auto'
					}
				})}
			>
				{children}
			</Box>
		</Box>
	);
};

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

export default Spin;
