#!/usr/bin/env python3
"""
Utilidades para BambuLuc
========================
"""

import hashlib
import os
from typing import Optional

def calculate_md5(file_path: str) -> str:
    """
    Calcular MD5 de un archivo
    
    Args:
        file_path: Ruta del archivo
        
    Returns:
        str: Hash MD5 en mayúsculas
    """
    with open(file_path, 'rb') as f:
        return hashlib.md5(f.read()).hexdigest().upper()

def format_time(seconds: int) -> str:
    """
    Formatear tiempo en formato legible
    
    Args:
        seconds: Tiempo en segundos
        
    Returns:
        str: Tiempo formateado (ej: "1h 30m 45s")
    """
    if seconds < 60:
        return f"{seconds}s"
    elif seconds < 3600:
        return f"{seconds//60}m {seconds%60}s"
    else:
        hours = seconds // 3600
        minutes = (seconds % 3600) // 60
        return f"{hours}h {minutes}m"

def format_size(bytes_size: int) -> str:
    """
    Formatear tamaño en formato legible
    
    Args:
        bytes_size: Tamaño en bytes
        
    Returns:
        str: Tamaño formateado (ej: "6.7 MB")
    """
    for unit in ['B', 'KB', 'MB', 'GB']:
        if bytes_size < 1024.0:
            return f"{bytes_size:.1f} {unit}"
        bytes_size /= 1024.0
    return f"{bytes_size:.1f} TB"

def validate_ip(ip: str) -> bool:
    """
    Validar dirección IP
    
    Args:
        ip: Dirección IP a validar
        
    Returns:
        bool: True si es válida
    """
    try:
        parts = ip.split('.')
        if len(parts) != 4:
            return False
        
        for part in parts:
            if not 0 <= int(part) <= 255:
                return False
        
        return True
    except:
        return False

def validate_file_extension(file_path: str, valid_extensions: list = None) -> bool:
    """
    Validar extensión de archivo
    
    Args:
        file_path: Ruta del archivo
        valid_extensions: Lista de extensiones válidas
        
    Returns:
        bool: True si es válida
    """
    if valid_extensions is None:
        valid_extensions = ['.gcode', '.3mf', '.gcode.3mf']
    
    file_ext = os.path.splitext(file_path)[1].lower()
    
    # Verificar extensión doble como .gcode.3mf
    if file_path.lower().endswith('.gcode.3mf'):
        return '.gcode.3mf' in valid_extensions
    
    return file_ext in valid_extensions

def diagnose_sd_card_error(error_message: str = None) -> dict:
    """
    Diagnosticar problemas comunes de tarjeta SD
    
    Args:
        error_message: Mensaje de error opcional
        
    Returns:
        dict: Diagnóstico y soluciones recomendadas
    """
    diagnosis = {
        'error_type': 'unknown',
        'severity': 'medium',
        'solutions': [],
        'anti_sd_recommended': False
    }
    
    if error_message:
        error_lower = error_message.lower()
        
        # Detectar tipos de error comunes
        if any(keyword in error_lower for keyword in ['sd', 'card', 'tarjeta']):
            diagnosis['error_type'] = 'sd_card_error'
            diagnosis['severity'] = 'high'
            diagnosis['anti_sd_recommended'] = True
            diagnosis['solutions'] = [
                "Usar configuración anti-SD en BambuLuc",
                "Enviar archivos directamente por red (sin SD)",
                "Verificar que la tarjeta SD esté insertada correctamente",
                "Formatear la tarjeta SD (FAT32)",
                "Reemplazar la tarjeta SD si está dañada"
            ]
        
        elif any(keyword in error_lower for keyword in ['network', 'connection', 'timeout']):
            diagnosis['error_type'] = 'network_error'
            diagnosis['severity'] = 'medium'
            diagnosis['solutions'] = [
                "Verificar conexión WiFi de la impresora",
                "Comprobar que la IP sea correcta",
                "Reiniciar la impresora",
                "Verificar que el access code sea válido"
            ]
        
        elif any(keyword in error_lower for keyword in ['file', 'archivo', 'gcode']):
            diagnosis['error_type'] = 'file_error'
            diagnosis['severity'] = 'medium'
            diagnosis['solutions'] = [
                "Verificar que el archivo existe",
                "Comprobar que el archivo no esté corrupto",
                "Verificar extensión del archivo (.gcode, .3mf)",
                "Revisar tamaño del archivo"
            ]
    
    return diagnosis

def get_anti_sd_config() -> dict:
    """
    Obtener configuración anti-SD recomendada
    
    Returns:
        dict: Configuración para evitar problemas de SD
    """
    return {
        'use_direct_upload': True,
        'skip_sd_check': True,
        'force_network_print': True,
        'disable_sd_fallback': True,
        'recommendations': [
            "Usar send_file() con auto_start=False",
            "Verificar conexión antes de enviar archivos",
            "Usar archivos pequeños para pruebas",
            "Monitorear estado durante la transferencia"
        ]
    }

def create_recovery_gcode(output_file: str = "recovery.gcode") -> bool:
    """
    Crear archivo G-code de recuperación para pruebas
    
    Args:
        output_file: Nombre del archivo de salida
        
    Returns:
        bool: True si se creó exitosamente
    """
    try:
        recovery_gcode = """; Archivo de recuperación BambuLuc
; Diseñado para resolver problemas de tarjeta SD
; Comandos seguros para restablecer la impresora

; Información del archivo
; Generado por: BambuLuc Recovery Tool
; Propósito: Diagnóstico y recuperación

; Comandos de inicialización seguros
G21 ; Usar unidades métricas
G90 ; Posicionamiento absoluto
M83 ; Extrusor en modo relativo

; Home seguro
G28 ; Home todos los ejes

; Mover a posición segura
G1 Z10 F300 ; Levantar Z 10mm lentamente
G1 X50 Y50 F1500 ; Mover al centro aproximado

; Verificar temperaturas (sin calentar)
M105 ; Reportar temperaturas

; Comandos de finalización
G1 Z50 F300 ; Levantar más el eje Z
G28 X Y ; Home X Y solamente

; Apagar calentadores
M104 S0 ; Apagar extrusor
M140 S0 ; Apagar cama caliente

; Apagar motores
M84 ; Desactivar motores

; Mensaje de finalización
M117 Recovery Complete ; Mostrar mensaje en pantalla

; Fin del archivo
"""
        
        with open(output_file, 'w', encoding='utf-8') as f:
            f.write(recovery_gcode)
        
        return True
        
    except Exception as e:
        print(f"Error creando archivo de recuperación: {e}")
        return False

def suggest_troubleshooting_steps(error_context: str = None) -> list:
    """
    Sugerir pasos de solución de problemas
    
    Args:
        error_context: Contexto del error
        
    Returns:
        list: Lista de pasos recomendados
    """
    base_steps = [
        "1. Verificar conexión de red con la impresora",
        "2. Comprobar que la impresora esté encendida",
        "3. Validar IP, access code y device ID",
        "4. Reiniciar la impresora si es necesario"
    ]
    
    if error_context and 'sd' in error_context.lower():
        sd_steps = [
            "5. Usar configuración anti-SD de BambuLuc",
            "6. Enviar archivos directamente por red",
            "7. Evitar usar la tarjeta SD temporalmente",
            "8. Crear archivo de recuperación pequeño para pruebas"
        ]
        base_steps.extend(sd_steps)
    
    return base_steps
