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

import { type AxiosResponse } from 'axios';
import { Typography } from '@material-hu/mui/index';
import Stack from '@material-hu/mui/Stack';

import { EVENTS_SOCKETS } from 'src/constants/sockets';
import { useAuth } from 'src/contexts/JWTContext';
import { useSocket } from 'src/contexts/SocketContext';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import Player, {
  Background,
} from 'src/pages/dashboard/liveStream/ViewerPlayer';
import {
  type JoinLivestreamResponse,
  type LiveStream,
  type LiveStreamPost,
  type PollResponse,
  StreamStatus,
} from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { lazyRetry } from 'src/utils/lazyRetry';

import useAutoplay from '../../liveStream/hooks/useAutoplay';
import CustomHlsVideoPlayer from '../../liveStream/ViewerPlayer/CustomHlsVideoPlayer';
import { type ReactionsHandlers } from '../../liveStream/ViewerPlayer/components/LiveDetails';

const StreamioProvider = lazyRetry(
  () => import('src/pages/dashboard/liveStream/context/StreamioProvider'),
);

type PostPlayerStreamingProps = {
  callType?: string;
  stream: LiveStream;
  post: LiveStreamPost;
  reactionsHandlers: ReactionsHandlers;
  joinLiveStreamRoom?: () => Promise<AxiosResponse<JoinLivestreamResponse>>;
  pollService?: {
    get: () => Promise<AxiosResponse<PollResponse>>;
    vote: (pollId: number, pollOptionId: number) => Promise<AxiosResponse>;
    key: Array<string | number>;
  };
};

const PostPlayerStreaming: FC<PostPlayerStreamingProps> = props => {
  const { stream, post, reactionsHandlers, joinLiveStreamRoom, pollService } =
    props;
  const socket = useSocket();
  const { user } = useAuth();
  const { t } = useLokaliseTranslation('livestream');
  const HuGoThemeProvider = useHuGoTheme();
  const { ref: playerRef, shouldPlay, setAlwaysMode } = useAutoplay();

  const joinLiveStreamMutation = useMutation(() => joinLiveStreamRoom!(), {
    onSuccess: response => {
      socket.emitEvent(EVENTS_SOCKETS.JOIN_ROOM, {
        userId: user?.id.toString(),
        ticketId: response.data.ticketId,
      });
    },
  });

  const { data: poll } = useQuery(
    pollService?.key ?? [],
    () => pollService!.get(),
    {
      select: response => response.data.poll,
      enabled: !!pollService,
    },
  );

  useEffect(() => {
    if (joinLiveStreamRoom) {
      joinLiveStreamMutation.mutate();
    }
  }, [joinLiveStreamMutation.mutate]);

  if (stream.status === StreamStatus.ENDED) return null;

  if (stream.status === StreamStatus.WAITING_RECORDING) {
    return (
      <Background>
        <Stack sx={{ alignItems: 'center' }}>
          <Typography
            variant="globalS"
            fontWeight="fontWeightSemiBold"
            color={theme => theme.palette.new.text.neutral.inverted}
          >
            {t('VIDEO_END')}
          </Typography>
          <Typography
            variant="globalXS"
            color={theme => theme.palette.new.text.neutral.inverted}
          >
            {t('SOON_TO_SEE_STREAM')}
          </Typography>
        </Stack>
      </Background>
    );
  }

  return (
    <HuGoThemeProvider>
      <StreamioProvider streamId={stream.providerStreamId}>
        {stream.hlsEnabled && (
          <CustomHlsVideoPlayer
            stream={stream}
            post={{ ...post, poll }}
            reactionsHandlers={reactionsHandlers}
            pollService={
              pollService
                ? { vote: pollService.vote, key: pollService.key }
                : undefined
            }
          />
        )}
        {!stream.hlsEnabled && (
          <Stack ref={playerRef}>
            <Player
              stream={stream}
              post={{ ...post, poll }}
              reactionsHandlers={reactionsHandlers}
              shouldPlay={shouldPlay}
              setAlwaysPlayMode={setAlwaysMode}
              pollService={
                pollService
                  ? { vote: pollService.vote, key: pollService.key }
                  : undefined
              }
            />
          </Stack>
        )}
      </StreamioProvider>
    </HuGoThemeProvider>
  );
};

export default PostPlayerStreaming;
