import { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withSnackbar } from 'notistack';
import * as notificationActions from '../../actions/notificationActions';

class Notifications extends Component
{
	displayed = [];

	storeDisplayed = (id) =>
	{
		this.displayed = [ ...this.displayed, id ];
	};

	shouldComponentUpdate({ notifications: newNotifications = [] })
	{
		const { notifications: currentNotifications } = this.props;

		let notExists = false;

		for (let i = 0; i < newNotifications.length; i += 1)
		{
			if (notExists) continue;

			notExists = notExists ||
				!currentNotifications.filter(({ id }) => newNotifications[i].id === id).length;
		}

		return notExists;
	}

	componentDidUpdate()
	{
		const { notifications = [] } = this.props;

		notifications.forEach((notification) =>
		{
			// Do nothing if snackbar is already displayed
			if (this.displayed.includes(notification.id)) return;
			// Display snackbar using notistack
			this.props.enqueueSnackbar(notification.text,
				{
					variant          : notification.type,
					autoHideDuration : notification.timeout,
					anchorOrigin     : {
						vertical   : 'bottom',
						horizontal : 'left'
					}
				}
			);
			// Keep track of snackbars that we've displayed
			this.storeDisplayed(notification.id);
			// Dispatch action to remove snackbar from redux store
			this.props.removeNotification(notification.id);
		});
	}

	render()
	{
		return null;
	}
}

Notifications.propTypes =
{
	notifications      : PropTypes.array.isRequired,
	enqueueSnackbar    : PropTypes.func.isRequired,
	removeNotification : PropTypes.func.isRequired
};

const mapStateToProps = (state) =>
	({
		notifications : state.notifications
	});

const mapDispatchToProps = (dispatch) =>
	({
		removeNotification : (notificationId) =>
			dispatch(notificationActions.removeNotification({ notificationId }))
	});

export default withSnackbar(
	connect(
		mapStateToProps,
		mapDispatchToProps,
		null,
		{
			areStatesEqual : (next, prev) =>
			{
				return (
					prev.notifications === next.notifications
				);
			}
		}
	)(Notifications)
);
