import { HeaderNotificationItem, INotification } from './NotificationItem';
import { IconButton, Transitions } from '@/components/@extended';
import { HeaderToggleButton } from '@/components/Layout/Header/Buttons';
import { useLayoutMediaState, useLayoutNotificationsState } from '@/components/Layout/Provider';
import { MainCard } from '@/components/MainCard';
import { PushNotificationToggleButton } from '@/components/ra-buttons';
import { Empty } from '@/components/ra-lists';
import { usePopoverState } from '@/hooks';
import { PushNotificationConfig } from '@/hooks/usePushNotifications';
import { BellOutlined, CheckCircleOutlined } from '@ant-design/icons';
import {
  Badge,
  ClickAwayListener,
  Divider,
  List,
  ListItemButton,
  ListItemText,
  Paper,
  Popper,
  Tooltip,
  Typography,
  useTheme
} from '@mui/material';
import dayjs from 'dayjs';
import { useGetList, useNotify, useRefresh, useTranslate, useUpdateMany } from 'ra-core';
import { useCallback, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';

const avatarSx = {
  width: 36,
  height: 36,
  fontSize: '1rem'
};

const actionSx = {
  mt: '6px',
  ml: 1,
  top: 'auto',
  right: 'auto',
  alignSelf: 'flex-start',
  transform: 'none'
};

type HeaderNotificationProps = {
  pushNotifications?: PushNotificationConfig;
};

function HeaderNotification({ pushNotifications }: HeaderNotificationProps) {
  const { enable } = useLayoutNotificationsState();
  return enable ? <HeaderNotificationButton pushNotifications={pushNotifications} /> : null;
}

type HeaderNotificationButtonProps = {
  pushNotifications?: PushNotificationConfig;
};

function HeaderNotificationButton({ pushNotifications }: HeaderNotificationButtonProps) {
  const translate = useTranslate();
  const theme = useTheme();
  const refresh = useRefresh();
  const notify = useNotify();
  const { downMd } = useLayoutMediaState();
  const { resource } = useLayoutNotificationsState();
  const [notifications, setNotifications] = useState<Array<INotification>>([]);
  const { data, isLoading } = useGetList<INotification>(resource, {
    pagination: { page: 1, perPage: 25 },
    sort: { field: 'created', order: 'DESC' },
    filter: {
      readed: false
    }
  });
  const read = notifications.filter((item) => item.readed === null).length;
  const { open, anchorEl, handleClose, handleToggle } = usePopoverState();

  useEffect(() => {
    if (!isLoading && data) {
      setNotifications(data ?? []);
    }
  }, [data, isLoading]);

  const unreadNotificationIds = notifications
    .filter((notification) => !notification.readed)
    .map((notification) => notification.id);

  const [updateMany] = useUpdateMany(
    resource,
    {
      ids: unreadNotificationIds,
      data: { readed: dayjs().toISOString() }
    },
    {
      onSuccess: () => {
        refresh();
        notify('resources.notifications.messages.readed.done');
      },
      onError: () => notify('ra.notification.readed_error')
    }
  );

  const handleUpdateMany = useCallback(() => {
    updateMany();
  }, [updateMany]);

  return (
    <>
      <HeaderToggleButton value="notifications" selected={open} onChange={handleToggle}>
        <Badge badgeContent={read} color="primary">
          <BellOutlined />
        </Badge>
      </HeaderToggleButton>
      <Popper
        placement={downMd ? 'bottom' : 'bottom-end'}
        open={open}
        anchorEl={anchorEl}
        role={undefined}
        transition
        disablePortal
      >
        {({ TransitionProps }) => (
          //@ts-ignore
          <Transitions type="grow" position={downMd ? 'top' : 'top-right'} in={open} {...TransitionProps}>
            <Paper
              sx={{
                marginTop: 1,
                //@ts-ignore
                boxShadow: theme.customShadows.z1,
                width: '100%',
                minWidth: 285,
                maxWidth: 420,
                [theme.breakpoints.down('md')]: {
                  maxWidth: 285
                }
              }}
            >
              <ClickAwayListener onClickAway={handleClose}>
                <MainCard
                  title={translate('ra.notification.title')}
                  elevation={0}
                  border={false}
                  content={false}
                  secondary={
                    <>
                      {pushNotifications ? <PushNotificationToggleButton config={pushNotifications!} /> : null}
                      {read > 0 && (
                        <Tooltip title={translate('ra.notification.mark-as-read')} onClick={handleUpdateMany}>
                          {/*@ts-ignore*/}
                          <IconButton color="success" size="small">
                            <CheckCircleOutlined style={{ fontSize: '1.15rem' }} />
                          </IconButton>
                        </Tooltip>
                      )}
                    </>
                  }
                >
                  {notifications.length === 0 ? (
                    <Empty
                      fitContent
                      hasCreate={false}
                      title={
                        <Typography variant="h5" component="span">
                          {translate('ra.notification.empty')}
                        </Typography>
                      }
                      sx={{
                        '& .ApplicaEmpty-icon': { fontSize: '60px' },
                        '& .ApplicaEmpty-toolbar': { display: 'none' }
                      }}
                    />
                  ) : (
                    <>
                      <List
                        component="nav"
                        sx={{
                          p: 0,
                          '& .MuiListItemButton-root': {
                            py: 0.5,
                            '&.Mui-selected': { bgcolor: 'grey.50', color: 'text.primary' },
                            '& .MuiAvatar-root': avatarSx,
                            '& .MuiListItemSecondaryAction-root': { ...actionSx, position: 'relative' }
                          },
                          maxHeight: 'calc(100vh - 240px)',
                          overflow: 'auto'
                        }}
                      >
                        {notifications.map((item, index) => (
                          <HeaderNotificationItem
                            key={item.id}
                            selected={read > 0}
                            notification={item}
                            onClick={handleClose}
                            divider={index < notifications.length - 1}
                          />
                        ))}
                      </List>
                      {/*@ts-ignore*/}
                      <ListItemButton
                        sx={{ textAlign: 'center', py: `${12}px !important` }}
                        to={`/${resource}`}
                        LinkComponent={Link}
                        onClick={handleClose}
                      >
                        <ListItemText
                          primary={
                            <Typography variant="h6" color="primary">
                              {translate('ra.notification.view_all')}
                            </Typography>
                          }
                        />
                      </ListItemButton>
                    </>
                  )}
                  <Divider />
                </MainCard>
              </ClickAwayListener>
            </Paper>
          </Transitions>
        )}
      </Popper>
    </>
  );
}

export { HeaderNotification };
