<?php
/**
 * Guest member service for handling non-logged-in member operations.
 *
 * @package RewardsWP
 */

namespace Awesomemotive\Rewardswp\Services;

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

use Awesomemotive\Rewardswp\Models\Member;
use Awesomemotive\Rewardswp\Helpers\CookieHelper;
use function Awesomemotive\Rewardswp\Helpers\get_member_by;

class GuestMemberService {
	/**
	 * Cookie key for guest member token.
	 *
	 * @since 1.0.0
	 */
	const MEMBER_TOKEN_KEY = 'rewardswp_member_access_token';

	/**
	 * Default token expiration in days.
	 *
	 * @since 1.0.0
	 */
	const MEMBER_TOKEN_DAYS_TO_EXPIRE = 400; // Maximum number of days accepted by modern browsers.

	/**
	 * Cookie helper instance.
	 *
	 * @since 1.0.0
	 *
	 * @var CookieHelper
	 */
	private CookieHelper $cookie_helper;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param CookieHelper $cookie_helper Cookie Helper.
	 */
	public function __construct( CookieHelper $cookie_helper ) {
		$this->cookie_helper = $cookie_helper;
	}

	/**
	 * Create the cookie.
	 *
	 * @since 1.0.0
	 *
	 * @param string $member_token Member token.
	 *
	 * @return void
	 */
	public function set_cookie( string $member_token ): void {
		$this->cookie_helper->set_cookie(
			self::MEMBER_TOKEN_KEY,
			sanitize_text_field( $member_token ),
			self::MEMBER_TOKEN_DAYS_TO_EXPIRE
		);
	}

	/**
	 * Save token to the local storage.
	 *
	 * @since 1.0.0
	 *
	 * @param string $member_token Member token.
	 *
	 * @return void
	 */
	public function save_token_to_local_storage( string $member_token ): void {
		wp_add_inline_script(
			AssetsService::MAIN_SCRIPT_HANDLE,
			sprintf(
				"localStorage.setItem( '%s', '%s' );",
				esc_js( self::MEMBER_TOKEN_KEY ),
				esc_js( $member_token )
			),
			'before'
		);
	}

	/**
	 * Save token to the local storage and create the cookie.
	 *
	 * @since 1.0.0
	 *
	 * @param string $member_token Member token.
	 *
	 * @return void
	 */
	public function persist_token( string $member_token ): void {
		$this->set_cookie( $member_token );
		$this->save_token_to_local_storage( $member_token );
	}

	/**
	 * Retrieve the persisted token from the cookies.
	 *
	 * @since 1.0.0
	 *
	 * @return string|null The token value or null if can't find.
	 */
	public function get_persisted_token(): ?string {
		return $this->cookie_helper->get_cookie( self::MEMBER_TOKEN_KEY );
	}

	/**
	 * Retrieve a member by token.
	 *
	 * @since 1.0.0
	 *
	 * @param string|null $member_token The member token.
	 *
	 * @return Member|null
	 */
	public function get_member_by_token( ?string $member_token = null ): ?Member {
		$member_token = $member_token ?? $this->get_persisted_token();

		if ( empty( $member_token ) ) {
			return null;
		}

		return get_member_by( 'token', $member_token );
	}
}
