import { type FC } from 'react';

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

import useAudioLevel from 'src/pages/dashboard/videoCall/hooks/useAudioLevel';
import useSpeakingState, {
  SPEAKER_FADE_IN_MS,
  SPEAKER_FADE_OUT_MS,
} from 'src/pages/dashboard/videoCall/hooks/useSpeakingState';
import { CallLayout } from 'src/types/stream';
import { useLokaliseTranslation } from 'src/utils/i18n';

const audioBars = [
  { minHeight: '5px', maxHeight: '11px', initialHeight: '8px', delay: '0.3s' },
  {
    minHeight: '5px',
    maxHeight: '11px',
    initialHeight: '10px',
    delay: '0.1s',
  },
  {
    minHeight: '5px',
    maxHeight: '11px',
    initialHeight: '8px',
    delay: '0.2s',
  },
  {
    minHeight: '5px',
    maxHeight: '11px',
    initialHeight: '6px',
    delay: '0.3s',
  },
];

type CustomParticipantViewProps = {
  layout?: CallLayout;
};

const CustomParticipantView: FC<CustomParticipantViewProps> = props => {
  const { layout = CallLayout.GRID } = props;
  const { t } = useLokaliseTranslation('calls');
  const theme = useTheme();
  const { useLocalParticipant } = useCallStateHooks();
  const { participant } = useParticipantViewContext();
  const localParticipant = useLocalParticipant();
  const { audioLevel } = useAudioLevel(participant);
  const { isVisible, isWavesAnimating, transitionMode } =
    useSpeakingState(audioLevel);

  const isLocalParticipant = localParticipant?.userId === participant.userId;

  const opacityTransition =
    transitionMode === 'fadeIn'
      ? `opacity ${SPEAKER_FADE_IN_MS}ms ease-in-out`
      : transitionMode === 'fadeOut'
        ? `opacity ${SPEAKER_FADE_OUT_MS}ms ease-out`
        : 'none';

  const isMuted = !hasAudio(participant);

  return (
    <>
      <Stack
        sx={{
          position: 'absolute',
          top: layout === CallLayout.SHARE_SCREEN ? '8px' : '16px',
          right: layout === CallLayout.SHARE_SCREEN ? '8px' : '16px',
          height: '24px',
          width: '24px',
          backgroundColor: theme.palette.base?.blueBrand[400],
          borderRadius: '50%',
          flexDirection: 'row',
          gap: 0.25,
          alignItems: 'center',
          justifyContent: 'center',
          opacity: isVisible ? 1 : 0,
          transition: opacityTransition,
        }}
      >
        {audioBars.map((bar, index) => (
          <Stack
            key={index}
            sx={{
              width: '2px',
              height: bar.minHeight,
              backgroundColor: theme.palette.base?.white,
              borderRadius: '1px',
              animation: isWavesAnimating
                ? `soundWave${index} 0.4s ease-in-out infinite`
                : 'none',
              animationDelay: bar.delay,
              transition: 'height 150ms ease-out',
              [`@keyframes soundWave${index}`]: {
                '0%, 100%': { height: bar.minHeight },
                '50%': { height: bar.maxHeight },
              },
            }}
          />
        ))}
      </Stack>

      <Stack
        sx={{
          flexDirection: 'row',
          position: 'absolute',
          bottom: layout === CallLayout.SHARE_SCREEN ? '8px' : '12px',
          left: layout === CallLayout.SHARE_SCREEN ? '8px' : '12px',
          maxWidth:
            layout === CallLayout.SHARE_SCREEN
              ? 'calc(100% - 16px)'
              : 'calc(100% - 24px)',
          minWidth: 0,
          gap:
            layout === CallLayout.SHARE_SCREEN
              ? theme.spacing(0.5)
              : theme.spacing(1),
          alignItems: 'center',
        }}
      >
        {isMuted && (
          <Stack
            sx={{
              backgroundColor: theme.palette.base?.greyTransparent['900p40'],
              border: `1px solid ${theme.palette.base?.greyTransparent['900p40']}`,
              borderRadius: theme.shape.borderRadiusL,
              py:
                layout === CallLayout.SHARE_SCREEN
                  ? theme.spacing(0.25)
                  : theme.spacing(0.5),
              px:
                layout === CallLayout.SHARE_SCREEN
                  ? theme.spacing(0.5)
                  : theme.spacing(1),
            }}
          >
            <IconMicrophoneOff
              size={layout === CallLayout.SHARE_SCREEN ? 10 : 16}
              color={theme.palette.new.text.neutral.inverted}
            />
          </Stack>
        )}
        <Typography
          variant={layout === CallLayout.SHARE_SCREEN ? 'globalXXS' : 'globalS'}
          fontWeight="fontWeightRegular"
          color="new.text.neutral.inverted"
          noWrap
          sx={{
            textShadow: '0 1px 2px #AAAABA73',
          }}
        >
          {participant.name} {isLocalParticipant && `(${t('CALL_YOU')})`}
        </Typography>
      </Stack>
    </>
  );
};

export default CustomParticipantView;
