<?php
/**
 * User storage utilities (common)
 *
 * Encodes/decodes miniOrange customer details stored in WordPress options so
 * common code (e.g. User_Service) does not depend on premium-only classes.
 *
 * @package    MOMCS_Sync
 * @subpackage MOMCS_Sync\includes\common\utils
 */

declare(strict_types=1);

namespace MOMCS_Sync\Includes\Common\Utils;

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

/**
 * Class User_Storage_Utils
 *
 * XOR + Base64 helpers and option keys shared with the license library.
 */
class User_Storage_Utils {

	/**
	 * Base64-encoded option name for user details storage.
	 * Decodes to: momcs_user_details
	 * Must match the option name used by license library (Mo_License_Service_Utility).
	 */
	public const USER_DETAILS_OPTION = 'bW9tY3NfdXNlcl9kZXRhaWxz';

	/**
	 * User detail keys used for encoding/decoding.
	 */
	public const KEY_CUSTOMER_TOKEN     = 'momcs_customer_token';
	public const KEY_CUSTOMER_EMAIL     = 'momcs_customer_email';
	public const KEY_CUSTOMER_ID        = 'momcs_customer_id';
	public const KEY_CUSTOMER_API_KEY   = 'momcs_customer_api_key';
	public const KEY_CUSTOMER_LOGGED_IN = 'momcs_customer_logged_in';

	/**
	 * License-related option keys for cleanup (aligned with premium flow).
	 *
	 * @var array<string>
	 */
	public const LICENSE_OPTIONS = array(
		'momcs_miniorange_user',
		'bW9tY3NfdXNlcl9kZXRhaWxz',
		'bW93Y3BzX3VzZXJfZGV0YWlscw==',
		'momcs_user_display_details',
		'momcs_lk',
		'momcs_led',
		'momcs_tla',
		'momcs_license_expired',
		'momcs_ln_check_t',
		'momcs_exp_notice_close',
	);

	/**
	 * Encode a string using XOR with the stored customer token.
	 *
	 * @param string $input The string to encode.
	 * @return string|false Encoded string on success, false on failure.
	 */
	public static function encoder( string $input ): string|false {
		$token = self::get_customer_token();
		if ( empty( $token ) || empty( $input ) ) {
			return false;
		}

		$token_length = strlen( $token );
		$input_length = strlen( $input );
		$result       = '';

		for ( $i = 0; $i < $input_length; $i++ ) {
			$token_char = $token[ $i % $token_length ];
			$encoded    = chr( ( ord( $input[ $i ] ) + ord( $token_char ) ) % 256 );
			$result    .= $encoded;
		}

		// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Required for secure storage.
		return base64_encode( $result );
	}

	/**
	 * Decode a string encoded with encoder().
	 *
	 * @param string $input The encoded string to decode.
	 * @return string|false Decoded string on success, false on failure.
	 */
	public static function decoder( string $input ): string|false {
		$token = self::get_customer_token();
		if ( empty( $token ) || empty( $input ) ) {
			return false;
		}

		// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode -- Required for secure storage.
		$decoded_input = base64_decode( $input, true );
		if ( false === $decoded_input ) {
			return false;
		}

		$token_length = strlen( $token );
		$input_length = strlen( $decoded_input );
		$result       = '';

		for ( $i = 0; $i < $input_length; $i++ ) {
			$token_char = $token[ $i % $token_length ];
			$decoded    = chr( ( ord( $decoded_input[ $i ] ) - ord( $token_char ) + 256 ) % 256 );
			$result    .= $decoded;
		}

		return $result;
	}

	/**
	 * Get the customer token from stored user details.
	 *
	 * @return string|null Customer token or null if not found.
	 */
	public static function get_customer_token(): ?string {
		$user_details = get_option( self::USER_DETAILS_OPTION, array() );

		if ( ! is_array( $user_details ) ) {
			return null;
		}

		// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Required for key lookup.
		$token_key = base64_encode( self::KEY_CUSTOMER_TOKEN );

		if ( isset( $user_details[ $token_key ] ) ) {
			// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode -- Required for token retrieval.
			$decoded = base64_decode( (string) $user_details[ $token_key ], true );
			return false !== $decoded ? $decoded : null;
		}

		return null;
	}
}
