<?php
/**
 * MindWebConcierge Session Manager
 *
 * @package MindWebConcierge
 */

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

/**
 * Class Mindweco_Session
 */
class Mindweco_Session {

	/**
	 * Request key used for the tab-scoped frontend session ID.
	 *
	 * @var string
	 */
	const FRONTEND_SESSION_KEY = 'tab_session_id';

	/**
	 * Legacy request key used by earlier frontend builds.
	 *
	 * @var string
	 */
	const LEGACY_FRONTEND_SESSION_KEY = 'mindweco_tab_session_id';

	/**
	 * Returns a session ID for legacy callers.
	 *
	 * The current frontend flow supplies the tab-scoped ID through request
	 * parameters. If one is present, it is returned. Otherwise a request-local
	 * UUID is generated so older callers still receive a usable identifier.
	 *
	 * @return string UUID v4 session ID.
	 */
	public static function get_id() {
		static $fallback_session_id = null;

		$session_id = self::get_frontend_session_id();
		if ( '' !== $session_id ) {
			return $session_id;
		}

		if ( null === $fallback_session_id ) {
			$fallback_session_id = wp_generate_uuid4();
		}

		return $fallback_session_id;
	}

	/**
	 * Returns the tab-scoped session ID supplied by the frontend.
	 *
	 * The frontend stores this UUID in sessionStorage and sends it with every
	 * chat request. If the ID is missing or invalid, an empty string is returned.
	 *
	 * @return string UUID v4 session ID, or an empty string when unavailable.
	 */
	public static function get_frontend_session_id() {
		$keys = array( self::FRONTEND_SESSION_KEY, self::LEGACY_FRONTEND_SESSION_KEY );

		foreach ( array( $_POST, $_GET ) as $request ) {
			foreach ( $keys as $key ) {
				if ( ! isset( $request[ $key ] ) ) {
					continue;
				}

				$raw_sid = $request[ $key ];
				if ( ! is_scalar( $raw_sid ) ) {
					continue;
				}

				$sid = sanitize_text_field( wp_unslash( $raw_sid ) );

				if ( self::is_valid_uuid( $sid ) ) {
					return $sid;
				}
			}
		}

		return '';
	}

	/**
	 * Legacy compatibility shim retained for callers that still expect it.
	 *
	 * The frontend session is tab-scoped in sessionStorage, so there is
	 * nothing to clear here.
	 *
	 * @return void
	 */
	public static function destroy() {
		// Intentionally empty.
	}

	/**
	 * Validates that a string is a UUID v4.
	 *
	 * @param string $uuid The string to validate.
	 * @return bool
	 */
	private static function is_valid_uuid( $uuid ) {
		return (bool) preg_match(
			'/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i',
			$uuid
		);
	}
}
