<?php
/**
 * Tracking Dispatcher
 *
 * @package AmbassadorHub\Tracking
 */

namespace AmbassadorHub\Tracking;

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

/**
 * Fans a TrackingEvent out to all configured providers.
 *
 * Errors in individual providers are caught and logged so that a broken
 * provider never interrupts the donation flow or other core behaviour.
 */
final class TrackingDispatcher {

	/**
	 * Dispatch an event to every configured tracking provider.
	 *
	 * Providers that return false from is_configured() are skipped silently.
	 * Any exception thrown inside a provider is caught and logged to the PHP
	 * error log — it never propagates to the caller.
	 *
	 * @param TrackingEvent $event Event to dispatch.
	 *
	 * @return void
	 */
	public static function dispatch( TrackingEvent $event ): void {
		foreach ( TrackingRegistry::get_providers() as $provider ) {
			if ( ! $provider->is_configured() ) {
				continue;
			}

			try {
				$provider->track( $event );
			} catch ( \Throwable $e ) {
				// Intentional: silently log provider failures so a broken tracking
				// provider never interrupts the donation flow.
				if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
					// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
					error_log(
						sprintf(
							'[AmbassadorHub Tracking] Provider "%s" failed for event "%s": %s',
							$provider->get_id(),
							$event->name,
							$e->getMessage()
						)
					);
				}
			}
		}
	}

	/**
	 * Extract the GA4 client_id from the _ga browser cookie.
	 *
	 * The _ga cookie format is: GA1.X.XXXXXXXXXX.XXXXXXXXXX
	 * The client_id is the last two dot-separated segments joined by a dot.
	 *
	 * Returns null when:
	 * - The _ga cookie is absent (server-to-server webhook context).
	 * - The cookie value does not match the expected format.
	 *
	 * @return string|null
	 */
	public static function get_client_id_from_cookie(): ?string {
		if ( empty( $_COOKIE['_ga'] ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
			return null;
		}

		$raw   = sanitize_text_field( wp_unslash( $_COOKIE['_ga'] ) );
		$parts = explode( '.', $raw );

		// Format: GA1.X.<clientid_part1>.<clientid_part2>
		if ( count( $parts ) >= 4 ) {
			return $parts[2] . '.' . $parts[3];
		}

		return null;
	}
}
