/*
 * Copyright (C) 2022 Savoir-faire Linux Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with this program.  If not, see
 * <https://www.gnu.org/licenses/>.
 */
import { Box, Chip, Divider, Link, Stack, Tooltip, Typography } from '@mui/material';
import { styled } from '@mui/material/styles';
import dayjs, { Dayjs } from 'dayjs';
import { Message } from 'jami-web-common';
import Linkify from 'linkify-react';
import * as linkify from 'linkifyjs';
import { ReactElement, ReactNode, useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { Account } from '../models/account';
import { Contact } from '../models/contact';
import { useLinkPreviewQuery } from '../services/linkPreviewQueries';
import { getMessageCallText, getMessageMemberText } from '../utils/chatmessages';
import { formatRelativeDate, formatTime } from '../utils/dates&times';
import { EmojiButton, MoreButton, ReplyMessageButton } from './Button';
import ConversationAvatar from './ConversationAvatar';
import LoadingPage from './Loading';
import PopoverList, { PopoverListItemData } from './PopoverList';
import {
  ArrowLeftCurved,
  ArrowLeftDown,
  ArrowRightUp,
  OppositeArrowsIcon,
  TrashBinIcon,
  TwoSheetsIcon,
} from './SvgIcon';

type MessagePosition = 'start' | 'end';

const notificationMessageTypes = ['initial', 'member'] as const;
type NotificationMessageType = typeof notificationMessageTypes[number];
const checkIsNotificationMessageType = (type: Message['type'] | undefined): type is NotificationMessageType => {
  return notificationMessageTypes.includes(type as NotificationMessageType);
};

const invisibleMessageTypes = ['application/update-profile', 'merge', 'vote'] as const;
type InvisibleMessageType = typeof invisibleMessageTypes[number];
const checkIsInvisibleMessageType = (type: Message['type'] | undefined): type is InvisibleMessageType => {
  return invisibleMessageTypes.includes(type as InvisibleMessageType);
};

const userMessageTypes = ['text/plain', 'application/data-transfer+json', 'application/call-history+json'] as const;
type UserMessageType = typeof userMessageTypes[number];
const checkIsUserMessageType = (type: Message['type'] | undefined): type is UserMessageType => {
  return userMessageTypes.includes(type as UserMessageType);
};

const checkShowsTime = (time: Dayjs, previousTime: Dayjs) => {
  return !previousTime.isSame(time) && !time.isBetween(previousTime, previousTime?.add(1, 'minute'));
};

const findPreviousVisibleMessage = (messages: Message[], messageIndex: number) => {
  for (let i = messageIndex + 1; i < messages.length; ++i) {
    const message = messages[i];
    if (!checkIsInvisibleMessageType(message?.type)) {
      return message;
    }
  }
};

const findNextVisibleMessage = (messages: Message[], messageIndex: number) => {
  for (let i = messageIndex - 1; i >= 0; --i) {
    const message = messages[i];
    if (!checkIsInvisibleMessageType(message?.type)) {
      return message;
    }
  }
};

const avatarSize = '22px';
const spacingBetweenAvatarAndBubble = '10px';
const bubblePadding = '16px';

interface MessageCallProps {
  message: Message;
  isAccountMessage: boolean;
  isFirstOfGroup: boolean;
  isLastOfGroup: boolean;
}

const MessageCall = ({ message, isAccountMessage, isFirstOfGroup, isLastOfGroup }: MessageCallProps) => {
  const position = isAccountMessage ? 'end' : 'start';

  const { i18n } = useTranslation();
  const { bubbleColor, Icon, text, textColor } = useMemo(() => {
    const text = getMessageCallText(isAccountMessage, message, i18n);
    const callDuration = dayjs.duration(parseInt(message?.duration || ''));
    if (callDuration.asSeconds() === 0) {
      if (isAccountMessage) {
        return {
          text,
          Icon: ArrowLeftCurved,
          textColor: 'white',
          bubbleColor: '#005699' + '80', // opacity 50%
        };
      } else {
        return {
          text,
          Icon: ArrowLeftCurved,
          textColor: 'black',
          bubbleColor: '#C6C6C6',
        };
      }
    } else {
      if (isAccountMessage) {
        return {
          text,
          Icon: ArrowRightUp,
          textColor: 'white',
          bubbleColor: '#005699',
        };
      } else {
        return {
          text,
          Icon: ArrowLeftDown,
          textcolor: 'black',
          bubbleColor: '#E5E5E5',
        };
      }
    }
  }, [isAccountMessage, message, i18n]);

  return (
    <Bubble position={position} isFirstOfGroup={isFirstOfGroup} isLastOfGroup={isLastOfGroup} bubbleColor={bubbleColor}>
      <Stack direction="row" spacing="10px" alignItems="center">
        <Icon sx={{ fontSize: '16px', color: textColor }} />
        <Typography variant="body1" color={textColor} textAlign={position} fontWeight="bold" textTransform="uppercase">
          {text}
        </Typography>
      </Stack>
    </Bubble>
  );
};

const MessageInitial = () => {
  const { t } = useTranslation();
  return <>{t('message_swarm_created')}</>;
};

interface MessageDataTransferProps {
  message: Message;
  isAccountMessage: boolean;
  isFirstOfGroup: boolean;
  isLastOfGroup: boolean;
}

const MessageDataTransfer = ({ isAccountMessage, isFirstOfGroup, isLastOfGroup }: MessageDataTransferProps) => {
  const position = isAccountMessage ? 'end' : 'start';
  return (
    <Bubble bubbleColor="#E5E5E5" position={position} isFirstOfGroup={isFirstOfGroup} isLastOfGroup={isLastOfGroup}>
      &quot;data-transfer&quot;
    </Bubble>
  );
};

interface MessageMemberProps {
  message: Message;
}

const MessageMember = ({ message }: MessageMemberProps) => {
  const { i18n } = useTranslation();

  const text = getMessageMemberText(message, i18n);
  return (
    <Chip
      sx={{
        width: 'fit-content',
      }}
      label={text}
    />
  );
};

type LinkPreviewProps = {
  isAccountMessage: boolean;
  link: string;
};

const LinkPreview = ({ isAccountMessage, link }: LinkPreviewProps) => {
  const [imageIsWorking, setImageIsWorking] = useState(true);
  const linkPreviewQuery = useLinkPreviewQuery(link);
  if (linkPreviewQuery.isLoading) {
    return <LoadingPage />;
  }
  if (!linkPreviewQuery.isSuccess) {
    return null;
  }
  const linkPreview = linkPreviewQuery.data;

  return (
    <a href={link} style={{ textDecorationLine: 'none' }}>
      <Stack>
        {imageIsWorking && linkPreview.image && (
          <img
            style={{
              padding: '15px 0',
            }}
            alt={linkPreview.title}
            src={linkPreview.image}
            onError={() => setImageIsWorking(false)}
          />
        )}
        <Typography variant="body1" color={isAccountMessage ? '#cccccc' : 'black'}>
          {linkPreview.title}
        </Typography>
        {linkPreview.description && (
          <Typography variant="body1" sx={{ color: isAccountMessage ? '#ffffff' : '#005699' }}>
            {linkPreview.description}
          </Typography>
        )}
        <Typography variant="body1" color={isAccountMessage ? '#cccccc' : 'black'}>
          {new URL(link).hostname}
        </Typography>
      </Stack>
    </a>
  );
};

type RenderLinkProps = {
  attributes: {
    isAccountMessage: boolean;
    href: string;
  };
  content: ReactNode;
};

const RenderLink = ({ attributes, content }: RenderLinkProps) => {
  const { href, isAccountMessage, ...props } = attributes;
  return (
    <Link href={href} {...props} variant="body1" color={isAccountMessage ? '#ffffff' : undefined}>
      {content}
    </Link>
  );
};

interface MessageTextProps {
  message: Message;
  isAccountMessage: boolean;
  isFirstOfGroup: boolean;
  isLastOfGroup: boolean;
}

const MessageText = ({ message, isAccountMessage, isFirstOfGroup, isLastOfGroup }: MessageTextProps) => {
  const position = isAccountMessage ? 'end' : 'start';
  const bubbleColor = isAccountMessage ? '#005699' : '#E5E5E5';
  const textColor = isAccountMessage ? 'white' : 'black';

  const link = useMemo(() => linkify.find(message?.body ?? '', 'url')[0]?.href, [message]);

  return (
    <MessageTooltip position={position}>
      <Bubble
        bubbleColor={bubbleColor}
        position={position}
        isFirstOfGroup={isFirstOfGroup}
        isLastOfGroup={isLastOfGroup}
        maxWidth={link ? '400px' : undefined}
      >
        <Typography variant="body1" color={textColor} textAlign={position}>
          <Linkify options={{ render: RenderLink as any, attributes: { isAccountMessage } }}>{message.body}</Linkify>
        </Typography>
        {link && <LinkPreview isAccountMessage={isAccountMessage} link={link} />}
      </Bubble>
    </MessageTooltip>
  );
};

interface DateIndicatorProps {
  time: Dayjs;
}

const DateIndicator = ({ time }: DateIndicatorProps) => {
  const { i18n } = useTranslation();
  const textDate = useMemo(() => formatRelativeDate(time, i18n), [time, i18n]);

  return (
    <Box marginTop="30px">
      <Divider
        sx={{
          '.MuiDivider-wrapper': {
            margin: 0,
            padding: 0,
          },
          '&::before': {
            borderTop: '1px solid #E5E5E5',
          },
          '&::after': {
            borderTop: '1px solid #E5E5E5',
          },
        }}
      >
        <Typography
          variant="caption"
          fontWeight={700}
          border="1px solid #E5E5E5"
          borderRadius="5px"
          padding="10px 16px"
          textTransform="capitalize"
        >
          {textDate}
        </Typography>
      </Divider>
    </Box>
  );
};

interface TimeIndicatorProps {
  time: Dayjs;
  hasDateOnTop: boolean;
}

const TimeIndicator = ({ time, hasDateOnTop }: TimeIndicatorProps) => {
  const { i18n } = useTranslation();
  const textTime = useMemo(() => formatTime(time, i18n), [time, i18n]);

  return (
    <Stack direction="row" justifyContent="center" marginTop={hasDateOnTop ? '20px' : '30px'}>
      <Typography variant="caption" color="#A7A7A7" fontWeight={700}>
        {textTime}
      </Typography>
    </Stack>
  );
};

interface NotificationMessageRowProps {
  message: Message;
}

const NotificationMessageRow = ({ message }: NotificationMessageRowProps) => {
  let messageComponent;
  switch (message.type) {
    case 'initial':
      messageComponent = <MessageInitial />;
      break;
    case 'member':
      messageComponent = <MessageMember message={message} />;
      break;
    default:
      console.error(`${NotificationMessageRow.name} received unhandled message type: ${message.type}`);
      return null;
  }

  return (
    <Stack paddingTop={'30px'} alignItems="center">
      {messageComponent}
    </Stack>
  );
};

interface UserMessageRowProps {
  message: Message;
  isAccountMessage: boolean;
  previousMessage: Message | undefined;
  nextMessage: Message | undefined;
  time: Dayjs;
  showsTime: boolean;
  author: Account | Contact;
}

const UserMessageRow = ({
  message,
  previousMessage,
  nextMessage,
  isAccountMessage,
  time,
  showsTime,
  author,
}: UserMessageRowProps) => {
  const authorName = author.getDisplayName();
  const position = isAccountMessage ? 'end' : 'start';

  const previousIsUserMessageType = checkIsUserMessageType(previousMessage?.type);
  const nextIsUserMessageType = checkIsUserMessageType(nextMessage?.type);
  const nextTime = dayjs.unix(Number(nextMessage?.timestamp));
  const nextShowsTime = checkShowsTime(nextTime, time);
  const isFirstOfGroup = showsTime || !previousIsUserMessageType || previousMessage?.author !== message.author;
  const isLastOfGroup = nextShowsTime || !nextIsUserMessageType || message.author !== nextMessage?.author;

  const props = {
    message,
    isAccountMessage,
    isFirstOfGroup,
    isLastOfGroup,
  };

  let MessageComponent;
  switch (message.type) {
    case 'text/plain':
      MessageComponent = MessageText;
      break;
    case 'application/data-transfer+json':
      MessageComponent = MessageDataTransfer;
      break;
    case 'application/call-history+json':
      MessageComponent = MessageCall;
      break;
    default:
      console.error(`${UserMessageRow.name} received unhandled message type: ${message.type}`);
      return null;
  }

  const participantNamePadding = isAccountMessage
    ? bubblePadding
    : parseInt(avatarSize) + parseInt(spacingBetweenAvatarAndBubble) + parseInt(bubblePadding) + 'px';

  return (
    <Stack alignItems={position}>
      {isFirstOfGroup && (
        <Box padding={`30px ${participantNamePadding} 0 ${participantNamePadding}`}>
          <ParticipantName name={authorName} />
        </Box>
      )}
      <Stack
        direction="row"
        justifyContent={position}
        alignItems="end"
        spacing={spacingBetweenAvatarAndBubble}
        paddingTop="6px"
        width="66.66%"
      >
        <Box sx={{ width: avatarSize }}>
          {!isAccountMessage && isLastOfGroup && (
            <ConversationAvatar
              displayName={authorName}
              sx={{ width: avatarSize, height: avatarSize, fontSize: '15px' }}
            />
          )}
        </Box>
        <MessageComponent {...props} />
      </Stack>
    </Stack>
  );
};

interface MessageTooltipProps {
  className?: string;
  position: MessagePosition;
  children: ReactElement;
}

const MessageTooltip = styled(({ className, position, children }: MessageTooltipProps) => {
  const [open, setOpen] = useState(false);
  const emojis = ['😎', '😄', '😍']; // Should be last three used emojis
  const additionalOptions: PopoverListItemData[] = [
    {
      Icon: TwoSheetsIcon,
      label: 'Copy',
      onClick: () => {},
    },
    {
      Icon: OppositeArrowsIcon,
      label: 'Transfer',
      onClick: () => {},
    },
    {
      Icon: TrashBinIcon,
      label: 'Delete message',
      onClick: () => {},
    },
  ];

  const toggleMoreMenu = useCallback(() => setOpen((open) => !open), [setOpen]);

  const onClose = useCallback(() => {
    setOpen(false);
  }, [setOpen]);

  return (
    <Tooltip
      classes={{ tooltip: className }} // Required for styles. Don't know why
      placement={position === 'start' ? 'right-start' : 'left-start'}
      PopperProps={{
        modifiers: [
          {
            name: 'offset',
            options: {
              offset: [-2, -30],
            },
          },
        ],
      }}
      onClose={onClose}
      title={
        <Stack>
          <Stack // Main options
            direction="row"
            spacing="16px"
            padding="16px"
          >
            {emojis.map((emoji) => (
              <EmojiButton key={emoji} emoji={emoji} />
            ))}
            <ReplyMessageButton />
            <MoreButton onClick={toggleMoreMenu} />
          </Stack>
          {open && (
            <>
              <Divider sx={{ marginX: '16px' }} />
              <PopoverList items={additionalOptions} />
            </>
          )}
        </Stack>
      }
    >
      {/* div fixes 'Function components cannot be given refs' error */}
      <div>{children}</div>
    </Tooltip>
  );
})(({ position }) => {
  const largeRadius = '20px';
  const smallRadius = '5px';
  return {
    backgroundColor: 'white',
    padding: '0px',
    boxShadow: '3px 3px 7px #00000029',
    borderRadius: largeRadius,
    borderStartStartRadius: position === 'start' ? smallRadius : largeRadius,
    borderStartEndRadius: position === 'end' ? smallRadius : largeRadius,
    overflow: 'hidden',
  };
});

interface BubbleProps {
  position: MessagePosition;
  isFirstOfGroup: boolean;
  isLastOfGroup: boolean;
  bubbleColor: string;
  maxWidth?: string;
  children: ReactNode;
}

const Bubble = ({ position, isFirstOfGroup, isLastOfGroup, bubbleColor, maxWidth, children }: BubbleProps) => {
  const largeRadius = '20px';
  const smallRadius = '5px';
  const radius = useMemo(() => {
    if (position === 'start') {
      return {
        borderStartStartRadius: isFirstOfGroup ? largeRadius : smallRadius,
        borderStartEndRadius: largeRadius,
        borderEndStartRadius: isLastOfGroup ? largeRadius : smallRadius,
        borderEndEndRadius: largeRadius,
      };
    }
    return {
      borderStartStartRadius: largeRadius,
      borderStartEndRadius: isFirstOfGroup ? largeRadius : smallRadius,
      borderEndStartRadius: largeRadius,
      borderEndEndRadius: isLastOfGroup ? largeRadius : smallRadius,
    };
  }, [isFirstOfGroup, isLastOfGroup, position]);

  return (
    <Box
      sx={{
        width: 'fit-content',
        maxWidth,
        backgroundColor: bubbleColor,
        padding: bubblePadding,
        overflow: 'hidden',
        wordWrap: 'break-word',
        ...radius,
      }}
    >
      {children}
    </Box>
  );
};

interface ParticipantNameProps {
  name: string;
}

const ParticipantName = ({ name }: ParticipantNameProps) => {
  return (
    <Typography variant="caption" color="#A7A7A7" fontWeight={700}>
      {name}
    </Typography>
  );
};

interface MessageProps {
  messageIndex: number;
  messages: Message[];
  isAccountMessage: boolean;
  author: Account | Contact;
}

export const MessageRow = ({ messageIndex, messages, isAccountMessage, author }: MessageProps) => {
  const message = messages[messageIndex];
  const previousMessage = findPreviousVisibleMessage(messages, messageIndex);
  const nextMessage = findNextVisibleMessage(messages, messageIndex);
  const time = dayjs.unix(Number(message.timestamp));
  const previousTime = dayjs.unix(Number(previousMessage?.timestamp));
  const showDate =
    message?.type === 'initial' || previousTime.year() !== time.year() || previousTime.dayOfYear() !== time.dayOfYear();
  const showTime = checkShowsTime(time, previousTime);
  let messageComponent;
  if (checkIsUserMessageType(message.type)) {
    messageComponent = (
      <UserMessageRow
        message={message}
        previousMessage={previousMessage}
        nextMessage={nextMessage}
        time={time}
        showsTime={showTime}
        isAccountMessage={isAccountMessage}
        author={author}
      />
    );
  } else if (checkIsNotificationMessageType(message.type)) {
    messageComponent = <NotificationMessageRow message={message} />;
  } else if (checkIsInvisibleMessageType(message.type)) {
    return null;
  } else {
    const _exhaustiveCheck: never = message.type;
    return _exhaustiveCheck;
  }

  return (
    <Stack>
      {showDate && <DateIndicator time={time} />}
      {showTime && <TimeIndicator time={time} hasDateOnTop={showDate} />}
      {messageComponent}
    </Stack>
  );
};
