import { type FC, useRef, useState } from 'react';

import {
  IconMicrophone,
  IconPlayerPause,
  IconPlayerPlay,
  IconSend,
  IconTrash,
} from '@material-hu/icons/tabler';
import Box from '@material-hu/mui/Box';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import { keyframes, styled } from '@material-hu/mui/styles';
import Typography from '@material-hu/mui/Typography';

import { formatMinutes, formatSeconds } from 'src/utils/record';

import useTimerAudio from '../../../hooks/useTimerAudio';

import LoopingWave from './LoopingWave';

type AudioRecorderProps = {
  audioUrl?: string | null;
  isRecording: boolean;
  onResume?: () => void;
  onPause?: () => void;
  onDelete?: () => void;
  onSendMessage?: (param: number) => void;
};

const spin = keyframes`
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
`;

type AnimationBulletRecordProps = {
  isRecording: boolean;
};

const SIZE_ICON = 40;

const AnimationBulletRecord = styled(Box, {
  shouldForwardProp: prop => prop !== 'isRecording',
})<AnimationBulletRecordProps>(({ theme, isRecording }) => ({
  backgroundColor: theme.palette.new.text.feedback.error,
  width: 10,
  height: 10,
  marginRight: 6,
  borderRadius: '50%',
  animation: `${isRecording ? spin : undefined} 1s infinite ease`,
}));

const AudioRecorder: FC<AudioRecorderProps> = props => {
  const { onResume, onPause, onDelete, isRecording, onSendMessage, audioUrl } =
    props;
  const [play, setPlay] = useState(false);
  const audioRef = useRef<HTMLAudioElement | null>(null);

  const timerRecorder = useTimerAudio(isRecording);

  const handleResume = () => {
    setPlay(false);
    onResume?.();
  };

  const handlePlayAudio = () => {
    audioRef.current?.play();
    setPlay(true);
  };

  const handlePauseAudio = () => {
    audioRef.current?.pause();
    setPlay(false);
  };

  const handleEnded = () => {
    audioRef.current?.load();
    setPlay(false);
  };

  const handleSendMessage = () =>
    onSendMessage?.(timerRecorder.elapsedMilliseconds);

  return (
    <Stack
      sx={{
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'flex-end',
        width: '100%',
      }}
    >
      <IconButton
        variant="tertiary"
        sx={{
          height: SIZE_ICON,
          width: SIZE_ICON,
        }}
        onClick={onDelete}
      >
        <IconTrash />
      </IconButton>
      {audioUrl && !isRecording && (
        <IconButton
          variant="tertiary"
          sx={{
            height: SIZE_ICON,
            width: SIZE_ICON,
          }}
          onClick={!play ? handlePlayAudio : handlePauseAudio}
        >
          {!play ? <IconPlayerPlay /> : <IconPlayerPause />}
        </IconButton>
      )}
      <LoopingWave isRecording={isRecording} />
      {isRecording && <AnimationBulletRecord isRecording={isRecording} />}
      <Typography
        color="textSecondary"
        variant="subtitle2"
      >
        {`${formatMinutes(timerRecorder.recordingMinutes)}:${formatSeconds(timerRecorder.recordingSeconds)}`}
      </Typography>
      <Stack>
        {audioUrl && !isRecording && (
          <audio
            ref={audioRef}
            src={audioUrl}
            onEnded={handleEnded}
          />
        )}
      </Stack>
      {isRecording && (
        <IconButton
          variant="tertiary"
          sx={{
            mx: 1,
            height: SIZE_ICON,
            width: SIZE_ICON,
          }}
          onClick={onPause}
        >
          <IconPlayerPause />
        </IconButton>
      )}
      {!isRecording && (
        <IconButton
          variant="tertiary"
          sx={{
            mx: 1,
            height: SIZE_ICON,
            width: SIZE_ICON,
          }}
          onClick={handleResume}
        >
          <IconMicrophone />
        </IconButton>
      )}
      <IconButton
        onClick={handleSendMessage}
        variant="secondary"
        sx={{
          height: SIZE_ICON,
          width: SIZE_ICON,
        }}
      >
        <IconSend />
      </IconButton>
    </Stack>
  );
};

export default AudioRecorder;
