import { FC, useEffect } from 'react';
import { useMutation } from 'react-query';

import {
  StreamTheme,
  StreamCall,
  useStreamVideoClient,
  SfuModels,
  StreamVideoClient,
} from '@stream-io/video-react-sdk';

import CircularProgress from '@material-hu/mui/CircularProgress';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import { logEvent } from 'src/config/amplitude';
import { useAuth } from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import { EventName } from 'src/types/amplitude';
import { StreamType } from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { Background } from '../ViewerPlayer';

import('@stream-io/video-react-sdk/dist/css/styles.css');

export type StreamIoProviderProps = {
  streamId?: string;
  callType?: string;
  isHost?: boolean;
};

const StreamioProvider: FC<
  React.PropsWithChildren<StreamIoProviderProps>
> = props => {
  const {
    children,
    streamId,
    callType = StreamType.LIVESTREAM,
    isHost = false,
  } = props;

  const showGeneralError = useGeneralError();
  const { t } = useLokaliseTranslation('livestream');
  const client = useStreamVideoClient();
  const { user } = useAuth();

  const {
    data: call,
    mutate: joinCall,
    isLoading = true,
    isError,
  } = useMutation(
    async ({
      id,
      isHost: isHostParameter,
      streamClient,
    }: {
      id: string;
      isHost: boolean;
      streamClient: StreamVideoClient;
    }) => {
      const callInstance = streamClient.call(callType, id);

      callInstance.disableClientCapabilities(
        SfuModels.ClientCapability.SUBSCRIBER_VIDEO_PAUSE,
      );

      if (isHostParameter) {
        await callInstance.join({ create: true });
      }

      return callInstance;
    },
    {
      onError: error => {
        showGeneralError(error, t('ERROR_JOIN_VIDEO'));
        logEvent(EventName.LIVESTREAM_CALL_INSTANCE_ERROR, {
          userId: user?.id,
          livestreamId: streamId,
          isHost,
          error:
            typeof error === 'object' && error !== null && 'message' in error
              ? error.message
              : 'Unknown error',
        });
      },
    },
  );

  useEffect(() => {
    if (client && streamId) {
      joinCall({ id: streamId, isHost, streamClient: client });
    }
  }, [client, streamId]);

  return (
    <>
      {isLoading && !isError && (
        <Stack
          sx={{
            alignItems: 'center',
            minHeight: '100%',
            // this color don't exist in DS yet.
            background: '#FAFAFC',
          }}
        >
          <Background
            isHost={isHost}
            sx={{
              width: isHost ? 1100 : '100%',
              mt: 2,
            }}
          >
            <CircularProgress
              sx={{ color: theme => theme.palette.common.white }}
            />
          </Background>
        </Stack>
      )}
      {client && !isError && (
        <StreamTheme
          style={{
            minHeight: '100%',
            // this color don't exist in DS yet.
            background: '#FAFAFC',
          }}
        >
          {call && <StreamCall call={call}>{children}</StreamCall>}
        </StreamTheme>
      )}
      {isError && (
        <Stack sx={{ alignItems: 'center' }}>
          <Background
            isHost={isHost}
            sx={{
              width: isHost ? 1100 : '100%',
              mt: 2,
            }}
          >
            <Typography sx={{ color: theme => theme.palette.common.white }}>
              {isHost
                ? t('GENERIC_ERROR_CREATE_LIVE')
                : t('GENERIC_ERROR_JOIN_LIVE')}
            </Typography>
          </Background>
        </Stack>
      )}
    </>
  );
};

export default StreamioProvider;
