// @flow
import React, { useState, useCallback, useEffect } from 'react';
import styled from 'styled-components';
import { Box } from '../../../../primitives';
import { UnstyledButton } from '../../../behaviors';
import { Span } from '../../../typography';
import { Close as CloseIcon } from '../../../icon';
import { getPaletteColor } from '../../../../mixins/branding';
import type { ToastProps } from './toast.proptypes';
import { getBackgroundColor } from './toast.css-rules';

const StyledToastContainer = styled.div`
  margin-bottom: 10px;
  transition: all 100ms linear;
  z-index: 1;

  &:last-child {
    margin-bottom: 0;
  }
`;

export const StyledToast = styled.div`
  pointer-events: auto;
  display: inline-block;
  background-color: ${getBackgroundColor};
  color: ${getPaletteColor('white')};
  padding: 20px;
  border-radius: 6px;
  box-shadow: 0 5px 15px 0 rgba(191, 189, 187, 0.5);
`;

const StyledToastInnerElement = styled.div`
  display: inline-block;
  min-height: 16px;
  line-height: 1.4;
`;

export const CloseButton = styled(UnstyledButton)`
  height: 16;
  display: flex;
`;

export const Toast = ({
  id,
  children,
  timerDelay = 5000,
  onClose,
  level,
  closeButtonLabel = 'Dismiss',
}: ToastProps) => {
  const [show, setShow] = useState(true);
  const [animationTimerId, setAnimationTimerId] = useState(null);

  const handleClose = useCallback(() => {
    setShow(false);
    if (onClose) {
      onClose(id);
    }
  }, [id, onClose]);

  const startTimer = useCallback(() => {
    if (timerDelay > 0) {
      const timerId = window.setTimeout(handleClose, timerDelay);
      setAnimationTimerId(timerId);
    }
  }, [handleClose, timerDelay]);

  const stopTimer = useCallback(() => {
    if (animationTimerId === null) return;

    window.clearTimeout(animationTimerId);
    setAnimationTimerId(null);
  }, [animationTimerId]);

  const handleMouseIn = useCallback(() => {
    stopTimer();
  }, [stopTimer]);

  const handleMouseOut = useCallback(() => {
    startTimer();
  }, [startTimer]);

  useEffect(() => {
    startTimer();
  }, [startTimer]);

  if (!show) return null;

  return (
    <StyledToastContainer>
      <StyledToast
        onMouseOver={handleMouseIn}
        onFocus={handleMouseIn}
        onMouseOut={handleMouseOut}
        onBlur={handleMouseOut}
        level={level}
      >
        <Box stacked="row" justify="center" align="center">
          <StyledToastInnerElement>
            <Span fontSize="f1" colorName="white" bold face="sans">
              {children}
            </Span>
          </StyledToastInnerElement>
          <StyledToastInnerElement style={{ marginLeft: 40 }}>
            <CloseButton
              insetFocus
              onFocus={handleMouseIn}
              onBlur={handleMouseOut}
              onClick={handleClose}
              aria-label={closeButtonLabel}
            >
              <CloseIcon />
            </CloseButton>
          </StyledToastInnerElement>
        </Box>
      </StyledToast>
    </StyledToastContainer>
  );
};

Toast.displayName = 'Toast';
