<?php
/**
 * Toast notification queue system.
 *
 * @package BricksExtras
 */

namespace BricksExtras;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Toast Queue Helper.
 *
 * Allows developers to queue toast notifications from PHP that will be displayed on page load.
 */
class BricksExtrasToast {

	/**
	 * Session key for storing queued toasts.
	 */
	const SESSION_KEY = 'bricksextras_toast_queue';

	/**
	 * Initialize the toast queue system.
	 */
	public static function init() {
		// Start session if not already started.
		add_action( 'init', array( __CLASS__, 'maybe_start_session' ), 1 );

		// Enqueue toasts in footer.
		add_action( 'wp_footer', array( __CLASS__, 'render_queued_toasts' ), 999 );
	}

	/**
	 * Start session if not already started.
	 */
	public static function maybe_start_session() {

		if ( ! session_id() && ! headers_sent() ) {
			session_start();
		}
	}

	/**
	 * Get session data.
	 *
	 * @return array Validated session queue data.
	 */
	private static function get_session_queue() {

		if ( ! isset( $_SESSION[ self::SESSION_KEY ] ) || ! is_array( $_SESSION[ self::SESSION_KEY ] ) ) {
			return array();
		}

		$session_data = $_SESSION[ self::SESSION_KEY ];

		$validated = array();
		foreach ( $session_data as $item ) {

			if ( ! is_array( $item ) ) {
				continue;
			}

			// Check required keys exist.
			if ( ! isset( $item['notification_id'], $item['message'], $item['announce'], $item['duration'], $item['context_icon'], $item['dismissible'], $item['close_button'], $item['timestamp'] ) ) {
				continue;
			}

			$notification_id = sanitize_text_field( $item['notification_id'] );
			$message         = wp_kses_post( $item['message'] );
			$announce        = sanitize_text_field( $item['announce'] );
			$duration        = intval( $item['duration'] );
			$context_icon    = (bool) $item['context_icon'];
			$dismissible     = (bool) $item['dismissible'];
			$close_button    = (bool) $item['close_button'];
			$timestamp       = intval( $item['timestamp'] );

			// Validate announce is in allowed list.
			if ( ! in_array( $announce, array( 'polite', 'assertive', 'off' ), true ) ) {
				$announce = 'polite';
			}

			$validated[] = array(
				'notification_id' => $notification_id,
				'message'         => $message,
				'announce'        => $announce,
				'duration'        => $duration,
				'context_icon'    => $context_icon,
				'dismissible'     => $dismissible,
				'close_button'    => $close_button,
				'timestamp'       => $timestamp,
			);
		}

		return $validated;
	}

	/**
	 * Queue a toast notification.
	 *
	 * @param string $notification_id The Bricks element ID of the toast notification (e.g., 'ghijkl').
	 * @param string $message Optional message to override notification content.
	 * @param string $announce ARIA live region announcement: 'polite', 'assertive', or 'off' (default: 'polite').
	 * @param int    $duration Duration in milliseconds (default: 5000).
	 * @param bool   $context_icon Include context icon if it exists (default: true).
	 * @param bool   $dismissible Allow swipe to dismiss (default: true).
	 * @param bool   $close_button Show close button (default: false).
	 */
	public static function add( $notification_id, $message = '', $announce = 'polite', $duration = 5000, $context_icon = true, $dismissible = true, $close_button = false ) {

		// Validate announce value.
		$allowed_announce = array( 'polite', 'assertive', 'off' );
		if ( ! in_array( $announce, $allowed_announce, true ) ) {
			$announce = 'polite';
		}

		$toast_data = array(
			'notification_id' => sanitize_text_field( $notification_id ),
			'message'         => $message ? wp_kses_post( $message ) : '',
			'announce'        => sanitize_text_field( $announce ),
			'duration'        => intval( $duration ),
			'context_icon'    => (bool) $context_icon,
			'dismissible'     => (bool) $dismissible,
			'close_button'    => (bool) $close_button,
			'timestamp'       => time(),
		);

		// Check for duplicate - prevent same notification from being queued multiple times.
		$queue = self::get_session_queue();
		foreach ( $queue as $existing ) {
			// Validate existing item structure.
			if ( ! is_array( $existing ) ||
				! isset( $existing['notification_id'], $existing['message'], $existing['timestamp'] ) ) {
				continue;
			}

			if ( $existing['notification_id'] === $toast_data['notification_id'] &&
				$existing['message'] === $toast_data['message'] &&
				( time() - $existing['timestamp'] ) < 2 ) { // Within 2 seconds.
				return;
			}
		}

		// Add to session.
		if ( ! isset( $_SESSION[ self::SESSION_KEY ] ) ) {
			$_SESSION[ self::SESSION_KEY ] = array();
		}
		$_SESSION[ self::SESSION_KEY ][] = $toast_data;
	}


	/**
	 * Get all queued toasts.
	 *
	 * @return array
	 */
	public static function get_queue() {
		$queue = self::get_session_queue();

		$validated_queue = array();
		foreach ( $queue as $item ) {
			if ( is_array( $item ) && isset( $item['notification_id'] ) ) {
				$validated_queue[] = $item;
			}
		}

		return $validated_queue;
	}

	/**
	 * Clear the toast queue.
	 */
	public static function clear() {
		if ( isset( $_SESSION[ self::SESSION_KEY ] ) ) {
			unset( $_SESSION[ self::SESSION_KEY ] );
		}
	}


	/**
	 * Render queued toasts as data attribute.
	 */
	public static function render_queued_toasts() {
		$queue = self::get_queue();

		if ( empty( $queue ) ) {
			return;
		}

		// Clear the queue after retrieving.
		self::clear();
		?>
		
		<script id="bricksextras-toast-queue" type="application/json">
		<?php echo wp_json_encode( $queue, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT ); ?>
		</script>
		<?php
	}
}