<?php

namespace App\Helpers\Utility;

class SymEncrypt {

    private string $cipher = "aes-256-cbc";
    private string $key;
    private int $ivLength;

    public function __construct(string $secretKey) {
        // Hash the key to ensure it's the correct length
        $this->key = hash('sha256', $secretKey, true);
        $this->ivLength = openssl_cipher_iv_length($this->cipher);
    }

    /**
     * Encrypts a string using symmetric encryption
     * 
     * @param string $plaintext The string to encrypt
     * @return string|false Returns base64 encoded encrypted string or false on failure
     */

    public function encrypt(string $plaintext) {
        try {
            // Create a random initialization vector
            $iv = openssl_random_pseudo_bytes($this->ivLength);
            
            // Encrypt the data
            $encrypted = openssl_encrypt(
                $plaintext,
                $this->cipher,
                $this->key,
                OPENSSL_RAW_DATA,
                $iv
            );

            if ($encrypted === false) {
                return false;
            }

            // Combine IV and encrypted data and encode
            return base64_encode($iv . $encrypted);
        } catch (\Throwable $e) {
            return false;
        }
    }

    /**
     * Decrypts an encrypted string
     * 
     * @param string $encryptedString The base64 encoded encrypted string
     * @return string|false Returns decrypted string or false on failure
     */

    public function decrypt(string $encryptedString) {
        try {
            // Decode the combined string
            $combined = base64_decode($encryptedString);
            
            // Extract IV and ciphertext
            $iv = substr($combined, 0, $this->ivLength);
            $ciphertext = substr($combined, $this->ivLength);

            // Decrypt the data
            $decrypted = openssl_decrypt(
                $ciphertext,
                $this->cipher,
                $this->key,
                OPENSSL_RAW_DATA,
                $iv
            );

            return $decrypted !== false ? $decrypted : false;
        } catch (\Throwable $e) {
            return false;
        }
    }
}