import { type FC, type ReactNode } from 'react';

import {
  IconMaximize,
  IconMinimize,
  IconVolume,
  IconVolume3,
} from '@material-hu/icons/tabler';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import { styled } from '@material-hu/mui/styles';

import { FullScreenElementType } from 'src/types/stream';

import VolumeSlider from 'src/components/attachment/components/VolumeSlider';

import { FULL_SCREEN_COMMENT_WIDTH } from '../../constants';
import type useVolume from '../hooks/useVolume';

const ControlsContainer = styled(Stack, {
  shouldForwardProp: prop =>
    prop !== 'showControls' && prop !== 'fullScreenElement',
})<Pick<ControlsProps, 'showControls' | 'fullScreenElement'>>(
  ({ theme, showControls, fullScreenElement }) => ({
    opacity: showControls ? 1 : 0,
    flexDirection: 'row',
    alignItems: 'center',
    padding: theme.spacing(1),
    justifyContent: 'flex-end',
    transition: 'opacity 0.3s ease-in-out',
    position: 'absolute',
    bottom: 0,
    left: 0,
    right:
      fullScreenElement === FullScreenElementType.SEMI
        ? FULL_SCREEN_COMMENT_WIDTH
        : 0,
    background: 'linear-gradient(180deg, transparent, #00000099)',
    borderBottomLeftRadius:
      fullScreenElement !== FullScreenElementType.NONE ? 0 : 16,
    borderBottomRightRadius:
      fullScreenElement !== FullScreenElementType.NONE ? 0 : 16,
  }),
);

type ControlsProps = {
  fullScreenElement: FullScreenElementType;
  showControls: boolean;
  children: ReactNode;
  controlHandlers: {
    toggleFullscreen: () => void;
  };
  volumeHandlers: ReturnType<typeof useVolume>;
};

const Controls: FC<ControlsProps> = props => {
  const {
    fullScreenElement,
    showControls,
    children,
    controlHandlers,
    volumeHandlers,
  } = props;
  const { toggleFullscreen } = controlHandlers;

  const {
    volume,
    muted,
    showVolumeSlider,
    handleVolumeButtonEnter,
    handleVolumeButtonLeave,
    handleVolumeChange,
    handleVolumeChangeCommitted,
    handleMuteChange,
  } = volumeHandlers;

  return (
    <ControlsContainer
      showControls={showControls || muted}
      fullScreenElement={fullScreenElement}
    >
      <Stack
        sx={{
          opacity: showControls ? 1 : 0,
          visibility: showControls ? 'visible' : 'hidden',
          transition: showControls
            ? 'opacity 0.3s ease-in-out, visibility 0s'
            : 'opacity 0.3s ease-in-out, visibility 0.3s',
          flexDirection: 'row',
          alignItems: 'center',
          flex: 1,
          justifyContent: 'flex-end',
        }}
      >
        {children}
        <IconButton
          sx={{
            svg: { stroke: theme => theme.palette.base?.white },
            '&:hover svg': {
              stroke: theme => theme.palette.base?.white,
            },
          }}
          onClick={toggleFullscreen}
        >
          {fullScreenElement === FullScreenElementType.NONE && <IconMaximize />}
          {fullScreenElement === FullScreenElementType.SEMI && <IconMaximize />}
          {fullScreenElement === FullScreenElementType.FULL && <IconMinimize />}
        </IconButton>
      </Stack>
      <Stack
        onMouseEnter={handleVolumeButtonEnter}
        onMouseLeave={handleVolumeButtonLeave}
        sx={{ position: 'relative' }}
      >
        {showVolumeSlider && showControls && (
          <Stack
            sx={{
              backgroundColor: '#00000099',
              height: '96px',
              position: 'absolute',
              bottom: '40px',
              left: '25%',
              borderRadius: '16px',
              py: 1,
            }}
          >
            <VolumeSlider
              volume={volume}
              muted={muted}
              onVolumeChange={handleVolumeChange}
              onVolumeSeekDown={handleVolumeChangeCommitted}
            />
          </Stack>
        )}
        <IconButton
          sx={{
            svg: { stroke: theme => theme.palette.base?.white },
            '&:hover svg': {
              stroke: theme => theme.palette.base?.white,
            },
            opacity: showControls || muted ? 1 : 0,
            visibility: showControls || muted ? 'visible' : 'hidden',
            transition:
              showControls || muted
                ? 'opacity 0.3s ease-in-out, visibility 0s'
                : 'opacity 0.3s ease-in-out, visibility 0s 0.3s',
          }}
          onClick={handleMuteChange}
        >
          {muted && <IconVolume3 />}
          {!muted && <IconVolume />}
        </IconButton>
      </Stack>
    </ControlsContainer>
  );
};

export default Controls;
