import logging
import os
from cryptography.fernet import Fernet


class Encryptor:
    """
    Handles file encryption and decryption using Fernet symmetric encryption.
    """

    def __init__(self, key_path: str | None):
        """
        Initializes the Encryptor. If a key file exists, it loads the key;
        otherwise, it generates a new one.

        Args:
            key_path (str or None): Path to store/retrieve the encryption key.
        """
        if key_path is None:
            key_path = "encryption.key"

        self.key_path = key_path
        if os.path.exists(self.key_path):
            with open(self.key_path, "rb") as key_file:
                self.encryption_key = key_file.read()
        else:
            self.encryption_key = Fernet.generate_key()
            with open(self.key_path, "wb") as key_file:
                key_file.write(self.encryption_key)

        self.cipher = Fernet(self.encryption_key)

    def encrypt_file(self, file_path):
        """Encrypts a file and overwrites it with the encrypted content."""
        try:
            with open(file_path, 'rb') as f:
                data = f.read()
            encrypted_data = self.cipher.encrypt(data)
            with open(file_path, 'wb') as f:
                f.write(encrypted_data)
        except Exception as e:
            logging.error(f"Error encrypting file {file_path}: {e}")

    def decrypt_file(self, file_path):
        """Decrypts a file and overwrites it with the decrypted content."""
        try:
            with open(file_path, 'rb') as f:
                data = f.read()
            decrypted_data = self.cipher.decrypt(data)
            with open(file_path, 'wb') as f:
                f.write(decrypted_data)
        except Exception as e:
            logging.error(f"Error decrypting file {file_path}: {e}")

    def encrypt_text(self, text):
        """Encrypts a given text string."""
        return self.cipher.encrypt(text.encode()).decode()

    def decrypt_text(self, encrypted_text):
        """Decrypts an encrypted text string."""
        return self.cipher.decrypt(encrypted_text.encode()).decode()
