import React, { useState, useEffect } from 'react';
import convertTimeToString from '../utils/convertTimeToString';

interface PropTypes {
  registerResult: (result: string) => void;
  maxCountdown?: number;
}

enum Mode {
  'idle',
  'countdown',
  'running' ,
  'over',
};

const helperTextMap = {
  [Mode.idle]: (
    <>
      <span>Hold </span>
      <code>SPACE</code>
      <span> to start countdown</span>
    </>
  ),
  [Mode.countdown]: (
    <>
      <span>Release </span>
      <code>SPACE</code>
      <span> to begin</span>
    </>
  ),
  [Mode.running]: 'Go fast!',
  [Mode.over]: 'You are too late!',
};

const KEY_CODE = 32; // Space key

const Timer: React.FC<PropTypes> = ({ registerResult, maxCountdown = 15000 }) => {
  const [mode, setMode] = useState<Mode>(Mode.idle);
  const [displayTime, setDisplayTime] = useState<string>('00:00:00');

  useEffect(() => {
    const timestamp = Date.now();

    if (mode === Mode.countdown) {
      const repeater = setInterval(() => {
        const timeDelta = maxCountdown - (Date.now() - timestamp);
        if (timeDelta <= 0) setMode(Mode.over);
        setDisplayTime(convertTimeToString(timeDelta));
      }, 10);
      return (): void => clearInterval(repeater);
    }

    if (mode === Mode.running) {
      const repeater = setInterval(() => {
        setDisplayTime(convertTimeToString(Date.now() - timestamp));
      }, 10);
      return (): void => clearInterval(repeater);
    }

    if (mode === Mode.over) {
      setDisplayTime('00:00:00');
    }
  }, [mode, maxCountdown]);

  const handleKeyPress = (event: KeyboardEvent): void => {
    event.preventDefault();
    if (event.keyCode === KEY_CODE && mode === Mode.idle) setMode(Mode.countdown);
  };

  const handleKeyUp = (event: KeyboardEvent): void => {
    if (event.keyCode === KEY_CODE) {
      if (mode === Mode.running) {
        registerResult(displayTime);
        setMode(Mode.idle);
      } else if (mode === Mode.over) {
        setMode(Mode.idle);
      } else {
        setMode(Mode.running);
      }
    }
  };

  useEffect(() => {
    window.addEventListener('keyup', handleKeyUp);
    window.addEventListener('keypress', handleKeyPress);

    return () => {
      window.removeEventListener('keyup', handleKeyUp);
      window.removeEventListener('keypress', handleKeyPress);
    };
  });

  return (
    <>
      <b>{ displayTime }</b>
      <p>{ helperTextMap[mode] }</p>
    </>
  );
};

export default Timer;
