<?php

namespace Limb_Chatbot\Includes\Services;

use Limb_Chatbot\Includes\Traits\SingletonTrait;


/**
 * Class Session_Manager
 *
 * Handles session-related tasks such as managing device UUID cookies.
 *
 * @since 1.0.0
 */
class Session_Manager {

	use SingletonTrait;

	/**
	 * Session_Manager constructor.
	 *
	 * Registers initialization hooks.
	 *
	 * @since 1.0.0
	 */
	protected function __construct() {
		add_action( 'init', array( $this, 'init' ), 1 );
	}

	/**
	 * Initializes the session manager, sets device UUID cookie if not present.
	 *
	 * @return void
	 * @since 1.0.0
	 */
	public function init() {
		if ( ! $this->exist_cookie( 'device_uuid' ) ) {
			$this->set_cookie( 'device_uuid', Helper::get_uuid() );
		}
	}

	/**
	 * Sets a cookie with given parameters.
	 *
	 * @param string  $name     Cookie name.
	 * @param string  $value    Cookie value.
	 * @param int     $expire   Expiration timestamp (default 0).
	 * @param bool    $secure   Whether cookie is secure (default false).
	 * @param bool    $httponly Whether cookie is HTTP only (default false).
	 *
	 * @return void
	 * @since 1.0.0
	 */
	public function set_cookie( $name, $value, $expire = 0, $secure = false, $httponly = false ) {
		if ( ! headers_sent( $file, $line ) ) {
			$options = apply_filters( 'lbaic_set_cookie_options', array(
				'expires'  => $expire,
				'secure'   => $secure,
				'path'     => COOKIEPATH ? COOKIEPATH : '/',
				'domain'   => COOKIE_DOMAIN,
				'httponly' => $httponly,
			), $name, $value );
			setcookie( $this->get_cookie_name_prefixed( $name ), $value, $options );
		}
	}

	/**
	 * Checks if a cookie with the given name exists.
	 *
	 * @param string $name Cookie name.
	 *
	 * @return bool True if cookie exists, false otherwise.
	 * @since 1.0.0
	 */
	public function exist_cookie( $name ) {
		return isset( $_COOKIE[ $this->get_cookie_name_prefixed( $name ) ] );
	}

	/**
	 * Returns the cookie name with plugin prefix applied.
	 *
	 * @param string $name Cookie name without prefix.
	 *
	 * @return string Prefixed cookie name.
	 * @since 1.0.0
	 */
	protected function get_cookie_name_prefixed($name) {
		return Limb_Chatbot()->get_plugin_prefix() . '_' . $name;
	}

	/**
	 * Retrieves the value of the cookie with the given name.
	 *
	 * @param string $name Cookie name.
	 *
	 * @return string|null Cookie value or null if not set.
	 * @since 1.0.0
	 */
	public function get_cookie( $name ) {
		$name = $this->get_cookie_name_prefixed( $name );
		if ( isset( $_COOKIE[ $name ] ) ) {
			return sanitize_text_field( wp_unslash( $_COOKIE[ $name ] ) );
		}

		return null;
	}

	/**
	 * Gets the device UUID stored in the cookie.
	 *
	 * @return string|null Device UUID or null if not set.
	 * @since 1.0.0
	 */
	public function get_device_uuid() {
		return $this->get_cookie( 'device_uuid' );
	}

	/**
	 * Generates a fresh REST API nonce for the current user/session.
	 *
	 * This method creates a WordPress nonce specifically for REST API authentication.
	 * The nonce is tied to the current user's session (or guest session via cookies).
	 *
	 * For logged-in users: The nonce is tied to their user ID and session.
	 * For guests: The nonce is tied to the session/cookie (via WordPress's session mechanism).
	 *
	 * @return string The generated nonce.
	 * @since 1.0.0
	 */
	public function get_nonce() {
		return wp_create_nonce( 'wp_rest' );
	}

	/**
	 * Gets the nonce expiration timestamp.
	 *
	 * WordPress nonces typically expire after 24 hours (DAY_IN_SECONDS).
	 * This method returns a Unix timestamp indicating when the nonce will expire.
	 *
	 * @return int Unix timestamp of nonce expiration.
	 * @since 1.0.0
	 */
	public function get_nonce_expiration() {
		return time() + DAY_IN_SECONDS;
	}
}