/*
 * 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, ListItemButton, 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 { useUrlParams } from '../hooks/useUrlParams';
import { setRefreshFromSlice } from '../redux/appSlice';
import { useAppDispatch } from '../redux/hooks';
import { ConversationRouteParams } from '../router';
import { getMessageCallText, getMessageMemberText } from '../utils/chatmessages';
import { formatRelativeDate, formatTime } from '../utils/dates&times';
import ContextMenu, { ContextMenuHandler, useContextMenuHandler } from './ContextMenu';
import ConversationAvatar from './ConversationAvatar';
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 callContext = useCallContext(true);
  const { callData } = useContext(CallManagerContext);
  const { t, i18n } = useTranslation();
  const navigate = useNavigate();

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

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

  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]);

  const conversationName = useMemo(
    () => conversationSummary.title || conversationSummary.membersNames.join(', ') || account.getDisplayName(),
    [account, conversationSummary]
  );

  return (
    <Box>
      <ConversationMenu
        conversationId={conversationId}
        conversationName={conversationName}
        onMessageClick={onClick}
        isSelected={isSelected}
        contextMenuProps={contextMenuHandler.props}
      />
      <ListItemButton
        alignItems="flex-start"
        selected={isSelected}
        onClick={onClick}
        onContextMenu={contextMenuHandler.handleAnchorPosition}
      >
        <Stack direction="row" spacing="10px">
          <ConversationAvatar displayName={conversationName} />
          <Stack>
            <Typography variant="body1">{conversationName}</Typography>
            <Stack direction="row" spacing="5px">
              <Typography variant="body2" fontWeight={isSelected ? 'bold' : 'normal'}>
                {timeIndicator}
              </Typography>
              <Typography variant="body2">{lastMessageText}</Typography>
            </Stack>
          </Stack>
        </Stack>
      </ListItemButton>
    </Box>
  );
}

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} />
    </>
  );
};

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;
  open: boolean;
  onClose: () => void;
}

const RemoveConversationDialog = ({ conversationId, open, onClose }: RemoveConversationDialogProps) => {
  const { axiosInstance } = useAuthContext();
  const { t } = useTranslation();
  const dispatch = useAppDispatch();

  const remove = async () => {
    const controller = new AbortController();
    try {
      await axiosInstance.delete(`/conversations/${conversationId}`, {
        signal: controller.signal,
      });
      dispatch(setRefreshFromSlice());
    } catch (e) {
      console.error(`Error removing conversation : `, e);
      dispatch(setRefreshFromSlice());
    }
    onClose();
  };

  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')}
    />
  );
};
