from app.schemas.crypto import EncryptRequest, EncryptResponse, DecryptRequest, DecryptResponse
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
# from app.core.crypto_key import key_iv_from_settings
import base64, json, logging
import asyncio
from dotenv import load_dotenv
load_dotenv()
import os
# key, iv = key_iv_from_settings()
a = os.getenv("AES_KEY")
b = os.getenv("AES_IV")
key = b'2f02c0c5fa6611c92cb672626d732bb3' 
iv = b'3ff2cfd9bb7acec9'                 

# def encrypt_data(plaintext: str) -> str:
#     cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
#     encryptor = cipher.encryptor()

#     # PKCS7 padding (block size 128 bits = 16 bytes)
#     padder = padding.PKCS7(128).padder()
#     padded_data = padder.update(plaintext.encode()) + padder.finalize()

#     ciphertext = encryptor.update(padded_data) + encryptor.finalize()

#     # Base64 encode the ciphertext and return it
#     return base64.b64encode(ciphertext).decode()

# # Decryption function
# def decrypt_data(encrypted_data: bytes) -> dict:
#     # Decrypt the raw encrypted data passed as bytes
#     ciphertext = base64.b64decode(encrypted_data)

#     cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
#     decryptor = cipher.decryptor()

#     decrypted_padded = decryptor.update(ciphertext) + decryptor.finalize()

#     # Remove PKCS7 padding
#     unpadder = padding.PKCS7(128).unpadder()
#     decrypted = unpadder.update(decrypted_padded) + unpadder.finalize()

#     # Decode to string and parse to JSON
#     decrypted_str = decrypted.decode()
#     decrypted_json = json.loads(decrypted_str)

#     return decrypted_json


# ---------------- Encryption ----------------

def encrypt_data(plain_text: str) -> str:
    print(f"Using AES_KEY: {a} and AES_IV: {b}")

    """Encrypt a plain string with AES/CBC/PKCS7 and return Base64 string."""
    # key, iv = key_iv_from_settings()

    # PKCS7 padding (AES block size = 128 bits)
    padder = padding.PKCS7(128).padder()
    padded_data = padder.update(plain_text.encode()) + padder.finalize()

    # AES CBC encryption
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    encrypted = encryptor.update(padded_data) + encryptor.finalize()

    # Base64 encode
    return base64.b64encode(encrypted).decode()

# ---------------- Decryption ----------------
def decrypt_data(encrypted_base64: str) -> dict:
    """Decrypt a Base64 string back to JSON object"""
    encrypted_bytes = base64.b64decode(encrypted_base64)

    cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
    decryptor = cipher.decryptor()
    decrypted_padded = decryptor.update(encrypted_bytes) + decryptor.finalize()

    # Remove PKCS7 padding
    unpadder = padding.PKCS7(128).unpadder()
    decrypted = unpadder.update(decrypted_padded) + unpadder.finalize()

    # Convert back to dict
    return json.loads(decrypted.decode())


# ---------------- Encryption ----------------
# async def encrypt_data(plain_text: str) -> str:
#     """Encrypt a plain string with AES/CBC/PKCS7 and return Base64 string."""
#     return await asyncio.to_thread(_encrypt_data_sync, plain_text)

# def _encrypt_data_sync(plain_text: str) -> str:
#     padder = padding.PKCS7(128).padder()
#     padded_data = padder.update(plain_text.encode()) + padder.finalize()

#     cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
#     encryptor = cipher.encryptor()
#     encrypted = encryptor.update(padded_data) + encryptor.finalize()

#     return base64.b64encode(encrypted).decode()


# # ---------------- Decryption ----------------
# async def decrypt_data(encrypted_base64: str) -> dict:
#     """Decrypt a Base64 string back to JSON object"""
#     return await asyncio.to_thread(_decrypt_data_sync, encrypted_base64)

# def _decrypt_data_sync(encrypted_base64: str) -> dict:
#     encrypted_bytes = base64.b64decode(encrypted_base64)

#     cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
#     decryptor = cipher.decryptor()
#     decrypted_padded = decryptor.update(encrypted_bytes) + decryptor.finalize()

#     unpadder = padding.PKCS7(128).unpadder()
#     decrypted = unpadder.update(decrypted_padded) + unpadder.finalize()

#     return json.loads(decrypted.decode())