import React, {
  useCallback,
  useContext,
  useEffect,
  useRef,
  useState,
} from "react";
import {
  Box,
  CircularProgress,
  ClickAwayListener,
  Divider,
  Grid,
  Paper,
  Popper,
  Typography,
} from "@mui/material";
import { useTheme } from "@mui/material/styles";
import notificationIcon from "../../../assets/images/icon/Actions.svg";
import unreadBadgeIcon from "../../../assets/images/icon/UnreadBadge.svg";
import bellIcon from "../../../assets/images/icon/bell.svg";
import { useStyles } from "../mainLayoutStyles";
import Transitions from "./Transitions";
import MainCard from "./MainCard";
import { useNavigate } from "react-router-dom";
import InfiniteScroll from "react-infinite-scroll-component";
import {
  getNotifications,
  markReadNotification,
} from "../../../services/notification.service";
import { format, formatDistanceToNow } from "date-fns";
import { FirebaseContext } from "../../../context/FirebaseProvider";
import { redirectByNotificationType } from "../../../views/Notifications/notificationUtils";

const NotificationSection = () => {
  const classes = useStyles();
  const theme = useTheme();
  const { notifications, setNotifications } = useContext(FirebaseContext);
  const [isUnreadInfiniteLoading, setIsUnreadInfiniteLoading] = useState(false);
  const [isRecentInfiniteLoading, setIsRecentInfiniteLoading] = useState(false);
  const [open, setOpen] = useState(false);
  const anchorRef = useRef(null);
  const navigate = useNavigate();
  const [unreadNotifications, setUnreadNotifications] = useState([]);
  const [unreadNotificationsPage, setUnreadNotificationsPage] = useState(0);
  const [unreadNotificationsTotalCount, setUnreadNotificationsTotalCount] =
    useState(0);
  const [recentNotifications, setRecentNotifications] = useState([]);
  const [recentNotificationsPage, setRecentNotificationsPage] = useState(0);
  const [recentNotificationsTotalCount, setRecentNotificationsTotalCount] =
    useState(0);

  const getUnreadNotifications = async (page = unreadNotificationsPage) => {
    try {
      setIsUnreadInfiniteLoading(true);
      const response = await getNotifications(true, page);
      if (
        response.status === 200 &&
        response?.data?.data?.notificationList?.length
      ) {
        setUnreadNotifications((notifications) => [
          ...notifications,
          ...response?.data?.data?.notificationList,
        ]);
        setUnreadNotificationsTotalCount(response?.data?.data?.totalCount);
        setUnreadNotificationsPage((page) => page + 1);
      }
    } catch (err) {
      // eslint-disable-next-line no-console
      console.log("Error::>", err);
    } finally {
      setIsUnreadInfiniteLoading(false);
    }
  };
  const getRecentNotifications = async (page = recentNotificationsPage) => {
    try {
      setIsRecentInfiniteLoading(true);
      const response = await getNotifications(false, page);
      if (
        response.status === 200 &&
        response?.data?.data?.notificationList?.length
      ) {
        setRecentNotifications((notifications) => [
          ...notifications,
          ...response?.data?.data?.notificationList,
        ]);
        setRecentNotificationsTotalCount(response?.data?.data?.totalCount);
        setRecentNotificationsPage((page) => page + 1);
      }
    } catch (err) {
      // eslint-disable-next-line no-console
      console.log("Error::>", err);
    } finally {
      setIsRecentInfiniteLoading(false);
    }
  };

  const handleClose = useCallback((event) => {
    if (anchorRef.current && anchorRef.current.contains(event.target)) {
      return;
    }
    setOpen(false);
  }, []);

  const setDefault = () => {
    setRecentNotifications(() => []);
    setUnreadNotifications(() => []);
    setRecentNotificationsPage(0);
    setUnreadNotificationsPage(0);
    getUnreadNotifications(0);
    getRecentNotifications(0);
    setRecentNotificationsTotalCount(0);
    setUnreadNotificationsTotalCount(0);
  };

  const handleToggle = () => {
    setOpen((prevOpen) => !prevOpen);
  };

  useEffect(() => {
    if (!open && !notifications) {
      anchorRef.current?.focus();
      setDefault();
    }
    setNotifications(() => null);
  }, [open]);

  useEffect(() => {
    if (notifications) {
      setDefault();
    }
  }, [notifications]);

  const markTheNotificationAsRead = async (ids) => {
    try {
      setIsUnreadInfiniteLoading(true);
      await markReadNotification(ids);
      setDefault();
      setNotifications(() => null);
    } catch (err) {
      // eslint-disable-next-line no-console
      console.log("Error::>>", err);
    } finally {
      setIsUnreadInfiniteLoading(false);
    }
  };

  const handleRouteClick = (type, resourceId, id, isRecent) => {
    if (!isRecent) {
      markTheNotificationAsRead([id]);
    }
    navigate(redirectByNotificationType(type, resourceId, true), {
      replace: true,
    });
    handleToggle();
  };

  const renderNotification = (
    notification,
    index,
    lastNotification = false,
    isRecent = false
  ) => (
    <React.Fragment key={index}>
      <Box
        onClick={() =>
          handleRouteClick(
            notification?.notificationType,
            notification?.resourceId,
            notification?.id,
            isRecent
          )
        }
        className={isRecent ? classes.recentListOuterDiv : classes.listOuterDiv}
      >
        <Box className={classes.unreadList}>
          <Grid container>
            <Grid item xs={3} className={classes.notificationListImgDiv}>
              <span className={classes.centerAlignClass}>
                <img
                  style={{
                    visibility: isRecent ? "hidden" : "visible",
                    height: "10px",
                    width: "10px",
                  }}
                  src={unreadBadgeIcon}
                  alt="unreadBadgeIcon"
                />
              </span>
              <Box
                sx={{
                  width: "100%",
                  display: "flex",
                  justifyContent: "left",
                  alignItems: "center",
                  paddingLeft: "2px",
                }}
              >
                <Box
                  sx={{
                    display: "flex",
                    justifyContent: "center",
                    alignItems: "center",
                    backgroundColor: isRecent ? "#9C9C9C" : "#0E2354",
                    height: "50%",
                    width: "60%",
                    borderRadius: "60%",
                  }}
                >
                  <img
                    style={{ height: "21px", width: "21px" }}
                    src={bellIcon}
                    alt="bell"
                  />
                </Box>
              </Box>
            </Grid>
            <Grid item xs={9} className={classes.unreadListBody}>
              <Box className={classes.contentDiv}>
                {notification?.message?.subText}
              </Box>
            </Grid>
          </Grid>
          <Grid container>
            <Grid item xs={3}></Grid>
            <Grid item xs={9} className={classes.timestamp}>
              {isRecent
                ? format(new Date(notification.createdAt), "MMM d, yyyy")
                : formatDistanceToNow(new Date(notification.createdAt), {
                    addSuffix: true,
                  }).replace("about ", "")}
            </Grid>
          </Grid>
        </Box>
      </Box>
      {!lastNotification && <Divider sx={{ width: "85%", margin: "auto" }} />}
    </React.Fragment>
  );

  return (
    <>
      <Box
        className={classes.notificationSection}
        ref={anchorRef}
        aria-controls={open ? "menu-list-grow" : undefined}
        aria-haspopup="true"
      >
        <Box className={classes.notificationDiv} onClick={handleToggle}>
          <img
            src={notificationIcon}
            className={classes.notificationImg}
            alt="notificationIcon"
          />
          {(unreadNotificationsTotalCount > 0 ||
            unreadNotifications?.length > 0) && (
            <div className={classes.notificationDot}></div>
          )}
        </Box>
      </Box>
      <Popper
        open={open}
        anchorEl={anchorRef.current}
        transition
        disablePortal
        className={classes.zIndex}
        placement="bottom-end"
        popperOptions={{
          modifiers: [{ name: "offset", options: { offset: [-12, 6] } }],
        }}
      >
        {({ TransitionProps }) => (
          <Transitions in={open} {...TransitionProps}>
            <Paper>
              <ClickAwayListener onClickAway={handleClose}>
                <MainCard
                  border={false}
                  elevation={16}
                  content={false}
                  boxShadow
                  shadow={theme.shadows[16]}
                >
                  <Box className={`${classes.notificationList} thumb4`}>
                    <Box sx={{ hight: "100%" }}>
                      <Box className={classes.notificationHeader}>
                        <Typography className={classes.notificationHeadText}>
                          Notifications
                        </Typography>
                      </Box>
                      <Divider />
                      <Box className={classes.notificationListHeader}>
                        <Box className={classes.unreadDiv}>
                          <Typography
                            variant="Inter-SemiBold"
                            className={classes.notificationHeadText}
                          >
                            Unread
                          </Typography>
                        </Box>
                        <Box
                          onClick={
                            unreadNotificationsTotalCount > 0
                              ? markTheNotificationAsRead
                              : () => {}
                          }
                          className={classes.markAsReadDiv}
                          sx={
                            unreadNotificationsTotalCount === 0
                              ? {
                                  opacity: 0.5,
                                  cursor: "not-allowed !important",
                                }
                              : {}
                          }
                        >
                          <Typography
                            variant="Inter-SemiBold"
                            className={classes.notificationSubHeadText}
                          >
                            Mark all as read
                          </Typography>
                        </Box>
                      </Box>
                      <Box
                        sx={{
                          maxHeight: "10rem",
                          overflow: "scroll",
                          position: "relative",
                        }}
                        className="thumb4"
                        id="scrollableDivOfUnreadNotification"
                      >
                        <InfiniteScroll
                          dataLength={unreadNotifications?.length || 0}
                          next={getUnreadNotifications || (() => {})}
                          hasMore={
                            unreadNotificationsTotalCount >
                              unreadNotifications?.length || false
                          }
                          scrollThreshold={0.8}
                          loader={
                            isUnreadInfiniteLoading && (
                              <CircularProgress
                                style={{
                                  position: "absolute",
                                  inset: 0,
                                  left: "50%",
                                  right: "50%",
                                  top: "5%",
                                  zIndex: "1000",
                                  backgroundColor: "white",
                                  height: "2rem",
                                  width: "2rem",
                                }}
                                color="inherit"
                              />
                            )
                          }
                          scrollableTarget="scrollableDivOfUnreadNotification"
                        >
                          {unreadNotifications?.map((notification, index) =>
                            renderNotification(
                              notification,
                              index,
                              index === unreadNotifications?.length - 1
                            )
                          )}
                        </InfiniteScroll>
                      </Box>
                      <Box className={classes.recentDiv}>
                        <Typography
                          variant="Inter-SemiBold"
                          className={classes.notificationHeadText}
                        >
                          Recent
                        </Typography>
                      </Box>
                      <Box
                        sx={{
                          maxHeight: "15rem",
                          overflow: "scroll",
                          position: "relative",
                        }}
                        className="thumb4"
                        id="scrollableDivOfRecentNotification"
                      >
                        <InfiniteScroll
                          dataLength={recentNotifications?.length || 0}
                          next={getRecentNotifications || (() => {})}
                          hasMore={
                            recentNotificationsTotalCount >
                              recentNotifications?.length || false
                          }
                          scrollThreshold={0.8}
                          loader={
                            isRecentInfiniteLoading && (
                              <CircularProgress
                                style={{
                                  position: "absolute",
                                  inset: 0,
                                  left: "50%",
                                  right: "50%",
                                  top: "5%",
                                  zIndex: "1000",
                                  backgroundColor: "white",
                                  height: "2rem",
                                  width: "2rem",
                                }}
                                color="inherit"
                              />
                            )
                          }
                          scrollableTarget="scrollableDivOfRecentNotification"
                        >
                          {recentNotifications?.map((notification, index) =>
                            renderNotification(
                              notification,
                              index,
                              index === recentNotifications?.length - 1,
                              true
                            )
                          )}
                        </InfiniteScroll>
                      </Box>
                    </Box>
                  </Box>
                </MainCard>
              </ClickAwayListener>
            </Paper>
          </Transitions>
        )}
      </Popper>
    </>
  );
};

export default NotificationSection;
