<?php
/**
 * AES-256-CBC secret storage for captcha provider keys.
 *
 * @package WP_PowerSuite\Captcha\Shared
 * @since 1.1.0
 */

namespace WP_PowerSuite\Captcha\Shared;

final class SecretCipher {

	public const PREFIX = 'ENC2:';

	public const MASK = '••••••••••••';

	/**
	 * Encrypt a secret for storage. Returns empty string on empty input or failure.
	 */
	public static function encrypt( string $value, string $domain_key ): string {
		if ( $value === '' ) {
			return '';
		}
		if ( str_starts_with( $value, self::PREFIX ) ) {
			return $value;
		}
		if ( ! function_exists( 'openssl_encrypt' ) ) {
			return '';
		}

		$auth_key  = defined( 'AUTH_KEY' ) && AUTH_KEY ? AUTH_KEY : ABSPATH;
		$key       = hash( 'sha256', $domain_key . $auth_key, true );
		$iv        = openssl_random_pseudo_bytes( 16 );
		$encrypted = openssl_encrypt( $value, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv );
		if ( $encrypted === false ) {
			return '';
		}

		return self::PREFIX . base64_encode( $iv . $encrypted );
	}

	/**
	 * Decrypt a secret. Legacy plaintext values (no prefix) pass through unchanged.
	 */
	public static function decrypt( string $value, string $domain_key ): string {
		if ( $value === '' ) {
			return '';
		}
		if ( ! str_starts_with( $value, self::PREFIX ) ) {
			return $value;
		}
		if ( ! function_exists( 'openssl_decrypt' ) ) {
			return '';
		}

		$encoded  = substr( $value, strlen( self::PREFIX ) );
		$auth_key = defined( 'AUTH_KEY' ) && AUTH_KEY ? AUTH_KEY : ABSPATH;
		$key      = hash( 'sha256', $domain_key . $auth_key, true );
		$data     = base64_decode( $encoded, true );
		if ( $data === false || strlen( $data ) < 17 ) {
			return '';
		}

		$iv        = substr( $data, 0, 16 );
		$encrypted = substr( $data, 16 );
		$decrypted = openssl_decrypt( $encrypted, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv );

		return $decrypted !== false ? $decrypted : '';
	}
}
