import { FC, useEffect } from 'react';

import { CallingState, useCallStateHooks } from '@stream-io/video-react-sdk';

import useConnectionSound from 'src/pages/dashboard/videoCall/hooks/useConnectionSound';
import useLeaveCallBeforeUnload from 'src/pages/dashboard/videoCall/hooks/useLeaveCallBeforeUnload';
import { Participant } from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';

import CallPreview from './CallPreview';
import FallbackMessage from './FallbackMessage';
import { LoadingCall } from './LoadingCall';
import LobbyContainer from './lobby/Container';
import ErrorState from './lobby/ErrorState';
import LobbyScreen from './lobby/LobbyScreen';
import OngoingCall from './OngoingCall';

export type VideoCallProps = {
  participants: Participant[];
  callId: string;
  initializeVideo: boolean;
  joinCallFromLobby: {
    mutation: () => Promise<void>;
    isLoading: boolean;
  };
  maxParticipantsAllowed: number;
  showRingingView: boolean;
  onEndCall: () => void;
};

const VideoCall: FC<VideoCallProps> = props => {
  const {
    initializeVideo,
    participants = [],
    callId,
    joinCallFromLobby,
    maxParticipantsAllowed,
    showRingingView,
    onEndCall,
  } = props;

  useLeaveCallBeforeUnload(callId, showRingingView);

  const { t } = useLokaliseTranslation('calls');
  const { useCallCallingState, useCameraState } = useCallStateHooks();

  const callingState = useCallCallingState();
  const { camera, hasBrowserPermission: hasPermissionCamera } =
    useCameraState();
  useConnectionSound();

  useEffect(() => {
    if (initializeVideo && hasPermissionCamera) {
      camera.enable();
    } else {
      camera.disable();
    }
  }, [camera, initializeVideo]);

  if (showRingingView) {
    // workaround because stream is not updating the calling state properly
    return <CallPreview participants={participants} />;
  }

  switch (callingState) {
    case CallingState.OFFLINE:
    case CallingState.MIGRATING:
    case CallingState.RECONNECTING:
      return <FallbackMessage message={t('RECONNECT_TO_VIDEOCALL')} />;

    case CallingState.RECONNECTING_FAILED:
      return <FallbackMessage message={t('ERROR_RECONNECT_TO_VIDEOCALL')} />;

    case CallingState.JOINING:
      return <LoadingCall />;

    case CallingState.JOINED:
      return (
        <OngoingCall
          callId={callId}
          maxParticipantsAllowed={maxParticipantsAllowed}
          onEndCall={onEndCall}
        />
      );

    case CallingState.RINGING:
      return <CallPreview participants={participants} />;

    case CallingState.IDLE:
      return (
        <LobbyScreen
          joinCall={joinCallFromLobby.mutation}
          isJoining={joinCallFromLobby.isLoading}
        />
      );

    case CallingState.LEFT:
      return (
        <LobbyContainer title={t('call_left_header')}>
          <ErrorState error={callingState} />
        </LobbyContainer>
      );
  }
};

export default VideoCall;
