import { ipcRenderer } from 'electron';
import React, { SessionDataTestId, useCallback } from 'react';
import { useSelector } from 'react-redux';
import styled from 'styled-components';
import { useMessageExpirationPropsById } from '../../../../hooks/useParamSelector';
import { useMessageStatus } from '../../../../state/selectors';
import { useIsDetailMessageView } from '../../../../contexts/isDetailViewContext';
import { getMostRecentOutgoingMessageId } from '../../../../state/selectors/conversations';
import { useSelectedIsGroupOrCommunity } from '../../../../state/selectors/selectedConversation';
import { SpacerXS } from '../../../basic/Text';
import { SessionIcon, SessionIconType } from '../../../icon';
import { ExpireTimer } from '../../ExpireTimer';
type Props = {
  messageId: string;
  dataTestId: SessionDataTestId;
};
/**
 * MessageStatus is used to display the status of an outgoing OR incoming message.
 * There are 3 parts to this status: a status text, a status icon and a expiring stopwatch.
 * At all times, we either display `text + icon` OR `text + stopwatch`.
 *
 * The logic to display the text is :
 *   - if the message is expiring:
 *        - if the message is incoming: display its 'read' state and the stopwatch icon (1)
 *        - if the message is outgoing: display its status and the stopwatch, unless when the status is error or sending (just display icon and text in this case, no stopwatch) (2)
 *   - if the message is not expiring:
 *        - if the message is incoming: do not show anything (3)
 *        - if the message is outgoing: show the text for the last message, or a message sending, or in the error state. (4)
 */
export const MessageStatus = ({ messageId, dataTestId }: Props) => {
  const isDetailView = useIsDetailMessageView();
  const status = useMessageStatus(messageId);
  const selected = useMessageExpirationPropsById(messageId);
  if (!messageId || !selected || isDetailView) {
    return null;
  }
  const isIncoming = selected.direction === 'incoming';
  if (isIncoming) {
    if (selected.isUnread || !selected.expirationDurationMs || !selected.expirationTimestamp) {
      return null; // incoming and not expiring, this is case (3) above
    }
    // incoming and  expiring, this is case (1) above
    return ;
  }
  switch (status) {
    case 'sending':
      return ; // we always show sending state
    case 'sent':
      return ;
    case 'read':
      return ; // read is used for both incoming and outgoing messages, but not with the same UI
    case 'error':
      return ; // we always show error state
    default:
      return null;
  }
};
const MessageStatusContainer = styled.div<{ isIncoming: boolean; isGroup: boolean }>`
  display: inline-block;
  align-self: ${props => (props.isIncoming ? 'flex-start' : 'flex-end')};
  flex-direction: ${props =>
    props.isIncoming
      ? 'row-reverse'
      : 'row'}; // we want {icon}{text} for incoming read messages, but {text}{icon} for outgoing messages
  margin-bottom: 2px;
  margin-inline-start: 5px;
  cursor: pointer;
  display: flex;
  align-items: center;
  margin-inline-start: ${props =>
    props.isGroup || !props.isIncoming ? 'var(--width-avatar-group-msg-list)' : 0};
`;
const StyledStatusText = styled.div<{ textColor: string }>`
  font-size: small;
  color: ${props => props.textColor};
`;
const TextDetails = ({ text, textColor }: { text: string; textColor: string }) => {
  return (
    <>
      {text}
      
    >
  );
};
function IconDanger({ iconType }: { iconType: SessionIconType }) {
  return ;
}
function IconNormal({
  iconType,
  rotateDuration,
}: {
  iconType: SessionIconType;
  rotateDuration?: number | undefined;
}) {
  return (
    
  );
}
function useIsExpiring(messageId: string) {
  const selected = useMessageExpirationPropsById(messageId);
  return (
    selected && selected.expirationDurationMs && selected.expirationTimestamp && !selected.isExpired
  );
}
function useIsMostRecentOutgoingMessage(messageId: string) {
  const mostRecentOutgoingMessageId = useSelector(getMostRecentOutgoingMessageId);
  return mostRecentOutgoingMessageId === messageId;
}
function MessageStatusExpireTimer(props: Pick) {
  const selected = useMessageExpirationPropsById(props.messageId);
  if (
    !selected ||
    !selected.expirationDurationMs ||
    !selected.expirationTimestamp ||
    selected.isExpired
  ) {
    return null;
  }
  return (
    
  );
}
const MessageStatusSending = ({ dataTestId }: Omit) => {
  // while sending, we do not display the expire timer at all.
  return (
    
      
      
    
  );
};
/**
 * Returns the correct expiring stopwatch icon if this message is expiring, or a normal status icon otherwise.
 * Only to be used with the status "read" and "sent"
 */
function IconForExpiringMessageId({
  messageId,
  iconType,
}: Pick & { iconType: SessionIconType }) {
  const isExpiring = useIsExpiring(messageId);
  return isExpiring ? (
    
  ) : (
    
  );
}
const MessageStatusSent = ({ dataTestId, messageId }: Omit) => {
  const isExpiring = useIsExpiring(messageId);
  const isMostRecentOutgoingMessage = useIsMostRecentOutgoingMessage(messageId);
  const isGroup = useSelectedIsGroupOrCommunity();
  // we hide the "sent" message status for a non-expiring messages unless it's the most recent outgoing message
  if (!isExpiring && !isMostRecentOutgoingMessage) {
    return null;
  }
  return (
    
      
      
    
  );
};
const MessageStatusRead = ({
  dataTestId,
  messageId,
  isIncoming,
}: Omit & { isIncoming: boolean }) => {
  const isExpiring = useIsExpiring(messageId);
  const isGroup = useSelectedIsGroupOrCommunity();
  const isMostRecentOutgoingMessage = useIsMostRecentOutgoingMessage(messageId);
  // we hide an outgoing "read" message status which is not expiring except for the most recent message
  if (!isIncoming && !isExpiring && !isMostRecentOutgoingMessage) {
    return null;
  }
  return (
    
      
      
    
  );
};
const MessageStatusError = ({ dataTestId }: Omit) => {
  const showDebugLog = useCallback(() => {
    ipcRenderer.send('show-debug-log');
  }, []);
  // when on error, we do not display the expire timer at all.
  const isGroup = useSelectedIsGroupOrCommunity();
  return (
    
      
      
    
  );
};