<?php
declare(strict_types=1);
// ==================================================
// Nuclear Fancy Pants Edition™ — NUCLEAR+++
// File: /includes/class-key-vault.php
// Description: Encrypts and decrypts API keys stored in wp_options using AES-256-CBC - NUCLEAR+++
// Last Edited: 2026-03-29
// ==================================================

namespace AutoMarketerAI;

defined('ABSPATH') || exit;

final class KeyVault
{
    private const CIPHER  = 'AES-256-CBC';
    private const PREFIX  = 'amai_enc:';

    // Encrypt a plaintext API key for storage in wp_options.
    // Returns the encrypted string on success, empty string on failure.
    public static function encrypt(string $plaintext): string
    {
        if ($plaintext === '' || !self::keyDefined()) {
            return $plaintext;
        }

        $key = self::key();
        $iv  = random_bytes(openssl_cipher_iv_length(self::CIPHER));

        $encrypted = openssl_encrypt($plaintext, self::CIPHER, $key, OPENSSL_RAW_DATA, $iv);
        if ($encrypted === false) {
            return $plaintext;
        }

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

    // Decrypt a stored value from wp_options.
    // Returns the plaintext key. Handles legacy plaintext values transparently.
    public static function decrypt(string $stored): string
    {
        if ($stored === '' || !self::keyDefined()) {
            return $stored;
        }

        // Legacy plaintext — not yet encrypted
        if (!str_starts_with($stored, self::PREFIX)) {
            return $stored;
        }

        $key     = self::key();
        $decoded = base64_decode(substr($stored, strlen(self::PREFIX)), true);
        if ($decoded === false) {
            return '';
        }

        $iv_len = openssl_cipher_iv_length(self::CIPHER);
        if (strlen($decoded) <= $iv_len) {
            return '';
        }

        $iv        = substr($decoded, 0, $iv_len);
        $ciphertext = substr($decoded, $iv_len);

        $plaintext = openssl_decrypt($ciphertext, self::CIPHER, $key, OPENSSL_RAW_DATA, $iv);

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

    // --------------------------------------------------
    // Internals
    // --------------------------------------------------

    private static function keyDefined(): bool
    {
        return defined('AMAI_ENCRYPTION_KEY') && AMAI_ENCRYPTION_KEY !== '';
    }

    private static function key(): string
    {
        // AMAI_ENCRYPTION_KEY is a 64-char hex string — convert to 32 raw bytes
        return (string) hex2bin(AMAI_ENCRYPTION_KEY);
    }
}