<?php

namespace KeyLair;

/**
 * AES-256-GCM encryption for small secrets at rest (currently: 2FA secrets).
 * Uses the app's configured encryption_key, never a per-record key, since
 * these are single-installation secrets rather than multi-tenant data.
 */
class Encryption
{
    private static function key(): string
    {
        $hex = Config::get('security', 'encryption_key') ?? '';
        $key = @hex2bin($hex);

        if ($key === false || strlen($key) < 32) {
            // Fall back to a hash so the app still runs during initial setup,
            // but this should never happen once config.php is filled in properly.
            $key = hash('sha256', $hex, true);
        }

        return substr($key, 0, 32);
    }

    public static function encrypt(string $plaintext): string
    {
        $iv = random_bytes(12);
        $tag = '';
        $ciphertext = openssl_encrypt($plaintext, 'aes-256-gcm', self::key(), OPENSSL_RAW_DATA, $iv, $tag);

        return base64_encode($iv . $tag . $ciphertext);
    }

    public static function decrypt(string $encoded): ?string
    {
        $raw = base64_decode($encoded, true);
        if ($raw === false || strlen($raw) < 28) {
            return null;
        }

        $iv = substr($raw, 0, 12);
        $tag = substr($raw, 12, 16);
        $ciphertext = substr($raw, 28);

        $plaintext = openssl_decrypt($ciphertext, 'aes-256-gcm', self::key(), OPENSSL_RAW_DATA, $iv, $tag);

        return $plaintext === false ? null : $plaintext;
    }
}
