import classNames from 'classnames';

import { MouseEvent } from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { useConvoIdFromContext } from '../../../contexts/ConvoIdContext';
import { Data } from '../../../data/data';
import {
  useActiveAt,
  useConversationPropsById,
  useHasUnread,
  useIsForcedUnreadWithoutUnreadMsg,
  useIsPinned,
  useMentionedUs,
  useUnreadCount,
} from '../../../hooks/useParamSelector';
import { Constants } from '../../../session';
import {
  openConversationToSpecificMessage,
  openConversationWithMessages,
} from '../../../state/ducks/conversations';
import { useIsSearching } from '../../../state/selectors/search';
import { getIsMessageSection } from '../../../state/selectors/section';
import { Timestamp } from '../../conversation/Timestamp';
import { SessionIcon } from '../../icon';
import { UserItem } from './UserItem';

const NotificationSettingIcon = () => {
  const isMessagesSection = useSelector(getIsMessageSection);
  const convoId = useConvoIdFromContext();
  const convoSetting = useConversationPropsById(convoId)?.currentNotificationSetting;

  if (!isMessagesSection) {
    return null;
  }

  switch (convoSetting) {
    case 'all':
      return null;
    case 'disabled':
      return (
        <SessionIcon
          iconType="mute"
          iconColor={'var(--conversation-tab-text-color)'}
          iconSize="small"
        />
      );
    case 'mentions_only':
      return (
        <SessionIcon
          iconType="bell"
          iconColor={'var(--conversation-tab-text-color)'}
          iconSize="small"
        />
      );
    default:
      return null;
  }
};

const StyledConversationListItemIconWrapper = styled.div`
  svg {
    margin: 0px 2px;
  }

  display: flex;
  flex-direction: row;
`;

const PinIcon = () => {
  const conversationId = useConvoIdFromContext();

  const isMessagesSection = useSelector(getIsMessageSection);
  const isPinned = useIsPinned(conversationId);

  return isMessagesSection && isPinned ? (
    <SessionIcon iconType="pin" iconColor={'var(--conversation-tab-text-color)'} iconSize="small" />
  ) : null;
};

const ListItemIcons = () => {
  return (
    <StyledConversationListItemIconWrapper>
      <PinIcon />
      <NotificationSettingIcon />
    </StyledConversationListItemIconWrapper>
  );
};

const MentionAtSymbol = styled.span`
  background: var(--unread-messages-alert-background-color);
  color: var(--unread-messages-alert-text-color);
  text-align: center;
  margin-top: 0px;
  margin-bottom: 0px;
  padding-inline-start: 3px;
  padding-inline-end: 3px;

  position: static;
  margin-inline-start: 5px;

  font-weight: 700;
  font-size: var(--font-size-xs);
  letter-spacing: 0.25px;

  height: 16px;
  min-width: 16px;
  border-radius: 8px;
  cursor: pointer;

  &:hover {
    filter: grayscale(0.7);
  }
`;

/**
 * When clicking on the `@` symbol of a conversation, we open the conversation to the first unread message tagging us (with the @pubkey syntax)
 */
async function openConvoToLastMention(e: MouseEvent<HTMLSpanElement>, conversationId: string) {
  e.stopPropagation();
  e.preventDefault();

  // mousedown is invoked sooner than onClick, but for both right and left click
  if (e.button === 0) {
    const oldestMessageUnreadWithMention =
      (await Data.getFirstUnreadMessageWithMention(conversationId)) || null;
    if (oldestMessageUnreadWithMention) {
      await openConversationToSpecificMessage({
        conversationKey: conversationId,
        messageIdToNavigateTo: oldestMessageUnreadWithMention,
        shouldHighlightMessage: true,
      });
    } else {
      window.log.info('cannot open to latest mention as no unread mention are found');
      await openConversationWithMessages({
        conversationKey: conversationId,
        messageId: null,
      });
    }
  }
}

const AtSymbol = ({ convoId }: { convoId: string }) => {
  const hasMentionedUs = useMentionedUs(convoId);
  const hasUnread = useHasUnread(convoId);

  return hasMentionedUs && hasUnread ? (
    <MentionAtSymbol
      title="Open to latest mention"
      // eslint-disable-next-line @typescript-eslint/no-misused-promises
      onMouseDown={async e => openConvoToLastMention(e, convoId)}
    >
      @
    </MentionAtSymbol>
  ) : null;
};

const UnreadCount = ({ convoId }: { convoId: string }) => {
  const unreadMsgCount = useUnreadCount(convoId);
  const forcedUnread = useIsForcedUnreadWithoutUnreadMsg(convoId);

  const unreadWithOverflow =
    unreadMsgCount > Constants.CONVERSATION.MAX_CONVO_UNREAD_COUNT
      ? `${Constants.CONVERSATION.MAX_CONVO_UNREAD_COUNT}+`
      : unreadMsgCount || ' ';

  // TODO would be good to merge the style of this with SessionNotificationCount or SessionUnreadCount at some point.
  return unreadMsgCount > 0 || forcedUnread ? (
    <p className="module-conversation-list-item__unread-count">{unreadWithOverflow}</p>
  ) : null;
};

export const ConversationListItemHeaderItem = () => {
  const conversationId = useConvoIdFromContext();

  const isSearching = useIsSearching();

  const hasUnread = useHasUnread(conversationId);
  const activeAt = useActiveAt(conversationId);

  return (
    <div className="module-conversation-list-item__header">
      <div
        className={classNames(
          'module-conversation-list-item__header__name',
          hasUnread ? 'module-conversation-list-item__header__name--with-unread' : null
        )}
      >
        <UserItem />
      </div>
      <ListItemIcons />

      <UnreadCount convoId={conversationId} />
      <AtSymbol convoId={conversationId} />

      {!isSearching && (
        <div
          className={classNames(
            'module-conversation-list-item__header__date',
            hasUnread ? 'module-conversation-list-item__header__date--has-unread' : null
          )}
        >
          <Timestamp timestamp={activeAt} isConversationSearchResult={false} />
        </div>
      )}
    </div>
  );
};
