import { type FC } from 'react';

import {
  hasScreenShare,
  ParticipantView,
  type StreamVideoParticipant,
  useCallStateHooks,
} from '@stream-io/video-react-sdk';
import { motion } from 'motion/react';
import Grid from '@material-hu/mui/Grid';
import Stack from '@material-hu/mui/Stack';
import { styled } from '@material-hu/mui/styles';

import { SPEAKER_INDICATOR_FADE_IN } from 'src/pages/dashboard/videoCall/constants';
import {
  getAvatarsFromParticipants,
  getScreenShareSideParticipantHeight,
} from 'src/pages/dashboard/videoCall/utils';
import { CallLayout } from 'src/types/stream';

import CustomParticipantView from './CustomParticipantView';
import CustomVideoPlaceholder from './CustomVideoPlaceholder';
import MoreParticipantsItem from './MoreParticipantsItem';

const MAX_SIDE_PARTICIPANTS = 5;

const MotionGrid = motion.create(Grid);

const SIDE_GRID_TRANSITION = { duration: 0.2, delay: 0.1 };

const ParticipantItem = styled(Stack, {
  shouldForwardProp: prop =>
    prop !== 'totalSlots' &&
    prop !== 'maxSideParticipants' &&
    prop !== 'isDominantSpeaker',
})<{
  totalSlots: number;
  maxSideParticipants: number;
  isDominantSpeaker?: boolean;
}>(({ theme, totalSlots, maxSideParticipants, isDominantSpeaker }) => ({
  height: getScreenShareSideParticipantHeight(totalSlots, maxSideParticipants),
  maxHeight: '150px',
  '& .str-video__participant-view': {
    height: '100%',
    position: 'relative',
    border: `1px solid ${
      isDominantSpeaker ? 'transparent' : theme.palette.base?.grey[600]
    }`,
    boxShadow: isDominantSpeaker
      ? `0 0 4px 0 ${theme.palette.new.shadows?.['8dp']}`
      : 'none',
    ...(isDominantSpeaker && {
      '&::after': {
        content: '""',
        position: 'absolute',
        inset: '-1px',
        border: `3px solid ${theme.palette.base?.blueBrand[400]}`,
        borderRadius: 'inherit',
        pointerEvents: 'none',
        zIndex: 1,
        animation: `${SPEAKER_INDICATOR_FADE_IN} 0.25s ease-out`,
      },
    }),
    '& .str-video__video': {
      borderRadius: '8px',
    },
  },
}));

type CallShareScreenLayoutProps = {
  screenShareParticipant: StreamVideoParticipant;
  providerParticipants: StreamVideoParticipant[];
  handleShowParticipants: () => void;
};

const CallShareScreenLayout: FC<CallShareScreenLayoutProps> = props => {
  const {
    screenShareParticipant,
    providerParticipants,
    handleShowParticipants,
  } = props;

  const { useLocalParticipant } = useCallStateHooks();
  const localParticipant = useLocalParticipant();

  const sideScreenShareParticipant = providerParticipants.filter(
    participant =>
      hasScreenShare(participant) &&
      participant.sessionId !== screenShareParticipant.sessionId,
  )[0];

  const sideParticipants = providerParticipants
    .slice(0, MAX_SIDE_PARTICIPANTS - (sideScreenShareParticipant ? 2 : 1))
    .filter(participant => !participant.isLocalParticipant);

  const remainingParticipants = [
    sideParticipants[sideParticipants.length - 1],
    ...providerParticipants
      .slice(MAX_SIDE_PARTICIPANTS - (sideScreenShareParticipant ? 2 : 1))
      .filter(participant => !participant.isLocalParticipant),
  ].filter(Boolean);

  const needsMoreButton = sideScreenShareParticipant
    ? providerParticipants.length > MAX_SIDE_PARTICIPANTS - 1
    : providerParticipants.length > MAX_SIDE_PARTICIPANTS;

  const sideParticipantsCount = sideScreenShareParticipant
    ? sideParticipants.length + 2
    : sideParticipants.length + 1; // +1 because previously we filter by localPariticpant.
  const totalSlots =
    sideParticipantsCount > MAX_SIDE_PARTICIPANTS || needsMoreButton
      ? MAX_SIDE_PARTICIPANTS
      : sideParticipantsCount;

  const sideAvatars = getAvatarsFromParticipants(remainingParticipants);

  return (
    <>
      <Grid
        item
        xs={10}
        sx={{
          height: '100%',
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          '& .str-video__participant-view': {
            '& .str-video__video': {
              objectFit: 'contain',
              border: 'none',
              borderRadius: 1,
            },
          },
        }}
      >
        <ParticipantView
          muteAudio
          participant={screenShareParticipant}
          VideoPlaceholder={CustomVideoPlaceholder}
          trackType="screenShareTrack"
          ParticipantViewUI={null}
        />
      </Grid>

      <MotionGrid
        item
        xs={2}
        sx={{ height: '100%' }}
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        transition={SIDE_GRID_TRANSITION}
      >
        <Stack
          spacing={1}
          sx={{
            height: '100%',
            overflowY: 'hidden',
            justifyContent: 'center',
            px: 0.5,
          }}
        >
          {sideScreenShareParticipant && (
            <ParticipantItem
              totalSlots={totalSlots}
              maxSideParticipants={MAX_SIDE_PARTICIPANTS}
              isDominantSpeaker={false}
            >
              <ParticipantView
                muteAudio
                participant={sideScreenShareParticipant}
                VideoPlaceholder={videoPlaceholderProps => (
                  <CustomVideoPlaceholder
                    {...videoPlaceholderProps}
                    layout={CallLayout.SHARE_SCREEN}
                  />
                )}
                trackType="screenShareTrack"
                ParticipantViewUI={null}
              />
            </ParticipantItem>
          )}

          {sideParticipants.map((participant, index) => {
            const isLastParticipant = index === sideParticipants.length - 1;
            if (isLastParticipant && needsMoreButton) {
              return null;
            }
            return (
              <ParticipantItem
                key={participant.sessionId}
                totalSlots={totalSlots}
                maxSideParticipants={MAX_SIDE_PARTICIPANTS}
                isDominantSpeaker={participant?.isDominantSpeaker}
              >
                <ParticipantView
                  muteAudio
                  participant={participant}
                  VideoPlaceholder={videoPlaceholderProps => (
                    <CustomVideoPlaceholder
                      {...videoPlaceholderProps}
                      layout={CallLayout.SHARE_SCREEN}
                    />
                  )}
                  trackType="videoTrack"
                  ParticipantViewUI={() => (
                    <CustomParticipantView layout={CallLayout.SHARE_SCREEN} />
                  )}
                />
              </ParticipantItem>
            );
          })}

          {localParticipant && (
            <ParticipantItem
              totalSlots={totalSlots}
              maxSideParticipants={MAX_SIDE_PARTICIPANTS}
              isDominantSpeaker={localParticipant?.isDominantSpeaker}
            >
              <ParticipantView
                muteAudio
                participant={localParticipant}
                VideoPlaceholder={videoPlaceholderProps => (
                  <CustomVideoPlaceholder
                    {...videoPlaceholderProps}
                    layout={CallLayout.SHARE_SCREEN}
                  />
                )}
                trackType="videoTrack"
                ParticipantViewUI={() => (
                  <CustomParticipantView layout={CallLayout.SHARE_SCREEN} />
                )}
              />
            </ParticipantItem>
          )}

          {needsMoreButton && (
            <MoreParticipantsItem
              avatars={sideAvatars}
              onClick={handleShowParticipants}
              sx={{
                height: getScreenShareSideParticipantHeight(
                  totalSlots,
                  MAX_SIDE_PARTICIPANTS,
                ),
              }}
            />
          )}
        </Stack>
      </MotionGrid>
    </>
  );
};

export default CallShareScreenLayout;
