import React, { Fragment, ReactNode } from "react";
import { Snackbar, Alert, Fade, Grow } from "@mui/material";
import useMySnackbar from "./useMySnackbar";
import snackbarContext from "./snackbarContext";
import { ThemeProvider, createTheme } from "@mui/material/styles";
import successIconSrc from "../../assets/project/successIcon.svg";

type MySnackbarProviderProp = {
	vertical?: "bottom" | "top";
	horizontal?: "center" | "left" | "right";
	autoHideDuration?: number;
	snackerClasses?: object;
	ClickAwayListenerProps?: object;
	ContentProps?: object;
	disableWindowBlurListener?: boolean;
	resumeHideDuration?: number;
	snackbarSx?: object;
	transition?: "grow" | "fade";
	transitionDuration?: number;
	TransitionProps?: object;
	alertClasses?: object;
	closeText?: string;
	variant?: "filled" | "outlined" | "standard";
	errorIcon?: ReactNode;
	infoIcon?: ReactNode;
	warningIcon?: ReactNode;
	elevation?: number;
	alertSx?: object;
	children?: ReactNode;
};

const getTransitionComponent = (transition: "grow" | "fade") => {
	switch (transition) {
		case "grow":
			return Grow;
		case "fade":
			return Fade;
		default:
			return Grow;
	}
};

const MySnackbarProvider = ({
	vertical = "top",
	horizontal = "center",
	autoHideDuration = 3000,
	snackerClasses,
	ClickAwayListenerProps,
	ContentProps,
	disableWindowBlurListener = true,
	resumeHideDuration,
	snackbarSx,
	transition = "grow",
	transitionDuration,
	TransitionProps = {},
	alertClasses,
	closeText = "Close",
	variant = "standard",
	errorIcon,
	infoIcon,
	warningIcon,
	elevation = 3,
	alertSx,
	children,
}: MySnackbarProviderProp) => {
	const {
		open,
		setOpen,
		messageInfo,
		handleExited,
		success,
		error,
		warning,
		info,
		close,
	} = useMySnackbar();

	const theme = createTheme({
		components: {
			MuiAlert: {
				styleOverrides: {
					root: {
						minWidth: "360px",
						maxWidth: "542px",
						minHeight: "38px",
						boxShadow: "none",
						"& .MuiAlert-action": {
							paddingLeft: "32px",
						},
						"&.MuiAlert-standardError": {
							color: "#FF4E4E",
							background: "rgba(255, 237, 237, 1)",
							"& .MuiAlert-icon": {
								color: "#FF4E4E",
							},
						},
						"&.MuiAlert-standardInfo": {
							color: "rgba(19, 112, 255, 1)",
							background: "rgba(235, 243, 255, 1)",
							"& .MuiAlert-icon": {
								color: "rgba(19, 112, 255, 1)",
							},
						},
						"&.MuiAlert-standardSuccess": {
							color: "rgba(2, 171, 131, 1)",
							background: "rgba(217, 255, 238, 1)",
							"& .MuiAlert-icon": {
								color: "rgba(2, 171, 131, 1)",
							},
						},
						"&.MuiAlert-standardWarning": {
							color: "rgba(255, 185, 25, 1)",
							background: "rgba(255, 246, 226, 1)",
							"& .MuiAlert-icon": {
								color: "rgba(255, 185, 25, 1)",
							},
						},
					},
				},
			},
		},
	});

	const successIcon = (
		<img
			src={successIconSrc}
			style={{ width: "16px", height: "16px", margin: "3px 0" }}
			alt=""
		/>
	);

	return (
		<Fragment>
			<ThemeProvider theme={theme}>
				<Snackbar
					open={open}
					autoHideDuration={autoHideDuration}
					onClose={close}
					anchorOrigin={{ vertical: vertical, horizontal: horizontal }}
					classes={snackerClasses}
					ClickAwayListenerProps={ClickAwayListenerProps}
					ContentProps={ContentProps}
					disableWindowBlurListener={disableWindowBlurListener}
					resumeHideDuration={resumeHideDuration}
					sx={snackbarSx}
					TransitionComponent={getTransitionComponent(transition)}
					transitionDuration={transitionDuration}
					TransitionProps={{ onExited: handleExited, ...TransitionProps }}
				>
					<Alert
						id="Alert"
						classes={alertClasses}
						closeText={closeText}
						iconMapping={{
							error: errorIcon,
							info: infoIcon,
							success: successIcon,
							warning: warningIcon,
						}}
						severity={messageInfo?.severity}
						variant={variant}
						elevation={elevation}
						sx={{ ...alertSx }}
						onClose={() => {
							setOpen(false);
						}}
					>
						{messageInfo?.content}
					</Alert>
				</Snackbar>
			</ThemeProvider>
			<snackbarContext.Provider value={{ success, error, warning, info }}>
				{children}
			</snackbarContext.Provider>
		</Fragment>
	);
};

export default MySnackbarProvider;
