import json
from typing import Dict, Any, Callable, Optional

class JSONTransformer:
    def __init__(self, mappings: Dict[str, str] = None, transformers: Dict[str, Callable] = None):
        self.mappings = mappings or {}
        self.transformers = transformers or {}
    
    def transform(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """Transform data according to mappings and transformers."""
        result = {}
        
        for key, value in data.items():
            # Apply field mapping
            new_key = self.mappings.get(key, key)
            
            # Apply value transformer if exists
            if new_key in self.transformers:
                value = self.transformers[new_key](value)
            elif key in self.transformers:
                value = self.transformers[key](value)
            
            # Handle nested objects
            if isinstance(value, dict):
                value = self.transform(value)
            elif isinstance(value, list):
                value = [self.transform(item) if isinstance(item, dict) else item for item in value]
            
            result[new_key] = value
        
        return result
    
    def transform_from_json(self, json_str: str) -> Dict[str, Any]:
        """Transform from JSON string."""
        data = json.loads(json_str)
        return self.transform(data)
    
    def transform_to_json(self, data: Dict[str, Any]) -> str:
        """Transform and return as JSON string."""
        transformed = self.transform(data)
        return json.dumps(transformed, indent=2)