<?php
/**
 * AES-256-CBC Encryption Helper
 *
 * @package Ugcify\Helpers
 */

namespace Ugcify\Helpers;

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

/**
 * Class Encryption
 *
 * Provides AES-256-CBC encryption/decryption using WordPress salts.
 * Key derivation: SHA-256 of wp_salt('auth')
 * IV derivation:  First 16 bytes of SHA-256 of wp_salt('secure_auth')
 *
 * Credentials are bound to the specific WordPress installation.
 * Copying the database to another site (with different wp-config.php salts)
 * will render all encrypted values unrecoverable — by design.
 */
class Encryption {

	/**
	 * Encrypt a plaintext value for storage.
	 *
	 * @param string $plaintext Value to encrypt.
	 * @return string Base64-encoded ciphertext, or original value if openssl unavailable.
	 */
	public static function encrypt( string $plaintext ): string {
		$plaintext = trim( $plaintext );
		if ( '' === $plaintext ) {
			return '';
		}

		if ( ! function_exists( 'openssl_encrypt' ) ) {
			return $plaintext;
		}

		list( $key, $iv ) = self::derive_key_iv();

		$encrypted = openssl_encrypt( $plaintext, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv );

		if ( false === $encrypted ) {
			return $plaintext;
		}

		return base64_encode( $encrypted ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Required for binary-safe storage of AES ciphertext.
	}

	/**
	 * Decrypt a stored ciphertext.
	 *
	 * @param string $ciphertext Base64-encoded encrypted value.
	 * @return string Decrypted plaintext, or empty string on failure.
	 */
	public static function decrypt( string $ciphertext ): string {
		$ciphertext = trim( $ciphertext );
		if ( '' === $ciphertext ) {
			return '';
		}

		if ( ! function_exists( 'openssl_decrypt' ) ) {
			return $ciphertext;
		}

		$decoded = base64_decode( $ciphertext, true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode -- Required to decode binary-safe AES ciphertext from storage.
		if ( false === $decoded ) {
			return $ciphertext;
		}

		list( $key, $iv ) = self::derive_key_iv();

		$decrypted = openssl_decrypt( $decoded, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv );

		if ( false === $decrypted ) {
			return '';
		}

		return $decrypted;
	}

	/**
	 * Derive AES key and IV from WordPress salts.
	 *
	 * @return array [ 32-byte key, 16-byte IV ]
	 */
	private static function derive_key_iv(): array {
		$key = hash( 'sha256', wp_salt( 'auth' ), true );
		$iv  = substr( hash( 'sha256', wp_salt( 'secure_auth' ), true ), 0, 16 );

		return array( $key, $iv );
	}
}
