import { connect } from 'react-redux';
import { withStyles } from '@material-ui/core/styles';
import CheckCircleIcon from '@material-ui/icons/CheckCircle';
import CloseIcon from '@material-ui/icons/Close';
import ErrorIcon from '@material-ui/icons/Error';
import IconButton from '@material-ui/core/IconButton';
import InfoIcon from '@material-ui/icons/Info';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import SnackbarContent from '@material-ui/core/SnackbarContent';
import WarningIcon from '@material-ui/icons/Warning';
import amber from '@material-ui/core/colors/amber';
import classNames from 'classnames';
import green from '@material-ui/core/colors/green';

import notificationActions from '../redux/actions';

import 'animate.css/source/zooming_exits/zoomOutUp.css';

const variantIcon = {
  success: CheckCircleIcon,
  warning: WarningIcon,
  error: ErrorIcon,
  info: InfoIcon
};

const styles = theme => {
  const margin = theme.spacing.unit;
  return {
    success: {
      backgroundColor: green[600],
      margin
    },
    error: {
      backgroundColor: theme.palette.error.dark,
      margin
    },
    info: {
      backgroundColor: theme.palette.primary.dark,
      margin
    },
    warning: {
      backgroundColor: amber[700],
      margin
    },
    icon: {
      fontSize: 25
    },
    iconVariant: {
      opacity: 0.9,
      marginRight: theme.spacing.unit
    },
    closeIcon: {
      fontSize: 20
    },
    message: {
      alignItems: 'center',
      display: 'flex',
      fontSize: 16
    }
  };
};

const mapDispatchToProps = notificationActions;

@withStyles(styles)
@connect(() => ({}), mapDispatchToProps)
export default class Notification extends Component {
  static propTypes = {
    $key: PropTypes.string.isRequired,
    autoDismissMillis: PropTypes.number,
    classes: PropTypes.shape({}).isRequired,
    dismissNotification: PropTypes.func.isRequired,
    message: PropTypes.node.isRequired,
    onDismiss: PropTypes.func,
    variant: PropTypes.oneOf([ 'success', 'warning', 'error', 'info' ]).isRequired
  };

  static defaultProps = {
    autoDismissMillis: 5000,
    onDismiss: () => {}
  }

  state = {
    discard: false
  }

  componentDidMount() {
    if (this.props.autoDismissMillis > 0) {
      setTimeout(this.close, this.props.autoDismissMillis);
    }
  }

  close = userDismissed => {
    if (!this.state.discard) {
      this.setState({ discard: true });
      setTimeout(() => { this.props.dismissNotification(this.props.$key); }, 1000);
      this.props.onDismiss(!!userDismissed);
    }
  }

  render() {
    const { classes, message, variant } = this.props;
    const { discard } = this.state;
    const Icon = variantIcon[variant];
    return (
      <SnackbarContent
        action={(
          <IconButton
            aria-label='Close'
            className={classes.close}
            color='inherit'
            onClick={() => { this.close(true); }}
          >
            <CloseIcon className={classNames(classes.closeIcon, classes.iconVariant)} />
          </IconButton>
        )}
        aria-describedby='user-snackbar'
        className={classNames(classes[variant], { 'animated zoomOutUp': discard }, 'notification')}
        message={(
          <span className={classes.message}>
            <Icon className={classNames(classes.icon, classes.iconVariant)} />
            {message}
          </span>
        )}
      />
    );
  }
}
