package dev.lions.unionflow.server.api.dto.system.response;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

/**
 * Response contenant les métriques système en temps réel
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SystemMetricsResponse {

    // Métriques CPU
    private Double cpuUsagePercent;
    private Integer availableProcessors;
    private Double systemLoadAverage;

    // Métriques mémoire
    private Long totalMemoryBytes;
    private Long usedMemoryBytes;
    private Long freeMemoryBytes;
    private Long maxMemoryBytes;
    private Double memoryUsagePercent;
    private String totalMemoryFormatted; // ex: "8.0 GB"
    private String usedMemoryFormatted;  // ex: "5.4 GB"
    private String freeMemoryFormatted;  // ex: "2.6 GB"

    // Métriques disque
    private Long totalDiskBytes;
    private Long usedDiskBytes;
    private Long freeDiskBytes;
    private Double diskUsagePercent;
    private String totalDiskFormatted; // ex: "500 GB"
    private String usedDiskFormatted;  // ex: "225 GB"
    private String freeDiskFormatted;  // ex: "275 GB"

    // Métriques utilisateurs
    private Integer activeUsersCount;          // Utilisateurs connectés actuellement
    private Integer totalUsersCount;           // Total utilisateurs dans le système
    private Integer activeSessionsCount;       // Sessions actives
    private Integer failedLoginAttempts24h;    // Échecs login dernières 24h

    // Métriques API
    private Long apiRequestsLastHour;          // Requêtes API dernière heure
    private Long apiRequestsToday;             // Requêtes API aujourd'hui
    private Double averageResponseTimeMs;      // Temps réponse moyen (ms)
    private Long totalRequestsCount;           // Total requêtes depuis démarrage

    // Métriques base de données
    private Integer dbConnectionPoolSize;      // Taille pool connexions
    private Integer dbActiveConnections;       // Connexions actives
    private Integer dbIdleConnections;         // Connexions en attente
    private Boolean dbHealthy;                 // État santé DB

    // Métriques erreurs et logs
    private Integer criticalErrorsCount;       // Erreurs critiques
    private Integer warningsCount;             // Avertissements
    private Integer infoLogsCount;             // Logs info
    private Integer debugLogsCount;            // Logs debug
    private Long totalLogsCount;               // Total logs

    // Métriques réseau
    private Double networkBytesReceivedPerSec; // Octets reçus/sec
    private Double networkBytesSentPerSec;     // Octets envoyés/sec
    private String networkInFormatted;         // ex: "12.5 MB/s"
    private String networkOutFormatted;        // ex: "8.2 MB/s"

    // Métriques système
    private String systemStatus;               // OPERATIONAL, DEGRADED, MAINTENANCE, DOWN
    private Long uptimeMillis;                 // Uptime en ms
    private String uptimeFormatted;            // ex: "5j 12h 34m"
    private LocalDateTime startTime;           // Date/heure démarrage
    private LocalDateTime currentTime;         // Date/heure actuelle
    private String javaVersion;                // Version Java
    private String quarkusVersion;             // Version Quarkus
    private String applicationVersion;         // Version application

    // Métriques maintenance
    private LocalDateTime lastBackup;          // Dernière sauvegarde
    private LocalDateTime nextScheduledMaintenance; // Prochaine maintenance
    private LocalDateTime lastMaintenance;     // Dernière maintenance

    // URLs et configuration réseau
    private String apiBaseUrl;                 // URL API
    private String authServerUrl;              // URL serveur auth (Keycloak)
    private String cdnUrl;                     // URL CDN (si applicable)

    // Statistiques de stockage (cache)
    private Long totalCacheSizeBytes;
    private String totalCacheSizeFormatted;    // ex: "450 MB"
    private Integer totalCacheEntries;

    /**
     * Helper pour formater les bytes en taille lisible
     */
    public static String formatBytes(long bytes) {
        if (bytes < 1024) return bytes + " B";
        int exp = (int) (Math.log(bytes) / Math.log(1024));
        String pre = "KMGTPE".charAt(exp - 1) + "";
        return String.format(java.util.Locale.US, "%.1f %sB", bytes / Math.pow(1024, exp), pre);
    }

    /**
     * Helper pour formater l'uptime
     */
    public static String formatUptime(long millis) {
        long seconds = millis / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        long days = hours / 24;

        hours = hours % 24;
        minutes = minutes % 60;

        if (days > 0) {
            return String.format("%dj %dh %dm", days, hours, minutes);
        } else if (hours > 0) {
            return String.format("%dh %dm", hours, minutes);
        } else {
            return String.format("%dm", minutes);
        }
    }
}
