<?php
/**
 * Small helper for encrypting/decrypting stored face descriptor data.
 * Face descriptors (128 floats from face-api.js) are not passwords, but they
 * are biometric-derived data, so we encrypt them at rest rather than storing
 * plain JSON in usermeta.
 */

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

class Capsq_Crypto {

	/**
	 * Returns a 32-byte binary key derived from the option stored at activation.
	 */
	private static function get_key() {
		$hex = get_option( 'capsq_encryption_key' );
		if ( ! $hex ) {
			$hex = bin2hex( random_bytes( 32 ) );
			update_option( 'capsq_encryption_key', $hex, false );
		}
		return hex2bin( $hex );
	}

	public static function encrypt( $plaintext ) {
		$key   = self::get_key();
		$iv    = random_bytes( 12 ); // GCM nonce.
		$tag   = '';
		$cipher = openssl_encrypt( $plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag );
		if ( false === $cipher ) {
			return false;
		}
		// Pack iv + tag + ciphertext together, base64 for storage.
		return base64_encode( $iv . $tag . $cipher );
	}

	public static function decrypt( $encoded ) {
		$key  = self::get_key();
		$raw  = base64_decode( $encoded );
		if ( false === $raw || strlen( $raw ) < 28 ) {
			return false;
		}
		$iv     = substr( $raw, 0, 12 );
		$tag    = substr( $raw, 12, 16 );
		$cipher = substr( $raw, 28 );
		$plain  = openssl_decrypt( $cipher, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag );
		return $plain;
	}
}
