<?php
/**
 * Encryption/Decryption for sensitive data like API keys.
 *
 * ENTERPRISE SECURITY NOTICE:
 * This class manages encryption of API credentials using AES-256-CBC.
 * The encryption key is stored in wp_options as 'wpfmj_encryption_key'.
 *
 * CRITICAL FOR PRODUCTION:
 * - The encryption key MUST be backed up with your database
 * - If the key is lost/changed, ALL saved automations will fail
 * - During site migrations, ensure wp_options table includes this key
 * - For multi-environment setups, consider using wp-config.php constants
 * - Monitor error logs for decryption failures
 *
 * @package    WPFMJ
 * @subpackage WPFMJ/includes
 */

class WPFMJ_Encryption {

    /**
     * Get encryption method (configurable via filter).
     * 
     * @return string Encryption method
     */
    private static function get_method() {
        $method = apply_filters('wpfmj_encryption_method', 'AES-256-CBC');
        
        // Validate that the method is available
        $available_methods = openssl_get_cipher_methods();
        if (!in_array($method, $available_methods, true)) {
            error_log("WPFMJ: Invalid encryption method '{$method}', falling back to AES-256-CBC");
            $method = 'AES-256-CBC';
        }
        
        return $method;
    }

    /**
     * Get the encryption key.
     */
    private static function get_key() {
        $key = get_option('wpfmj_encryption_key');
        
        if (!$key) {
            // Generate a new key if it doesn't exist
            $key = base64_encode(random_bytes(32));
            add_option('wpfmj_encryption_key', $key, '', false);
        }
        
        return base64_decode($key);
    }

    /**
     * Encrypt data.
     */
    public static function encrypt($data) {
        if (empty($data)) {
            return '';
        }

        $key = self::get_key();
        $method = self::get_method();
        $iv_length = openssl_cipher_iv_length($method);
        $iv = openssl_random_pseudo_bytes($iv_length);
        
        $encrypted = openssl_encrypt($data, $method, $key, 0, $iv);
        
        // Combine IV and encrypted data
        return base64_encode($iv . $encrypted);
    }

    /**
     * Decrypt data.
     */
    public static function decrypt($data) {
        if (empty($data)) {
            return '';
        }

        try {
            $key = self::get_key();
            $method = self::get_method();
            $decoded_data = base64_decode($data);
            
            if ($decoded_data === false) {
                error_log('WPFMJ Decryption Error: Invalid base64 data');
                return false;
            }
            
            $iv_length = openssl_cipher_iv_length($method);
            
            if (strlen($decoded_data) <= $iv_length) {
                error_log('WPFMJ Decryption Error: Data too short');
                return false;
            }
            
            $iv = substr($decoded_data, 0, $iv_length);
            $encrypted = substr($decoded_data, $iv_length);
            
            $decrypted = openssl_decrypt($encrypted, $method, $key, 0, $iv);
            
            if ($decrypted === false) {
                error_log('WPFMJ Decryption Error: Decryption failed - possibly corrupted data or wrong key');
                return false;
            }
            
            return $decrypted;
        } catch (Exception $e) {
            error_log('WPFMJ Decryption Error: ' . $e->getMessage());
            return false;
        }
    }
}
