import React, { forwardRef, useState, MouseEvent } from 'react';

import ClosedCaption from '@material-hu/icons/material/ClosedCaption';
import ClosedCaptionOff from '@material-hu/icons/material/ClosedCaptionOff';
import FullScreen from '@material-hu/icons/material/Fullscreen';
import FullscreenExitIcon from '@material-hu/icons/material/FullscreenExit';
import MoreVertIcon from '@material-hu/icons/material/MoreVert';
import PauseIcon from '@material-hu/icons/material/Pause';
import PlayArrowIcon from '@material-hu/icons/material/PlayArrow';
import RestartAltIcon from '@material-hu/icons/material/RestartAlt';
import VolumeDown from '@material-hu/icons/material/VolumeDown';
import VolumeMute from '@material-hu/icons/material/VolumeOff';
import VolumeUp from '@material-hu/icons/material/VolumeUp';
import Box from '@material-hu/mui/Box';
import IconButton from '@material-hu/mui/IconButton';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';

import usePermissions from 'src/hooks/usePermissions';
import { UserPermissions } from 'src/utils/permissions';

import MoreOptionsPopover from 'src/components/attachment/components/MoreOptionsPopover';
import PlaySlider from 'src/components/attachment/components/PlaySlider';
import SpeedRatePopover from 'src/components/attachment/components/SpeedRatePopover';
import VolumeSlider from 'src/components/attachment/components/VolumeSlider';

const playerIconStyles = {
  width: '38px',
  height: '38px',
  p: 0.5,
  color: '#FFFFFF',
};

const playerIconButtonStyles = {
  svg: {
    stroke: 'unset',
  },
};

export type ControlProps = {
  onSeek: any;
  onSeekMouseDown: () => void;
  onSeekMouseUp: any;
  onPlayPause: () => void;
  onDownload: () => void;
  onPictureInPicture: () => void;
  onVolumeSeekDown: any;
  onVolumeChange: any;
  onPlaybackRateChange: (rate: number) => void;
  onToggleFullScreen: () => void;
  onMute: () => void;
  playing: boolean;
  played: number;
  elapsedTime: string;
  muted: boolean;
  playbackRate: number;
  fullScreenValue: boolean;
  volume: number;
  isPictureInPicture: boolean;
  isVideoEnded: boolean;
  isChat?: boolean;
  idContainer?: string;
  captionsEnabled?: boolean;
  isCaptionsOpen?: boolean;
  onToggleCaptions?: () => void;
  grantDownload: boolean;
  isDownloading?: boolean;
};

export const Controls = forwardRef<
  HTMLDivElement,
  React.PropsWithChildren<ControlProps>
>(function ControlsComponent(props, ref) {
  const {
    onSeek,
    onSeekMouseDown,
    onSeekMouseUp,
    onPlayPause,
    onDownload,
    onPictureInPicture,
    playing,
    played,
    elapsedTime,
    onMute,
    muted,
    onVolumeSeekDown,
    playbackRate,
    onPlaybackRateChange,
    onToggleFullScreen,
    onVolumeChange,
    fullScreenValue,
    volume,
    isPictureInPicture,
    isVideoEnded,
    isChat = false,
    idContainer,
    captionsEnabled,
    isCaptionsOpen,
    onToggleCaptions,
    grantDownload,
    isDownloading,
  } = props;

  const { hasAll: canDownloadVideo } = usePermissions([
    UserPermissions.CAN_DOWNLOAD_VIDEO,
  ]);
  const allowVideoDownload = canDownloadVideo || grantDownload;

  const [anchorRate, setAnchorRate] = useState<HTMLButtonElement | null>(null);
  const [anchorMoreOptions, setAnchorMoreOptions] =
    useState<HTMLButtonElement | null>(null);

  const handleClickRate = (event: MouseEvent<HTMLButtonElement>) =>
    setAnchorRate(event.currentTarget);

  const handleCloseRate = () => setAnchorRate(null);

  const handleClickMoreOptions = (event: MouseEvent<HTMLButtonElement>) =>
    setAnchorMoreOptions(event.currentTarget);

  const handleCloseMoreOptions = () => setAnchorMoreOptions(null);

  const openRate = Boolean(anchorRate);
  const openMoreOptions = Boolean(anchorMoreOptions);
  const id = openRate ? 'simple-popover' : undefined;

  const [showVolumeSlider, setShowVolumeSlider] = useState(false);
  const handleVolumeButtonClick = () => setShowVolumeSlider(true);
  const handleVolumeButtonLeave = () => setShowVolumeSlider(false);

  const handleChangePlaybackRate = (rate: number) => {
    onPlaybackRateChange(rate);
    handleCloseRate();
  };

  return (
    <Box
      ref={ref}
      onClick={onPlayPause}
      sx={{
        visibility: 'hidden',
        position: 'absolute',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        height: '100%',
        width: '100%',
        display: 'flex',
        alignItems: 'flex-end',
        pointerEvents: allowVideoDownload ? 'none' : 'auto',
      }}
    >
      <Box
        onClick={event => event.stopPropagation()}
        sx={{
          display: 'flex',
          alignItems: 'center',
          width: '100%',
          background: 'linear-gradient(180deg, transparent, #00000099)',
          pb: isChat ? '14px' : '0px',
          zIndex: 2,
          pointerEvents: 'auto',
        }}
      >
        <IconButton
          onClick={onPlayPause}
          sx={playerIconButtonStyles}
        >
          {isVideoEnded && <RestartAltIcon sx={playerIconStyles} />}
          {!isVideoEnded && playing && <PauseIcon sx={playerIconStyles} />}
          {!isVideoEnded && !playing && <PlayArrowIcon sx={playerIconStyles} />}
        </IconButton>
        <PlaySlider
          onSeek={onSeek}
          onSeekMouseDown={onSeekMouseDown}
          onSeekMouseUp={onSeekMouseUp}
          played={played}
        />
        <Box sx={{ ml: 1 }}>
          <Typography
            sx={{ color: '#FFFFFF', fontSize: '14px', fontWeight: 600 }}
          >
            {elapsedTime}
          </Typography>
        </Box>
        {captionsEnabled && (
          <IconButton
            sx={{
              ...playerIconButtonStyles,
              ml: 0.6,
              color: theme => theme.palette.common.white,
            }}
            onClick={onToggleCaptions}
          >
            {isCaptionsOpen && <ClosedCaption fontSize="medium" />}
            {!isCaptionsOpen && <ClosedCaptionOff fontSize="medium" />}
          </IconButton>
        )}
        <Box
          onMouseEnter={handleVolumeButtonClick}
          onMouseLeave={handleVolumeButtonLeave}
          sx={{ position: 'relative', ml: 0.6 }}
        >
          {showVolumeSlider && (
            <Box
              sx={{
                backgroundColor: '#00000099',
                height: '96px',
                position: 'absolute',
                bottom: '40px',
                left: '20%',
                borderRadius: '16px',
                display: 'flex',
                alignItems: 'center',
              }}
            >
              <VolumeSlider
                volume={volume}
                muted={muted}
                onVolumeChange={onVolumeChange}
                onVolumeSeekDown={onVolumeSeekDown}
              />
            </Box>
          )}
          <IconButton
            onClick={onMute}
            sx={playerIconButtonStyles}
          >
            {muted && (
              <VolumeMute
                fontSize="medium"
                sx={{ color: '#FFFFFF' }}
              />
            )}
            {!muted && volume > 0.5 && (
              <VolumeUp
                fontSize="medium"
                sx={{ color: '#FFFFFF' }}
              />
            )}
            {!muted && volume <= 0.5 && (
              <VolumeDown
                fontSize="medium"
                sx={{ color: '#FFFFFF' }}
              />
            )}
          </IconButton>
        </Box>
        <Button
          onClick={handleClickRate}
          sx={{ minWidth: 'auto', ml: 0.6 }}
        >
          <Typography sx={{ color: '#FFFFFF', fontWeight: 600 }}>
            {playbackRate}x
          </Typography>
        </Button>
        <SpeedRatePopover
          openRate={openRate}
          id={id}
          idContainer={idContainer}
          handleCloseRate={handleCloseRate}
          anchorRate={anchorRate}
          handleChangePlaybackRate={handleChangePlaybackRate}
          playbackRate={playbackRate}
        />
        <IconButton
          onClick={onToggleFullScreen}
          sx={playerIconButtonStyles}
        >
          {fullScreenValue ? (
            <FullscreenExitIcon
              fontSize="medium"
              sx={{ color: '#FFFFFF' }}
            />
          ) : (
            <FullScreen
              fontSize="medium"
              sx={{ color: '#FFFFFF' }}
            />
          )}
        </IconButton>
        <IconButton
          onClick={handleClickMoreOptions}
          sx={playerIconButtonStyles}
        >
          <MoreVertIcon
            fontSize="medium"
            sx={{ color: '#FFFFFF' }}
          />
        </IconButton>
        <MoreOptionsPopover
          idContainer={idContainer}
          openMoreOptions={openMoreOptions}
          id={id}
          handleCloseMoreOptions={handleCloseMoreOptions}
          anchorMoreOptions={anchorMoreOptions}
          onDownload={onDownload}
          onPictureInPicture={onPictureInPicture}
          isPictureInPicture={isPictureInPicture}
          grantDownload={grantDownload}
          isDownloading={isDownloading}
        />
      </Box>
    </Box>
  );
});

export default Controls;
