import React, { useState, useCallback, useImperativeHandle, forwardRef } from 'react';
import { SxProps, Theme } from '@mui/material';
import Snackbar, { SnackbarCloseReason } from '@mui/material/Snackbar';
import Alert from '@mui/material/Alert';

import './Snack.css';

type SeverityType = 'error' | 'info' | 'success' | 'warning' | undefined;
type SetSnackType = (message: string, severity?: SeverityType) => void;

interface SnackHandle {
  setSnack: SetSnackType;
};

interface SnackProps {
  sx?: SxProps<Theme>;
  className?: string;
};

const Snack = forwardRef<SnackHandle, SnackProps>(({
  className,
  sx
}: SnackProps, ref) => {
  const [open, setOpen] = useState(false);
  const [message, setMessage] = useState("");
  const [severity, setSeverity] = useState<SeverityType>("success");

  // Set the snack pop-up and open it
  const setSnack: SetSnackType = useCallback<SetSnackType>((message: string, severity: SeverityType = "success") => {
    setTimeout(() => {
      setMessage(message);
      setSeverity(severity);
      setOpen(true);
    });
  }, [setMessage, setSeverity, setOpen]);

  useImperativeHandle(ref, () => ({
    setSnack: (message: string, severity?: SeverityType) => {
      setSnack(message, severity);
    }
  }));

  const handleSnackClose = (
    event: React.SyntheticEvent | Event,
    reason?: SnackbarCloseReason,
  ) => {
    if (reason === 'clickaway') {
      return;
    }

    setOpen(false);
  };

  return (
    <Snackbar
      className={className || "Snack"}
      sx={{ ...sx }}
      open={open}
      autoHideDuration={(severity === "success" || severity === "info") ? 1500 : 6000}
      onClose={handleSnackClose}>
      <Alert
        onClose={handleSnackClose}
        severity={severity}
        variant="filled"
        sx={{ width: '100%' }}
      >
        {message}
      </Alert>
    </Snackbar>
  )
});

export type {
  SeverityType,
  SetSnackType
};

export {
  Snack
};