import { useState } from 'react';
import { useMutation, useQuery } from 'react-query';

import { useDrawer } from '@material-hu/hooks/useDrawer';
import { useModal } from '@material-hu/hooks/useModal';

import HuDialog from '@material-hu/components/design-system/Dialog';

import useGeneralError from 'src/hooks/useGeneralError';
import {
  inviteParticipants,
  missCall,
  getVideoCallParticipants,
} from 'src/services/streaming';
import { InviteParticipantsRequest, Participant } from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';

import AddParticipant from 'src/components/dashboard/videoCall/participants/AddParticipant';
import ParticipantListDrawer from 'src/components/dashboard/videoCall/participants/ParticipantListDrawer';

import {
  CALL_INVITE_PARTICIPANTS_TIMEOUT,
  MAX_CALL_PARTICIPANTS,
} from '../constants';
import { videoCallKeys } from '../queries';

const useCallParticipants = (
  callId: string,
  maxParticipantsAllowed: number,
) => {
  const [selectedParticipants, setSelectedParticipants] = useState<
    Participant[]
  >([]);
  const { t } = useLokaliseTranslation('calls');
  const showGeneralError = useGeneralError();

  const { mutate: missCallMutation } = useMutation(
    (variables: { id: string; participantUserIds: number[] }) =>
      missCall(variables.id, variables.participantUserIds),
  );

  const handleCloseAddParticipantModal = () => {
    closeAddParticipantModal();
    setSelectedParticipants([]);
  };

  const { mutate: inviteParticipantsMutation, isLoading: isInvitingLoading } =
    useMutation(
      (variables: InviteParticipantsRequest) => inviteParticipants(variables),
      {
        onSuccess: () => {
          // Workaround until Stream SDK support miss the call when the user invites participants.
          setTimeout(() => {
            missCallMutation({
              id: callId,
              participantUserIds: selectedParticipants.map(
                participant => participant.id,
              ),
            });
          }, CALL_INVITE_PARTICIPANTS_TIMEOUT);

          handleCloseAddParticipantModal();
          showParticipantListDrawer();
        },
        onError: () => {
          showGeneralError({
            title: t('ADD_PARTICIPANTS_ERROR'),
          });
        },
      },
    );

  const { data: callParticipantsCount = 0 } = useQuery(
    videoCallKeys.callParticipantsCount(),
    () => {
      return getVideoCallParticipants({
        id: callId,
        limit: maxParticipantsAllowed,
        q: '',
        cursor: '',
      });
    },
    {
      select: data => data.data.items.length,
      onError: err => showGeneralError(err, t('ERROR_GET_LIST_USERS')),
    },
  );

  const remainingParticipants = maxParticipantsAllowed - callParticipantsCount;
  const maxParticipantsToAdd =
    remainingParticipants >= MAX_CALL_PARTICIPANTS
      ? MAX_CALL_PARTICIPANTS
      : remainingParticipants;
  const disabledSelectMoreParticipant =
    selectedParticipants.length === maxParticipantsToAdd;

  const {
    modal: addParticipantModal,
    showModal: showAddParticipantModal,
    closeModal: closeAddParticipantModal,
  } = useModal(
    HuDialog,
    {
      fullWidth: true,
      maxWidth: 'sm',
      sx: {
        '& .MuiPaper-root > .MuiStack-root': {
          height: '100%',
          maxHeight: '610px',
        },
        '& .MuiDialog-paper': {
          height: '610px',
        },
        '& .MuiDialogContent-root': {
          maxHeight: '500px',
          flex: 1,
          pb: 0,
        },
      },
      onClose: () => {
        handleCloseAddParticipantModal();
      },
    },
    {
      title: t('ADD_MEMBER'),
      body: (
        <AddParticipant
          selectedParticipants={selectedParticipants}
          setSelectedParticipants={setSelectedParticipants}
          disabledSelectMoreParticipant={disabledSelectMoreParticipant}
          maxParticipantsToAdd={maxParticipantsToAdd}
        />
      ),
      primaryButtonProps: {
        children: t('ADD'),
        disabled: selectedParticipants.length === 0,
        loading: isInvitingLoading,
        onClick: () => {
          inviteParticipantsMutation({
            id: callId,
            participantUserIds: selectedParticipants.map(
              participant => participant.id,
            ),
          });
        },
      },
      onClose: () => {
        handleCloseAddParticipantModal();
      },
      actionInfo: disabledSelectMoreParticipant
        ? t('MAX_PARTICIPANTS_REACHED')
        : '',
    },
  );

  const {
    showDrawer: showParticipantListDrawer,
    drawer: participantListDrawer,
    closeDrawer: closeParticipantListDrawer,
  } = useDrawer(
    ParticipantListDrawer,
    {
      title: t('PARTICIPANTS'),
    },
    {
      showAddParticipantModal: () => {
        showAddParticipantModal();
        closeParticipantListDrawer();
      },
    },
  );

  return {
    showParticipantListDrawer,
    showAddParticipantModal,
    participantListDrawer,
    addParticipantModal,
  };
};

export default useCallParticipants;
