/*
 * 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, Divider, Fade, Stack, Typography } from '@mui/material';
import { motion } from 'framer-motion';
import { ConversationMessage, Message, WebSocketMessageType } from 'jami-web-common';
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { useTranslation } from 'react-i18next';

import { FilePreviewRemovable } from '../components/FilePreview';
import LoadingPage from '../components/Loading';
import MessageList from '../components/MessageList';
import { FileDragOverlay } from '../components/Overlay';
import SendMessageForm from '../components/SendMessageForm';
import { useConversationContext } from '../contexts/ConversationProvider';
import { WebSocketContext } from '../contexts/WebSocketProvider';
import { ConversationMember } from '../models/conversation-member';
import { useMessagesQuery, useSendMessageMutation } from '../services/conversationQueries';
import { FileHandler } from '../utils/files';
import { translateEnumeration, TranslateEnumerationOptions } from '../utils/translations';

const ChatInterface = () => {
  const webSocket = useContext(WebSocketContext);
  const { conversationId } = useConversationContext();
  const [messages, setMessages] = useState<Message[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(false);

  const messagesQuery = useMessagesQuery(conversationId);
  const sendMessageMutation = useSendMessageMutation(conversationId);

  const [fileHandlers, setFileHandlers] = useState<FileHandler[]>([]);

  const onFilesDrop = useCallback(
    (acceptedFiles: File[]) => {
      const newFileHandlers = acceptedFiles.map((file) => new FileHandler(file));
      setFileHandlers((oldFileHandlers) => [...oldFileHandlers, ...newFileHandlers]);
    },
    [setFileHandlers]
  );

  const removeFile = useCallback(
    (fileId: string | number) => {
      setFileHandlers((fileHandlers) => fileHandlers.filter((fileHandler) => fileHandler.id !== fileId));
    },
    [setFileHandlers]
  );

  const {
    getRootProps,
    getInputProps,
    open: openFilePicker,
    isDragActive,
  } = useDropzone({
    onDrop: onFilesDrop,
    noClick: true,
    noKeyboard: true,
  });

  useEffect(() => {
    if (messagesQuery.isSuccess) {
      const sortedMessages = sortMessages(messagesQuery.data);
      setMessages(sortedMessages);
    }
  }, [messagesQuery.isSuccess, messagesQuery.data]);

  useEffect(() => {
    setIsLoading(messagesQuery.isLoading);
  }, [messagesQuery.isLoading]);

  useEffect(() => {
    setError(messagesQuery.isError);
  }, [messagesQuery.isError]);

  const sendMessage = useCallback((message: string) => sendMessageMutation.mutate(message), [sendMessageMutation]);

  useEffect(() => {
    if (webSocket) {
      const conversationMessageListener = (data: ConversationMessage) => {
        console.log('newMessage');
        setMessages((messages) => addMessage(messages, data.message));
      };

      webSocket.bind(WebSocketMessageType.ConversationMessage, conversationMessageListener);

      return () => {
        webSocket.unbind(WebSocketMessageType.ConversationMessage, conversationMessageListener);
      };
    }
  }, [webSocket]);

  if (isLoading) {
    return <LoadingPage />;
  } else if (error) {
    return <div>Error loading {conversationId}</div>;
  }

  return (
    <Stack flex={1} overflow="hidden" {...getRootProps()} paddingBottom="16px">
      {isDragActive && <FileDragOverlay />}
      <input {...getInputProps()} />
      <MessageList messages={messages} />
      <ComposingMembersIndicator />
      <Divider
        sx={{
          marginX: '16px',
          borderTop: '1px solid #E5E5E5',
        }}
      />
      <SendMessageForm onSend={sendMessage} openFilePicker={openFilePicker} />
      {fileHandlers.length > 0 && <FilePreviewsList fileHandlers={fileHandlers} removeFile={removeFile} />}
    </Stack>
  );
};

interface FilePreviewsListProps {
  fileHandlers: FileHandler[];
  removeFile: (fileId: string | number) => void;
}

const FilePreviewsList = ({ fileHandlers, removeFile }: FilePreviewsListProps) => {
  return (
    <Stack
      direction="row"
      flexWrap="wrap"
      gap="16px"
      overflow="auto"
      maxHeight="30%"
      paddingX="16px"
      marginTop="12px" // spacing with the component on top
      paddingTop="4px" // spacing so "RemoveButton" are not cut
    >
      {fileHandlers.map((fileHandler) => (
        <FilePreviewRemovable
          key={fileHandler.id}
          remove={() => removeFile(fileHandler.id)}
          fileHandler={fileHandler}
          borderColor={'#005699' /* Should be same color as message bubble */}
        />
      ))}
    </Stack>
  );
};

export const ComposingMembersIndicator = () => {
  const { t } = useTranslation();
  const { composingMembers } = useConversationContext();

  const text = useMemo(() => {
    const options: TranslateEnumerationOptions<ConversationMember> = {
      elementPartialKey: 'member',
      getElementValue: (member) => member.getDisplayName(),
      translaters: [
        () => '',
        (interpolations) => t('are_composing_1', interpolations),
        (interpolations) => t('are_composing_2', interpolations),
        (interpolations) => t('are_composing_3', interpolations),
        (interpolations) => t('are_composing_more', interpolations),
      ],
    };

    return translateEnumeration<ConversationMember>(composingMembers, options);
  }, [composingMembers, t]);

  return (
    <Stack height="30px" padding="0 16px" justifyContent="center">
      <Fade in={composingMembers.length !== 0}>
        <Stack
          alignItems="center"
          direction="row"
          spacing="8.5px"
          sx={(theme: any) => ({
            height: theme.typography.caption.lineHeight,
          })}
        >
          <WaitingDots />
          <Typography variant="caption">{text}</Typography>
        </Stack>
      </Fade>
    </Stack>
  );
};

const SingleDot = ({ delay }: { delay: number }) => (
  <Box
    width="8px"
    height="8px"
    borderRadius="100%"
    sx={{ backgroundColor: '#000000' }}
    component={motion.div}
    animate={{ scale: [0.75, 1, 0.75] }}
    transition={{
      delay,
      duration: 0.5,
      repeatDelay: 1,
      repeatType: 'loop',
      repeat: Infinity,
      ease: 'easeInOut',
    }}
  />
);

const WaitingDots = () => {
  return (
    <Stack direction="row" spacing="5px">
      <SingleDot delay={0} />
      <SingleDot delay={0.5} />
      <SingleDot delay={1} />
    </Stack>
  );
};

const addMessage = (sortedMessages: Message[], message: Message) => {
  if (sortedMessages.length === 0) {
    return [message];
  } else if (message.id === sortedMessages[sortedMessages.length - 1].linearizedParent) {
    return [...sortedMessages, message];
  } else if (message.linearizedParent === sortedMessages[0].id) {
    return [message, ...sortedMessages];
  } else {
    console.error("Can't insert message " + message.id);
    return sortedMessages;
  }
};

const sortMessages = (messages: Message[]) => {
  let sortedMessages: Message[] = [];
  messages.forEach((message) => (sortedMessages = addMessage(sortedMessages, message)));
  return sortedMessages;
};

export default ChatInterface;
