# Utilidades para EmpoorioChain SDK

from typing import List, Dict, Any
from .sdk import Utils as SDKUtils

class Utils(SDKUtils):
    """Utilidades adicionales para el desarrollo con EmpoorioChain"""

    @staticmethod
    def format_transaction_data(tx_data: Dict[str, Any]) -> str:
        """Formatear datos de transacción para logging"""
        return f"Tx: {tx_data.get('hash', 'N/A')} from {tx_data.get('from', 'N/A')} to {tx_data.get('to', 'N/A')} value {tx_data.get('value', '0')}"

    @staticmethod
    def calculate_transaction_fee(gas_used: str, gas_price: str) -> str:
        """Calcular tarifa de transacción"""
        return str(int(gas_used) * int(gas_price))

    @staticmethod
    def validate_transaction(tx: Dict[str, Any]) -> List[str]:
        """Validar una transacción y devolver lista de errores"""
        errors = []

        if not Utils.is_valid_address(tx.get('from', '')):
            errors.append("Dirección 'from' inválida")

        if not Utils.is_valid_address(tx.get('to', '')):
            errors.append("Dirección 'to' inválida")

        try:
            value = int(tx.get('value', 0))
            if value < 0:
                errors.append("Valor negativo no permitido")
        except ValueError:
            errors.append("Valor debe ser un número entero")

        return errors

    @staticmethod
    def encode_function_call(function_name: str, params: List[Any]) -> str:
        """Codificar una llamada a función de contrato (simplificado)"""
        # Implementación simplificada - en producción usar web3.py o similar
        return f"0x{function_name}({','.join(str(p) for p in params)})"

    @staticmethod
    def decode_function_result(encoded_data: str) -> Dict[str, Any]:
        """Decodificar resultado de función de contrato (simplificado)"""
        # Implementación simplificada
        return {"decoded": encoded_data}

    @staticmethod
    def generate_mnemonic() -> str:
        """Generar frase mnemónica BIP39 (simplificado)"""
        # En producción usar bibliotecas como mnemonic
        words = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract"]
        return " ".join(words[:12])

    @staticmethod
    def derive_address_from_mnemonic(mnemonic: str, index: int = 0) -> str:
        """Derivar dirección desde mnemónico (simplificado)"""
        # En producción usar web3.py Account.from_mnemonic
        return f"0x{'0' * 40}"  # Placeholder

    @staticmethod
    def estimate_network_fee(priority: str = "standard") -> Dict[str, str]:
        """Estimar tarifas de red basadas en prioridad"""
        base_fee = "20000000000"  # 20 gwei

        multipliers = {
            "slow": 0.8,
            "standard": 1.0,
            "fast": 1.5,
            "instant": 2.0
        }

        multiplier = multipliers.get(priority, 1.0)
        estimated_fee = str(int(int(base_fee) * multiplier))

        return {
            "base_fee": base_fee,
            "priority_fee": estimated_fee,
            "estimated_total": estimated_fee
        }

    @staticmethod
    def convert_units(amount: str, from_unit: str, to_unit: str) -> str:
        """Convertir entre unidades (wei, gwei, ether, etc.)"""
        units = {
            "wei": 1,
            "kwei": 10**3,
            "mwei": 10**6,
            "gwei": 10**9,
            "szabo": 10**12,
            "finney": 10**15,
            "ether": 10**18
        }

        if from_unit not in units or to_unit not in units:
            raise ValueError("Unidad no soportada")

        amount_wei = int(amount) * units[from_unit]
        result = amount_wei // units[to_unit]

        return str(result)

    @staticmethod
    def validate_contract_abi(abi: List[Dict[str, Any]]) -> List[str]:
        """Validar ABI de contrato"""
        errors = []

        for item in abi:
            if not isinstance(item, dict):
                errors.append("Cada elemento del ABI debe ser un diccionario")
                continue

            if "type" not in item:
                errors.append("Cada elemento del ABI debe tener un campo 'type'")

            item_type = item.get("type")
            if item_type in ["function", "constructor", "fallback"]:
                if "name" not in item and item_type != "fallback":
                    errors.append(f"Función {item.get('name', 'unknown')} debe tener nombre")
                if "inputs" not in item:
                    errors.append(f"Función {item.get('name', 'unknown')} debe tener inputs")
                if item_type == "function" and "outputs" not in item:
                    errors.append(f"Función {item.get('name', 'unknown')} debe tener outputs")

        return errors

    @staticmethod
    def generate_contract_interface(abi: List[Dict[str, Any]]) -> str:
        """Generar interfaz TypeScript/Python desde ABI"""
        # Implementación simplificada
        functions = [item for item in abi if item.get("type") == "function"]

        interface_lines = []
        for func in functions:
            name = func.get("name", "unknown")
            inputs = func.get("inputs", [])
            outputs = func.get("outputs", [])

            input_types = [inp.get("type", "unknown") for inp in inputs]
            output_types = [out.get("type", "unknown") for out in outputs]

            interface_lines.append(f"{name}({', '.join(input_types)}) -> ({', '.join(output_types)})")

        return "\n".join(interface_lines)