<?php namespace BulkPriceEditor\PriceEditorPage\Notifications;

class NotificationManager {
	
	const NOTIFICATION_OPTION_KEY = 'bulk_price_editor_price_notifications';
	
	protected static ?self $instance;
	protected array $nextRequestNotifications = array();
	
	protected function __construct() {
		add_action( 'shutdown', function () {
			$this->handleFlashNotifications();
		} );
	}
	
	public static function getInstance(): self {
		if ( ! isset( self::$instance ) ) {
			self::$instance = new self();
		}
		
		return self::$instance;
	}
	
	protected function _addNotification( Notification $notification ) {
		$notifications = $this->getAllNotifications();
		
		if ( $notification->isFlash() ) {
			$this->nextRequestNotifications[] = $notification;
		} else {
			$notifications[] = $notification;
			$this->updateNotifications( $notifications );
		}
	}
	
	public function updateNotifications( array $notifications ) {
		
		$notifications = array_filter( $notifications, function ( $notification ) {
			return $notification instanceof Notification && $notification->getMessage() !== '';
		} );
		
		$notifications = array_map( function ( $notification ) {
			return $notification->getAsArray();
		}, $notifications );
		
		update_option( self::NOTIFICATION_OPTION_KEY, $notifications );
	}
	
	/**
	 * Get all notifications
	 *
	 * @return Notification[]
	 */
	public function getAllNotifications(): array {
		$notifications = get_option( self::NOTIFICATION_OPTION_KEY, array() );
		
		return array_map( function ( $notification ) {
			return Notification::build( $notification );
		}, $notifications );
	}
	
	protected function handleFlashNotifications() {
		
		$notifications = $this->getAllNotifications();
		
		if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
			// Remove all notifications that are not permanent
			$notifications = array_filter( $notifications, function ( $notification ) {
				return $notification->isPermanent();
			} );
		}
		
		foreach ( $this->nextRequestNotifications as $notification ) {
			$notifications[] = $notification;
		}
		
		$this->updateNotifications( $notifications );
	}
	
	public static function addNotification( Notification $notification ) {
		self::getInstance()->_addNotification( $notification );
	}
}
