/*
 * 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, Stack, Typography } from '@mui/material';
import dayjs from 'dayjs';
import { IConversationSummary } from 'jami-web-common';
import { QRCodeCanvas } from 'qrcode.react';
import { useCallback, useContext, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';

import { useAuthContext } from '../contexts/AuthProvider';
import { CallManagerContext } from '../contexts/CallManagerProvider';
import { CallStatus, useCallContext } from '../contexts/CallProvider';
import { useConversationDisplayNameShort } from '../hooks/useConversationDisplayName';
import { useUrlParams } from '../hooks/useUrlParams';
import { ConversationRouteParams } from '../router';
import { useRemoveConversationMutation } from '../services/conversationQueries';
import { getMessageCallText, getMessageMemberText } from '../utils/chatmessages';
import { formatRelativeDate, formatTime } from '../utils/dates&times';
import ContextMenu, { ContextMenuHandler, useContextMenuHandler } from './ContextMenu';
import ConversationAvatar from './ConversationAvatar';
import { CustomListItemButton } from './CustomListItemButton';
import { ConfirmationDialog, DialogContentList, InfosDialog, useDialogHandler } from './Dialog';
import { PopoverListItemData } from './PopoverList';
import { AudioCallIcon, CancelIcon, MessageIcon, PersonIcon, VideoCallIcon } from './SvgIcon';

type ConversationListItemProps = {
  conversationSummary: IConversationSummary;
};

export default function ConversationListItem({ conversationSummary }: ConversationListItemProps) {
  const { account } = useAuthContext();
  const {
    urlParams: { conversationId: selectedConversationId },
  } = useUrlParams<ConversationRouteParams>();
  const contextMenuHandler = useContextMenuHandler();
  const navigate = useNavigate();

  const conversationId = conversationSummary.id;
  const isSelected = conversationId === selectedConversationId;

  const onClick = useCallback(() => {
    if (conversationId) {
      navigate(`/conversation/${conversationId}`);
    }
  }, [navigate, conversationId]);

  const conversationName = useConversationDisplayNameShort(
    account,
    conversationSummary.title,
    conversationSummary.membersNames
  );

  return (
    <Box>
      <ConversationMenu
        conversationId={conversationId}
        conversationName={conversationName}
        onMessageClick={onClick}
        isSelected={isSelected}
        contextMenuProps={contextMenuHandler.props}
      />
      <CustomListItemButton
        selected={isSelected}
        onClick={onClick}
        onContextMenu={contextMenuHandler.handleAnchorPosition}
        icon={<ConversationAvatar displayName={conversationName} src={conversationSummary.avatar} />}
        primaryText={<Typography variant="body1">{conversationName}</Typography>}
        secondaryText={<SecondaryText conversationSummary={conversationSummary} isSelected={isSelected} />}
      />
    </Box>
  );
}

type SecondaryTextProps = {
  conversationSummary: IConversationSummary;
  isSelected: boolean;
};

const SecondaryText = ({ conversationSummary, isSelected }: SecondaryTextProps) => {
  const { account } = useAuthContext();
  const callContext = useCallContext(true);
  const { callData } = useContext(CallManagerContext);
  const { t, i18n } = useTranslation();

  const timeIndicator = useMemo(() => {
    const message = conversationSummary.lastMessage;
    const time = dayjs.unix(Number(message.timestamp));
    if (time.isToday()) {
      return formatTime(time, i18n);
    } else {
      return formatRelativeDate(time, i18n);
    }
  }, [conversationSummary, i18n]);

  const lastMessageText = useMemo(() => {
    if (!callContext || !callData || callData.conversationId !== conversationSummary.id) {
      const message = conversationSummary.lastMessage;
      switch (message.type) {
        case 'initial': {
          return t('message_swarm_created');
        }
        case 'application/data-transfer+json': {
          return message.fileId;
        }
        case 'application/call-history+json': {
          const isAccountMessage = message.author === account.getUri();
          return getMessageCallText(isAccountMessage, message, i18n);
        }
        case 'member': {
          return getMessageMemberText(message, i18n);
        }
        case 'text/plain': {
          return message.body;
        }
        default: {
          console.error(`${ConversationListItem.name} received an unexpected lastMessage type: ${message.type}`);
          return '';
        }
      }
    }

    if (callContext.callStatus === CallStatus.InCall) {
      return callContext.isAudioOn ? t('ongoing_call_unmuted') : t('ongoing_call_muted');
    }

    if (callContext.callStatus === CallStatus.Connecting) {
      return t('connecting_call');
    }

    return callContext.callRole === 'caller' ? t('outgoing_call') : t('incoming_call');
  }, [account, conversationSummary, callContext, callData, t, i18n]);

  return (
    <Stack direction="row" spacing="5px">
      <Typography variant="body2" fontWeight={isSelected ? 'bold' : 'normal'}>
        {timeIndicator}
      </Typography>
      <Typography variant="body2">{lastMessageText}</Typography>
    </Stack>
  );
};

interface ConversationMenuProps {
  conversationId: string;
  conversationName: string;
  onMessageClick: () => void;
  isSelected: boolean;
  contextMenuProps: ContextMenuHandler['props'];
}

const ConversationMenu = ({
  conversationId,
  conversationName,
  onMessageClick,
  isSelected,
  contextMenuProps,
}: ConversationMenuProps) => {
  const { t } = useTranslation();
  const { startCall } = useContext(CallManagerContext);
  const [isSwarm] = useState(true);

  const detailsDialogHandler = useDialogHandler();
  const RemoveConversationDialogHandler = useDialogHandler();

  const navigate = useNavigate();

  const menuOptions: PopoverListItemData[] = useMemo(
    () => [
      {
        label: t('conversation_message'),
        Icon: MessageIcon,
        onClick: onMessageClick,
      },
      {
        label: t('conversation_start_audiocall'),
        Icon: AudioCallIcon,
        onClick: () => {
          if (conversationId) {
            startCall({
              conversationId,
              role: 'caller',
            });
          }
        },
      },
      {
        label: t('conversation_start_videocall'),
        Icon: VideoCallIcon,
        onClick: () => {
          if (conversationId) {
            startCall({
              conversationId,
              role: 'caller',
              withVideoOn: true,
            });
          }
        },
      },
      ...(isSelected
        ? [
            {
              label: t('conversation_close'),
              Icon: CancelIcon,
              onClick: () => {
                navigate(`/`);
              },
            },
          ]
        : []),
      {
        label: t('conversation_details'),
        Icon: PersonIcon,
        onClick: () => {
          detailsDialogHandler.openDialog();
        },
      },
      {
        label: t('conversation_delete'),
        Icon: CancelIcon,
        onClick: () => {
          RemoveConversationDialogHandler.openDialog();
        },
      },
    ],
    [
      navigate,
      onMessageClick,
      isSelected,
      detailsDialogHandler,
      RemoveConversationDialogHandler,
      t,
      startCall,
      conversationId,
    ]
  );

  return (
    <>
      <ContextMenu {...contextMenuProps} items={menuOptions} />

      <DetailsDialog
        {...detailsDialogHandler.props}
        conversationId={conversationId}
        conversationName={conversationName}
        isSwarm={isSwarm}
      />

      <RemoveConversationDialog
        {...RemoveConversationDialogHandler.props}
        conversationId={conversationId}
        isSelected={isSelected}
      />
    </>
  );
};

interface DetailsDialogProps {
  conversationId: string;
  conversationName: string;
  open: boolean;
  onClose: () => void;
  isSwarm: boolean;
}

const DetailsDialog = ({ conversationId, conversationName, open, onClose, isSwarm }: DetailsDialogProps) => {
  const { t } = useTranslation();
  const items = useMemo(
    () => [
      {
        label: t('conversation_details_name'),
        value: conversationName,
      },
      {
        label: t('conversation_details_identifier'),
        value: conversationId,
      },
      {
        label: t('conversation_details_qr_code'),
        value: <QRCodeCanvas size={80} value={`${conversationId}`} />,
      },
      {
        label: t('conversation_details_is_swarm'),
        value: isSwarm ? t('conversation_details_is_swarm_true') : t('conversation_details_is_swarm_false'),
      },
    ],
    [conversationId, conversationName, isSwarm, t]
  );
  return (
    <InfosDialog
      open={open}
      onClose={onClose}
      icon={<ConversationAvatar sx={{ width: 'inherit', height: 'inherit' }} displayName={conversationName} />}
      title={conversationName}
      content={<DialogContentList title={t('conversation_details_informations')} items={items} />}
    />
  );
};

interface RemoveConversationDialogProps {
  conversationId: string;
  isSelected: boolean;
  open: boolean;
  onClose: () => void;
}

const RemoveConversationDialog = ({ conversationId, isSelected, open, onClose }: RemoveConversationDialogProps) => {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const removeConversationMutation = useRemoveConversationMutation();

  const remove = useCallback(async () => {
    removeConversationMutation.mutate(
      { conversationId },
      {
        onSuccess: () => {
          if (isSelected) {
            navigate('/conversation/');
          }
        },
        onError: (e) => {
          console.error(`Error removing conversation : `, e);
        },
        onSettled: () => {
          onClose();
        },
      }
    );
  }, [conversationId, isSelected, navigate, onClose, removeConversationMutation]);

  return (
    <ConfirmationDialog
      open={open}
      onClose={onClose}
      title={t('dialog_confirm_title_default')}
      content={t('conversation_ask_confirm_remove')}
      onConfirm={remove}
      confirmButtonText={t('conversation_confirm_remove')}
    />
  );
};
