"""
Formatters for telemetry and process data responses
"""

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


def _safe_float(value: Any, default: float = 0.0) -> float:
    """Safely convert a value to float, handling None."""
    if value is None:
        return default
    try:
        return float(value)
    except (TypeError, ValueError):
        return default


def _bytes_to_gb(bytes_val: Any) -> float:
    """Convert bytes to GB, handling None."""
    if bytes_val is None:
        return 0.0
    try:
        return float(bytes_val) / (1024 ** 3)
    except (TypeError, ValueError):
        return 0.0


def format_telemetry_for_ai(telemetry_data: Optional[Dict[str, Any]], as_json: bool = True) -> str:
    """
    Format telemetry data for AI assistant consumption.
    
    Args:
        telemetry_data: Raw telemetry data from backend
        as_json: If True, return structured JSON. If False, return human-readable text.
    
    Returns:
        Formatted string (JSON or text)
    """
    
    if not telemetry_data:
        if as_json:
            return json.dumps({
                "status": "error",
                "message": "Device telemetry not available - device may be offline or not sending data"
            })
        return "Device telemetry not available - device may be offline or not sending data."
    
    # Handle both old format (GB) and new format (bytes)
    cpu_percent = _safe_float(telemetry_data.get("cpu_percent"))
    
    # Try bytes format first, fall back to GB format
    memory_used_bytes = telemetry_data.get("memory_used_bytes")
    memory_total_bytes = telemetry_data.get("memory_total_bytes")
    
    if memory_used_bytes is not None or memory_total_bytes is not None:
        memory_used_gb = _bytes_to_gb(memory_used_bytes)
        memory_total_gb = _bytes_to_gb(memory_total_bytes)
    else:
        memory_used_gb = _safe_float(telemetry_data.get("memory_used_gb"))
        memory_total_gb = _safe_float(telemetry_data.get("memory_total_gb"))
    
    # Disk usage
    disk_used_bytes = telemetry_data.get("disk_used_bytes")
    disk_total_bytes = telemetry_data.get("disk_total_bytes")
    
    if disk_total_bytes and disk_used_bytes:
        disk_used_percent = (float(disk_used_bytes) / float(disk_total_bytes) * 100) if disk_total_bytes else 0
        disk_used_gb = _bytes_to_gb(disk_used_bytes)
        disk_total_gb = _bytes_to_gb(disk_total_bytes)
    else:
        disk_used_percent = _safe_float(telemetry_data.get("disk_used_percent"))
        disk_used_gb = 0.0
        disk_total_gb = 0.0
    
    process_count = int(_safe_float(telemetry_data.get("process_count")))
    
    # Calculate memory percentage
    memory_percent = (memory_used_gb / memory_total_gb * 100) if memory_total_gb > 0 else 0
    
    # Determine status levels
    cpu_status = "critical" if cpu_percent > 90 else "high" if cpu_percent > 70 else "normal" if cpu_percent > 0 else "unknown"
    memory_status = "critical" if memory_percent > 90 else "high" if memory_percent > 80 else "normal" if memory_percent > 0 else "unknown"
    disk_status = "critical" if disk_used_percent > 90 else "high" if disk_used_percent > 80 else "normal" if disk_used_percent > 0 else "unknown"
    
    # Build alerts list
    alerts = []
    if cpu_percent > 80:
        alerts.append({"type": "cpu", "severity": "high", "message": f"High CPU usage: {cpu_percent:.1f}%"})
    if memory_percent > 80:
        alerts.append({"type": "memory", "severity": "high", "message": f"High memory usage: {memory_percent:.1f}%"})
    if disk_used_percent > 80:
        alerts.append({"type": "disk", "severity": "high", "message": f"High disk usage: {disk_used_percent:.1f}%"})
    if process_count > 300:
        alerts.append({"type": "processes", "severity": "warning", "message": f"High process count: {process_count}"})
    
    # Build recommendations
    recommendations = []
    if cpu_percent > 70 or memory_percent > 70:
        recommendations.append("Use 'get_device_processes' to identify resource-heavy applications")
        recommendations.append("Consider restarting high-usage processes")
    if disk_used_percent > 80:
        recommendations.append("Use 'clear_cache' to free up disk space")
    if not recommendations:
        recommendations.append("System is running normally")
    
    if as_json:
        # Return structured JSON
        result = {
            "status": "success",
            "device_id": telemetry_data.get("device_id"),
            "timestamp": telemetry_data.get("timestamp"),
            "source": telemetry_data.get("source", "unknown"),
            "metrics": {
                "cpu": {
                    "percent": round(cpu_percent, 1),
                    "status": cpu_status
                },
                "memory": {
                    "used_gb": round(memory_used_gb, 2),
                    "total_gb": round(memory_total_gb, 2),
                    "percent": round(memory_percent, 1),
                    "status": memory_status
                },
                "disk": {
                    "used_gb": round(disk_used_gb, 2),
                    "total_gb": round(disk_total_gb, 2),
                    "percent": round(disk_used_percent, 1),
                    "status": disk_status
                },
                "processes": {
                    "count": process_count
                }
            },
            "alerts": alerts,
            "recommendations": recommendations
        }
        return json.dumps(result, indent=2)
    
    # Return human-readable text format
    cpu_display = f"{cpu_percent:.1f}%" if cpu_percent > 0 else "N/A"
    memory_display = f"{memory_used_gb:.1f}GB / {memory_total_gb:.1f}GB ({memory_percent:.1f}%)" if memory_total_gb > 0 else "N/A"
    disk_display = f"{disk_used_percent:.1f}%" if disk_used_percent > 0 else "N/A"
    
    output = f"""Device System Metrics
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

CPU Usage: {cpu_display} ({cpu_status.title()})
Memory Usage: {memory_display} ({memory_status.title()})
Disk Usage: {disk_display} ({disk_status.title()})
Running Processes: {process_count}

Performance Analysis:"""
    
    if alerts:
        for alert in alerts:
            output += f"\n- {alert['message']}"
    else:
        output += "\n- System performance is healthy"
    
    output += "\n\nRecommended Actions:"
    for i, rec in enumerate(recommendations, 1):
        output += f"\n{i}. {rec}"
    
    return output


def format_processes_for_ai(processes_data: Optional[List[Dict[str, Any]]], as_json: bool = True) -> str:
    """
    Format process list for AI assistant consumption.
    
    Args:
        processes_data: List of process data from backend
        as_json: If True, return structured JSON. If False, return human-readable text.
    
    Returns:
        Formatted string (JSON or text)
    """
    
    if not processes_data:
        if as_json:
            return json.dumps({
                "status": "error",
                "message": "No processes found or device offline",
                "processes": []
            })
        return "Running Processes: No processes found or device offline"
    
    # Sort processes by CPU usage (highest first), handling None values
    sorted_processes = sorted(
        processes_data, 
        key=lambda x: _safe_float(x.get("cpu_percent")), 
        reverse=True
    )
    
    # Get top 10 processes
    top_processes = []
    for process in sorted_processes[:10]:
        name = process.get("name", "Unknown")
        pid = process.get("pid", 0)
        cpu_percent = _safe_float(process.get("cpu_percent"))
        memory_mb = _safe_float(process.get("memory_mb"))
        
        # Try memory_bytes if memory_mb is not available
        if memory_mb == 0:
            memory_working_set = process.get("memory_working_set_bytes") or process.get("memory_bytes")
            if memory_working_set:
                memory_mb = _safe_float(memory_working_set) / (1024 * 1024)
        
        # Determine status
        if cpu_percent > 50:
            status = "high_cpu"
        elif cpu_percent > 20:
            status = "moderate_cpu"
        elif memory_mb > 1000:
            status = "high_memory"
        else:
            status = "normal"
        
        top_processes.append({
            "name": name,
            "pid": pid,
            "cpu_percent": round(cpu_percent, 1),
            "memory_mb": round(memory_mb, 1),
            "status": status
        })
    
    # Analyze processes
    high_cpu_processes = [p for p in processes_data if _safe_float(p.get("cpu_percent")) > 30]
    high_memory_processes = [p for p in processes_data if _safe_float(p.get("memory_mb", 0)) > 1000 or _safe_float(p.get("memory_working_set_bytes", 0)) > 1024*1024*1024]
    
    if as_json:
        result = {
            "status": "success",
            "total_count": len(processes_data),
            "top_processes": top_processes,
            "analysis": {
                "high_cpu_count": len(high_cpu_processes),
                "high_memory_count": len(high_memory_processes),
                "high_cpu_processes": [
                    {"name": p.get("name"), "cpu_percent": round(_safe_float(p.get("cpu_percent")), 1)}
                    for p in high_cpu_processes[:5]
                ],
                "high_memory_processes": [
                    {"name": p.get("name"), "memory_mb": round(_safe_float(p.get("memory_mb", 0)) or _safe_float(p.get("memory_working_set_bytes", 0))/(1024*1024), 1)}
                    for p in high_memory_processes[:5]
                ]
            },
            "available_actions": [
                "restart_process - Restart a specific application",
                "kill_process - Force-close frozen applications"
            ]
        }
        return json.dumps(result, indent=2)
    
    # Human-readable text format
    output = f"""Running Processes ({len(processes_data)} total)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Top Resource Consumers:
"""
    
    for i, proc in enumerate(top_processes, 1):
        output += f"\n{i:2d}. {proc['name']} (PID: {proc['pid']})"
        output += f"\n    CPU: {proc['cpu_percent']:.1f}% | Memory: {proc['memory_mb']:.0f}MB | {proc['status'].replace('_', ' ').title()}"
    
    output += f"\n\nProcess Analysis:"
    
    if high_cpu_processes:
        output += f"\n- {len(high_cpu_processes)} processes using high CPU (>30%)"
    
    if high_memory_processes:
        output += f"\n- {len(high_memory_processes)} processes using high memory (>1GB)"
    
    if not high_cpu_processes and not high_memory_processes:
        output += "\n- All processes are running within normal resource limits"
    
    output += "\n\nAvailable Actions:"
    output += "\n- Use 'restart_process' to restart a specific application"
    output += "\n- Use 'kill_process' to force-close frozen applications"
    
    return output