import isNil from 'lodash-es/isNil';
import { IconBellRinging, type TablerIcon } from '@material-hu/icons/tabler';
import ListItemButton from '@material-hu/mui/ListItemButton';
import Stack from '@material-hu/mui/Stack';
import { alpha, useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import HTMLBody from '@material-hu/components/composed-components/HTMLBody';

import { moduleIcons } from '../../constants';
import { type NotificationItem } from '../../types';

import NotificationItemAvatar from './NotificationItemAvatar';
import NotificationsOptions from './NotificationsOptions';

const lineClampBase = {
  display: '-webkit-box',
  WebkitBoxOrient: 'vertical' as const,
  overflow: 'hidden',
  textOverflow: 'ellipsis',
  overflowWrap: 'break-word',
};

const LINE_CLAMP_2 = { ...lineClampBase, WebkitLineClamp: 2 };
const LINE_CLAMP_4 = { ...lineClampBase, WebkitLineClamp: 4 };

type NotificationListItemProps = {
  notification: NotificationItem;
  metaText: string;
  optionsOpenId: string | null;
  onOptionsOpenChange: (id: string | null) => void;
  isMarkingRead: boolean;
  onClick: () => void;
  onRead: (id: string, read: boolean) => void;
  onDelete: (id: string) => void;
};

const NotificationListItem = ({
  notification,
  metaText,
  optionsOpenId,
  onOptionsOpenChange,
  isMarkingRead,
  onClick,
  onRead,
  onDelete,
}: NotificationListItemProps) => {
  const theme = useTheme();
  const moduleValue = String(notification.module);
  const moduleIcon =
    (moduleIcons[moduleValue as keyof typeof moduleIcons] as
      | TablerIcon
      | undefined) || IconBellRinging;

  const brand50 = alpha(theme.palette.primary.main, 0.08);
  const tertiary =
    theme.palette.new?.background?.layout?.tertiary ??
    theme.palette.background.paper;

  return (
    <ListItemButton
      disabled={isMarkingRead}
      onClick={onClick}
      sx={{
        width: '100%',
        p: 2,
        gap: 1,
        flexDirection: 'row',
        alignItems: 'flex-start',
        borderRadius: 0,
        backgroundColor: notification.isRead ? tertiary : brand50,
        '& .more-button': {
          opacity: 0,
        },
        '&:hover .more-button': {
          opacity: 1,
        },
      }}
    >
      <Stack
        sx={{
          gap: 1,
          flexDirection: 'row',
          alignItems: 'flex-start',
          flex: 1,
          minWidth: 0,
        }}
      >
        <NotificationItemAvatar
          notification={notification}
          moduleIcon={moduleIcon}
        />
        <Stack sx={{ flex: 1, minWidth: 0, gap: 0.5 }}>
          {!isNil(notification.text) ? (
            <Typography
              variant="globalXS"
              component="div"
              sx={{
                ...LINE_CLAMP_4,
                // HTMLBody hardcodes its own font styles; inherit the
                // globalXS typography so injected HTML matches the list items
                '& > div': {
                  fontFamily: 'inherit',
                  fontSize: 'inherit',
                  lineHeight: 'inherit',
                },
              }}
            >
              <HTMLBody body={notification.text} />
            </Typography>
          ) : (
            <>
              <Typography
                variant="globalXS"
                fontWeight="fontWeightSemiBold"
                sx={LINE_CLAMP_2}
              >
                {notification.title}
              </Typography>
              <Typography
                variant="globalXS"
                sx={LINE_CLAMP_2}
              >
                {notification.description}
              </Typography>
            </>
          )}
          <Typography
            variant="globalXXS"
            fontWeight="fontWeightRegular"
            color="new.text.neutral.brand"
          >
            {metaText}
          </Typography>
        </Stack>
      </Stack>
      <NotificationsOptions
        notification={notification}
        open={optionsOpenId === notification.id}
        onToggle={() =>
          onOptionsOpenChange(
            optionsOpenId === notification.id ? null : notification.id,
          )
        }
        onClose={() => onOptionsOpenChange(null)}
        isMarkingRead={isMarkingRead}
        onRead={onRead}
        onDelete={onDelete}
      />
    </ListItemButton>
  );
};

export default NotificationListItem;
