import { type FC, useEffect, useState } from 'react';
import { useFormContext } from 'react-hook-form';

import { useParticipantViewContext } from '@stream-io/video-react-sdk';
import { IconVideo } from '@material-hu/icons/tabler';
import Chip from '@material-hu/mui/Chip';
import Stack from '@material-hu/mui/Stack';
import { useTheme } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import HuAlert from '@material-hu/components/design-system/Alert';

import { Configuration, StreamStatus, VideoOrigin } from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';

import SoftwareControls from './controls/SoftwareControls';
import WebcamControls from './controls/WebcamControls';
import { NetworkAlert } from './network/Alert';
import PreparingLayout from './PreparingLayout';

type CustomParticipantViewProps = {
  activeStep: Configuration;
  streamStatus: StreamStatus;
  onReady: () => void;
  isConnectSoftwareStreaming: boolean;
  isSoftwareStreamConnected: boolean;
};

const CustomParticipantView: FC<CustomParticipantViewProps> = props => {
  const {
    activeStep,
    streamStatus,
    onReady,
    isConnectSoftwareStreaming,
    isSoftwareStreamConnected,
  } = props;

  const theme = useTheme();
  const { t } = useLokaliseTranslation('livestream');
  const { watch } = useFormContext();

  const { videoElement } = useParticipantViewContext();
  const [pictureInPictureElement, setPictureInPictureElement] = useState(
    document.pictureInPictureElement,
  );
  const { videoOrigin } = watch();

  useEffect(() => {
    if (!videoElement) return;

    const handlePictureInPicture = () => {
      setPictureInPictureElement(document.pictureInPictureElement);
    };

    videoElement.addEventListener(
      'enterpictureinpicture',
      handlePictureInPicture,
    );
    videoElement.addEventListener(
      'leavepictureinpicture',
      handlePictureInPicture,
    );

    return () => {
      videoElement.removeEventListener(
        'enterpictureinpicture',
        handlePictureInPicture,
      );
      videoElement.removeEventListener(
        'leavepictureinpicture',
        handlePictureInPicture,
      );
    };
  }, [videoElement]);

  useEffect(() => {
    if (activeStep === Configuration.CONFIGURATION) {
      if (videoElement && pictureInPictureElement !== videoElement)
        videoElement.requestPictureInPicture().then(() => {
          videoElement.play();
        });
    } else {
      if (document.pictureInPictureElement) {
        document.exitPictureInPicture();
      }
    }

    return () => {
      if (document.pictureInPictureElement) {
        document.exitPictureInPicture();
      }
    };
  }, [activeStep]);

  const isPreparing = streamStatus === StreamStatus.Preparing;
  const isFinished = streamStatus === StreamStatus.Finished;
  const isStreaming = streamStatus === StreamStatus.Streaming;

  const showSoftwareSignalActiveAlert =
    videoOrigin === VideoOrigin.WEBCAM && isSoftwareStreamConnected;

  return (
    <>
      {isPreparing && <PreparingLayout onReady={onReady} />}
      {!isFinished && (
        <>
          <Stack
            sx={{
              position: 'absolute',
              top: 10,
              left: 10,
              color: theme.palette.common.white,
              flexDirection: 'row',
              alignItems: 'center',
              gap: 1.5,
            }}
          >
            <Chip
              // DS doesn't have dark variant yet
              sx={{
                height: '36px',
                backgroundColor: isStreaming
                  ? theme.palette.base?.red[800]
                  : theme.palette.base?.greyTransparent['900p40'],
                border: `1px solid ${isStreaming ? theme.palette.base?.red[600] : theme.palette.base?.greyTransparent['900p40']}`,
                color: theme.palette.common.white,
                fontSize: 14,
                fontWeight: 600,
              }}
              label={isStreaming ? t('LIVE') : t('WAITING_LIVE')}
            />
          </Stack>
          {videoOrigin === VideoOrigin.WEBCAM && <WebcamControls />}
          {showSoftwareSignalActiveAlert && (
            <HuAlert
              severity="info"
              title={t('STREAMING_FROM_WEBCAM')}
              description={t('STREAMING_FROM_WEBCAM_DESCRIPTION')}
              sx={{
                position: 'absolute',
                bottom: theme.spacing(2),
                left: theme.spacing(3),
                zIndex: 2,
                maxWidth: '380px',
              }}
              hasClose
            />
          )}
          {!isConnectSoftwareStreaming &&
            videoOrigin === VideoOrigin.SOFTWARE_STREAMING && (
              <SoftwareControls isStreaming={isStreaming} />
            )}
          {isConnectSoftwareStreaming && !isStreaming && (
            <Stack
              sx={{
                position: 'absolute',
                top: '50%',
                left: '50%',
                transform: 'translate(-50%, -50%)',
                alignItems: 'center',
                gap: theme.spacing(2),
              }}
            >
              <IconVideo color={theme.palette.new.text.neutral.inverted} />
              <Typography
                variant="globalXS"
                color="new.text.neutral.inverted"
                sx={{ textAlign: 'center' }}
              >
                {t('CONNECT_SOFTWARE_STREAMING')}
              </Typography>
            </Stack>
          )}
          {isConnectSoftwareStreaming && isStreaming && (
            <Stack
              sx={{
                position: 'absolute',
                top: '50%',
                left: '50%',
                transform: 'translate(-50%, -50%)',
                alignItems: 'center',
                zIndex: 1,
              }}
            >
              <Typography
                variant="globalM"
                color="new.text.neutral.inverted"
                fontWeight="fontWeightSemiBold"
              >
                {t('LOST_SOFTWARE_CONNECTION')}
              </Typography>
              <Typography
                variant="globalXS"
                color="new.text.neutral.inverted"
              >
                {t('LOST_SOFTWARE_CONNECTION_DESCRIPTION')}
              </Typography>
            </Stack>
          )}
          <NetworkAlert />
        </>
      )}
    </>
  );
};

export default CustomParticipantView;
