<?php
/**
 * SocialPilot Encryption Handler
 *
 * @package SocialPilot
 * @subpackage Encryption
 * @since 1.0.0
 */

/**
 * Class to handle encryption and decryption of sensitive data
 */
class SocialPilot_Encrypt {

    /**
     * Encryption key
     *
     * @since 1.0.0
     * @var string
     */
    private static $encryption_key = null;

    /**
     * Get encryption key
     *
     * @since 1.0.0
     * @return string Encryption key
     */
    private static function get_encryption_key() {
        if ( null === self::$encryption_key ) {
            if ( defined( 'SOCIALPILOT_ENCRYPTION_KEY' ) ) {
                self::$encryption_key = SOCIALPILOT_ENCRYPTION_KEY;
            } else {
                // Generate a unique key using WordPress salts
                self::$encryption_key = wp_hash( 
                    'socialpilot_' . AUTH_KEY . AUTH_SALT,
                    'nonce'
                );
            }
        }
        return self::$encryption_key;
    }

    /**
     * Encrypt a value
     *
     * @since 1.0.0
     * @param string $value Value to encrypt.
     * @return string Encrypted value
     */
    public static function encrypt( $value ) {
        if ( empty( $value ) ) {
            return '';
        }

        try {
            $key = self::get_encryption_key();
            $method = 'aes-256-cbc';
            $iv_length = openssl_cipher_iv_length( $method );
            
            // Generate initialization vector
            $iv = openssl_random_pseudo_bytes( $iv_length );
            if ( false === $iv ) {
                throw new Exception( 'Failed to generate IV' );
            }

            // Encrypt the value
            $encrypted = openssl_encrypt(
                $value,
                $method,
                $key,
                OPENSSL_RAW_DATA,
                $iv
            );

            if ( false === $encrypted ) {
                throw new Exception( 'Encryption failed' );
            }

            // Combine IV and encrypted data
            $combined = $iv . $encrypted;
            
            // Base64 encode for storage
            return base64_encode( $combined );

        } catch ( Exception $e ) {
            // Log error but don't expose details
            error_log( 'SocialPilot encryption error: ' . $e->getMessage() );
            return '';
        }
    }

    /**
     * Decrypt a value
     *
     * @since 1.0.0
     * @param string $encrypted_value Encrypted value to decrypt.
     * @return string Decrypted value or empty string on failure
     */
    public static function decrypt( $encrypted_value ) {
        if ( empty( $encrypted_value ) ) {
            return '';
        }

        try {
            $key = self::get_encryption_key();
            $method = 'aes-256-cbc';
            
            // Decode the combined string
            $combined = base64_decode( $encrypted_value );
            if ( false === $combined ) {
                throw new Exception( 'Invalid base64 encoding' );
            }

            // Extract IV and encrypted data
            $iv_length = openssl_cipher_iv_length( $method );
            if ( strlen( $combined ) < $iv_length ) {
                throw new Exception( 'Data too short' );
            }

            $iv = substr( $combined, 0, $iv_length );
            $encrypted = substr( $combined, $iv_length );

            // Decrypt the value
            $decrypted = openssl_decrypt(
                $encrypted,
                $method,
                $key,
                OPENSSL_RAW_DATA,
                $iv
            );

            if ( false === $decrypted ) {
                throw new Exception( 'Decryption failed' );
            }

            return $decrypted;

        } catch ( Exception $e ) {
            // Log error but don't expose details
            error_log( 'SocialPilot decryption error: ' . $e->getMessage() );
            return '';
        }
    }

    /**
     * Generate a new encryption key
     *
     * @since 1.0.0
     * @return string New encryption key
     */
    public static function generate_key() {
        try {
            return bin2hex( openssl_random_pseudo_bytes( 32 ) );
        } catch ( Exception $e ) {
            // Fallback to WordPress functions if openssl fails
            return wp_hash( 
                uniqid( 'socialpilot_', true ) . wp_rand() . microtime(),
                'nonce'
            );
        }
    }

    /**
     * Verify encryption is working
     *
     * @since 1.0.0
     * @return bool True if encryption is working
     */
    public static function verify_encryption() {
        $test_string = 'test_encryption_' . wp_rand();
        $encrypted = self::encrypt( $test_string );
        $decrypted = self::decrypt( $encrypted );
        
        return $test_string === $decrypted;
    }
}