import { type FC, Fragment, type SyntheticEvent, useMemo } from 'react';
import { useParams } from 'react-router-dom';

import {
  IconAt,
  IconBellOff,
  IconCamera,
  IconChevronDown,
  IconFile,
  IconMicrophone,
  IconPin,
  IconVideo,
} from '@material-hu/icons/tabler';
import Divider from '@material-hu/mui/Divider';
import IconButton from '@material-hu/mui/IconButton';
import ListItemButton from '@material-hu/mui/ListItemButton';
import Stack from '@material-hu/mui/Stack';
import { type Theme, useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import HuBadge from '@material-hu/components/design-system/Badge';
import HuCheckbox from '@material-hu/components/design-system/Checkbox/Checkbox';

import { useAuth } from 'src/contexts/JWTContext';
import {
  BUNNY_IMAGE_CLASSES,
  CONVERSATIONS_LIST_DIVIDER,
  CONVERSATIONS_ROW_LIST_ITEM,
} from 'src/pages/dashboard/Conversations/constants';
import {
  type Channel,
  type ConversationUser,
  MessageTypeSocket,
  NotificationType,
} from 'src/pages/dashboard/Conversations/types';
import {
  compareIds,
  getCorrectIconType,
  getDataUserItem,
  getDisplayUser,
  getIsSelfConversation,
  getMessageState,
  getSystemMessageText,
  isForwardedMessage,
  isKnownBlockType,
  isReplyMessage,
} from 'src/pages/dashboard/Conversations/utils';
import { formatTimestampInChatList } from 'src/utils/date';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getInitials } from 'src/utils/userUtils';

import { useConversationMenuOpen } from '../../stores/menuStore';
import TypographyTagAndLinkSensitive from '../ConversationsThread/ConversationMessage/TypographyTagAndLinkSensitive';
import LazySecureImage from '../shared/LazySecureImage';
import MessageState from '../shared/MessageState';

import ConversationItemIconMenu from './ConversationItemIconMenu';

type ConversationItemProps = {
  onClick: ({
    conversation,
    user,
  }: {
    conversation?: Channel;
    user?: ConversationUser;
  }) => void;
  conversation: Channel;
  pinnedConversationsCount: number;
  withInternalDetails?: boolean;
  withCheckbox?: boolean;
  disabledCheckbox?: boolean;
  selectedConversations?: Channel[];
  selectedUsers?: ConversationUser[];
};

const SIZE_ICON = 16;

const MENU_TRIGGER_CLASS = 'ConversationItem-menuTrigger';

const iconStyle = { verticalAlign: 'text-bottom' };
const ellipsisStyle = {
  overflow: 'hidden',
  textOverflow: 'ellipsis',
  whiteSpace: 'nowrap',
  minWidth: 0,
};

const iconType = (theme: Theme): Record<string, React.ReactNode> => {
  const iconColor = theme.palette.new.text.neutral.lighter;
  return {
    video: (
      <IconVideo
        color={iconColor}
        style={iconStyle}
      />
    ),
    image: (
      <IconCamera
        color={iconColor}
        style={iconStyle}
      />
    ),
    gif: (
      <Typography
        component="span"
        sx={{
          lineHeight: 1,
        }}
      >
        👾
      </Typography>
    ),
    audio: (
      <IconMicrophone
        color={iconColor}
        style={iconStyle}
      />
    ),
    file: (
      <IconFile
        color={iconColor}
        style={iconStyle}
      />
    ),
  };
};

const ConversationItem: FC<ConversationItemProps> = props => {
  const {
    onClick,
    conversation,
    pinnedConversationsCount,
    withInternalDetails = true,
    withCheckbox = false,
    disabledCheckbox = false,
    selectedConversations = [],
    selectedUsers = [],
  } = props;

  const {
    isOpen: isMenuOpen,
    open: openMenu,
    close: closeMenu,
  } = useConversationMenuOpen(conversation.id);
  const { t } = useLokaliseTranslation(['chat', 'general']);
  const { id } = useParams();

  const theme = useTheme();

  const { latest } = conversation;

  const { user: loggedUser } = useAuth();

  const isGroupConversation = !!conversation.is_channel;
  const isLoggedUserMessage = compareIds(latest.user, loggedUser?.id);
  const systemMessages = latest?.blocks ?? null;
  const isKnowBlock = !!(systemMessages && isKnownBlockType(systemMessages));
  const isDeleted = latest?.subtype === MessageTypeSocket.DELETED;
  const isReplyMessageType = systemMessages && isReplyMessage(systemMessages);
  const isForwardMessageType =
    systemMessages && isForwardedMessage(systemMessages);
  const shouldShowUser =
    isGroupConversation &&
    (!systemMessages || isReplyMessageType || isForwardMessageType);

  const isSelfConversation = getIsSelfConversation(
    Number(conversation.user),
    loggedUser?.id,
    isGroupConversation,
  );
  const isCheckedUser = !!selectedUsers?.some(
    user => user.id === conversation.user,
  );
  const isCheckedConversation = !!selectedConversations?.some(
    conv => conv.id === conversation.id,
  );
  const isChecked = isCheckedUser || isCheckedConversation;

  const shouldShowMentionTag = !!(
    conversation.hu_data.mentioned && conversation.unread_count_display > 0
  );

  const displayUser = getDisplayUser({
    isGroupConversation,
    isUser: isLoggedUserMessage,
    t,
    username: latest.username,
  });

  const conversationText = getSystemMessageText({
    text: latest.text,
    t,
    username: latest.username || '',
    systemMessages,
    isUser: isLoggedUserMessage,
    isSidebarMsg: true,
    attachments: latest.attachments,
    userId: loggedUser?.id,
    isKnowBlock,
    isDeleted,
  });
  const userToShow = getDataUserItem(
    t,
    isSelfConversation,
    isGroupConversation,
    conversation.hu_data,
    loggedUser,
  );

  const messageState = getMessageState({
    readAt: latest.read_status?.read_at,
    receivedAt: latest.read_status?.received_at,
    isSelfConversation,
  });

  const hasUnread =
    conversation.unread_count_display > 0 ||
    !!conversation.properties.marked_unread_at;
  const unreadCount =
    conversation.unread_count_display > 0
      ? conversation.unread_count_display
      : '';
  const isMentionConversation =
    conversation.properties?.notification_status?.notification_type ===
    NotificationType.MENTIONS;

  const isPinConversation = !!conversation.properties?.pinned_at;

  const handleOnClick = () =>
    !(disabledCheckbox && !isChecked) && onClick({ conversation });

  const handleOpenMenu = (e: SyntheticEvent) => {
    e.stopPropagation();
    openMenu();
  };

  const handleRightClick = (event: React.MouseEvent) => {
    event.stopPropagation();
    event.preventDefault();
    handleOpenMenu(event);
  };

  const pictureUrl = isGroupConversation
    ? conversation.hu_data.picture_url
    : userToShow?.picture;

  const showIconsList = useMemo(
    () => [
      {
        id: 'icon-bell-off',
        enabled: isMentionConversation,
        icon: (
          <IconBellOff
            size={16}
            color={theme.palette.new.text.neutral.default}
          />
        ),
      },
      {
        id: 'icon-pin',
        enabled: isPinConversation,
        icon: (
          <IconPin
            size={16}
            color={theme.palette.new.text.neutral.default}
          />
        ),
      },
      {
        id: 'icon-at',
        enabled: shouldShowMentionTag,
        icon: (
          <IconAt
            size={16}
            color={theme.palette.new.graphics.brand[500]}
          />
        ),
      },
      {
        id: 'icon-unread',
        enabled: hasUnread,
        icon: (
          <HuBadge
            badgeContent={unreadCount}
            color="primary"
            sx={{
              '& .MuiBadge-badge': {
                position: 'static',
                transform: 'none',
              },
            }}
          />
        ),
      },
    ],
    [
      isMentionConversation,
      isPinConversation,
      shouldShowMentionTag,
      hasUnread,
      unreadCount,
      theme,
    ],
  );

  const filteredShowIconsList = showIconsList.filter(option => option.enabled);

  const isThreadSelected = conversation.id === id && withInternalDetails;

  return (
    <>
      <ListItemButton
        className={CONVERSATIONS_ROW_LIST_ITEM}
        data-selected={isThreadSelected}
        onClick={handleOnClick}
        onContextMenu={handleRightClick}
        disableRipple
        sx={{
          p: 0,
          px: 2,
          backgroundColor: isThreadSelected
            ? theme.palette.new.background.layout.default
            : 'transparent',
          [`&:hover .${MENU_TRIGGER_CLASS}`]: {
            display: 'inline-flex',
          },
        }}
      >
        {withCheckbox && (
          <HuCheckbox
            sx={{ zIndex: 0, mr: 1 }}
            label=""
            disabled={disabledCheckbox && !isChecked}
            checked={isChecked}
            onClick={e => {
              e.stopPropagation();
              handleOnClick();
            }}
          />
        )}
        <Stack
          sx={{
            my: 2,
            flexDirection: 'row',
            gap: 1,
            width: '100%',
          }}
        >
          <LazySecureImage
            url={pictureUrl}
            isAvatar
            imageClass={BUNNY_IMAGE_CLASSES.AVATAR}
            avatarProps={{
              text: getInitials(userToShow?.name || ''),
            }}
          />
          <Stack sx={{ flex: 1, minWidth: 0 }}>
            <Stack
              sx={{
                flexDirection: 'row',
                justifyContent: 'space-between',
                alignItems: 'center',
                gap: 1,
              }}
            >
              <Typography
                variant="globalS"
                fontWeight="fontWeightSemiBold"
                sx={{ ...ellipsisStyle, maxWidth: '206px', flex: 1 }}
              >
                {isGroupConversation ? conversation.name : userToShow?.name}
              </Typography>
              {withInternalDetails && latest && (
                <Stack
                  sx={{
                    flexDirection: 'row',
                    alignItems: 'center',
                    flexShrink: 0,
                  }}
                >
                  <Typography
                    variant="globalXXS"
                    fontWeight="fontWeightRegular"
                    color={theme.palette.new.text.neutral.lighter}
                  >
                    {formatTimestampInChatList(latest.ts, loggedUser, t)}
                  </Typography>
                  <IconButton
                    className={MENU_TRIGGER_CLASS}
                    variant="tertiary"
                    onClick={handleOpenMenu}
                    disableRipple
                    sx={{
                      p: 0,
                      display: 'none',
                      '&:hover': {
                        backgroundColor: 'transparent',
                      },
                    }}
                  >
                    <IconChevronDown
                      size={16}
                      color={theme.palette.new.text.neutral.default}
                    />
                  </IconButton>
                </Stack>
              )}
            </Stack>
            {withInternalDetails &&
              latest &&
              (conversationText || filteredShowIconsList.length > 0) && (
                <Stack
                  sx={{
                    flexDirection: 'row',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    gap: 1,
                  }}
                >
                  {conversationText && (
                    <Typography
                      variant="globalXS"
                      color={theme.palette.new.text.neutral.lighter}
                      fontStyle={isDeleted ? 'italic' : 'normal'}
                      fontWeight="fontWeightRegular"
                      sx={{
                        ...ellipsisStyle,
                        display: 'flex',
                        gap: 0.5,
                        alignItems: 'center',
                        flex: 1,
                      }}
                    >
                      <MessageState
                        state={messageState}
                        theme={theme}
                        isSystemMessage={Boolean(isKnowBlock)}
                        isReplyMessageType={Boolean(isReplyMessageType)}
                        isForwardMessageType={Boolean(isForwardMessageType)}
                        isLoggedUserMessage={isLoggedUserMessage}
                        hidden={isDeleted}
                        style={{
                          verticalAlign: 'middle',
                          flexShrink: 0,
                        }}
                      />
                      {shouldShowUser && displayUser}
                      {!!latest.attachments?.length && !isDeleted && (
                        <Stack
                          component="span"
                          sx={{
                            width: SIZE_ICON,
                            height: SIZE_ICON,
                            alignItems: 'center',
                            flexShrink: 0,
                          }}
                        >
                          {
                            iconType(theme)[
                              getCorrectIconType(latest.attachments)
                            ]
                          }
                        </Stack>
                      )}
                      <TypographyTagAndLinkSensitive
                        variant="globalXS"
                        color={theme.palette.new.text.neutral.lighter}
                        fontStyle={isDeleted ? 'italic' : 'normal'}
                        fontWeight="fontWeightRegular"
                        sx={ellipsisStyle}
                        disableLink
                        highlightedSpans={latest.highlighted_spans}
                      >
                        {conversationText}
                      </TypographyTagAndLinkSensitive>
                    </Typography>
                  )}
                  {!conversationText && <Stack sx={{ flex: 1 }} />}
                  {filteredShowIconsList.length > 0 && (
                    <Stack
                      sx={{
                        flexDirection: 'row',
                        justifyContent: 'flex-end',
                        alignItems: 'center',
                        gap: 0.2,
                        flexShrink: 0,
                        '& .MuiBadge-badge': {
                          lineHeight: '0px',
                        },
                      }}
                    >
                      {filteredShowIconsList.map(option => (
                        <Fragment key={option.id}>{option.icon}</Fragment>
                      ))}
                    </Stack>
                  )}
                </Stack>
              )}
          </Stack>
        </Stack>
      </ListItemButton>
      <Divider
        className={CONVERSATIONS_LIST_DIVIDER}
        sx={{
          mx: 2,
          transition: theme.transitions.create('margin', {
            duration: theme.transitions.duration.shorter,
          }),
        }}
      />
      <ConversationItemIconMenu
        conversation={conversation}
        conversationId={conversation.id}
        open={isMenuOpen}
        pinnedConversationsCount={pinnedConversationsCount}
        onCloseMenu={closeMenu}
        onCloseMenuOnLeave={closeMenu}
      />
    </>
  );
};

export default ConversationItem;
