import json
import redis 
import os

# Secrets Manager client
redis_client = redis.Redis.from_url(os.getenv("ML_REDIS_URL") or "")

def handler(event, context):
    key = event.get("key", "")
    
    # Handle hash operations
    if event.get("hash_operation", False):
        hash_key = event.get("hash_key", "")
        
        if not hash_key:
            return {
                "statusCode": 400,
                "body": json.dumps({"message": "Hash key is required for hash operations"})
            }
        
        # Get all hash values
        if event.get("get_all_hash", False):
            if not redis_client.exists(hash_key):
                return {
                    "statusCode": 404,
                    "body": json.dumps({"message": f"Hash key '{hash_key}' not found"})
                }
                
            hash_data = redis_client.hgetall(hash_key)
            result = {}
            
            for field, value in hash_data.items():
                field = field.decode('utf-8')
                value = value.decode('utf-8')
                try:
                    # Attempt to deserialize the value if it is a JSON string
                    value = json.loads(value)
                except json.JSONDecodeError:
                    pass
                result[field] = value
                
            return {
                "statusCode": 200,
                "body": json.dumps({"message": "Hash retrieved successfully", "value": result})
            }
        
        hash_field = event.get("hash_field", "")
        if not hash_field:
            return {
                "statusCode": 400,
                "body": json.dumps({"message": "Hash field is required for specific field operations"})
            }
        
        # Set hash field
        if event.get("value", "") != "":
            value = event.get("value", "")
            if isinstance(value, dict) or isinstance(value, list):
                value = json.dumps(value)
                
            redis_client.hset(hash_key, hash_field, value)
            return {
                "statusCode": 200,
                "body": json.dumps({"message": "Hash field set successfully"})
            }
        # Get hash field
        else:
            value = redis_client.hget(hash_key, hash_field)
            if value is not None:
                value = value.decode('utf-8')
                try:
                    # Attempt to deserialize the value if it is a JSON string
                    value = json.loads(value)
                except json.JSONDecodeError:
                    pass
            return {
                "statusCode": 200,
                "body": json.dumps({"message": "Hash field retrieved", "value": value})
            }
    
    # Handle key prefix scan operation
    elif event.get("scan_prefix", ""):
        prefix = event.get("scan_prefix")
        pattern = f"{prefix}*"
        
        # Use scan_iter to efficiently fetch keys by pattern
        matching_keys = []
        for key in redis_client.scan_iter(match=pattern):
            matching_keys.append(key.decode('utf-8'))
            
        return {
            "statusCode": 200,
            "body": json.dumps({
                "message": f"Found {len(matching_keys)} keys with prefix '{prefix}'",
                "keys": matching_keys
            })
        }
    
    # Handle regular key-value operations
    elif key:
        value = event.get("value", "")
        if value != "":
            if isinstance(value, dict) or isinstance(value, list):
                value = json.dumps(value)
            if key.startswith("lyrics-remi"):
                redis_client.set(key, value)
            else:
                redis_client.set(key, value, ex=60 * 60 * 24 * 30)
        
            return {
                "statusCode": 200,
                "body": json.dumps({"message": "Key set successfully"})
            }
        else:
            value = redis_client.get(key)
            if value is not None:
                value = value.decode('utf-8')
                try:
                    # Attempt to deserialize the value if it is a JSON string
                    value = json.loads(value)
                except json.JSONDecodeError:
                    pass
            return {
                "statusCode": 200,
                "body": json.dumps({"message": "Key retrieved", "value": value})
            }
    else:
        return {
            "statusCode": 400,
            "body": json.dumps({"message": "Either key, scan_prefix, or hash operation parameters are required"})
        }