import 'package:json_annotation/json_annotation.dart';

part 'system_metrics_model.g.dart';

/// Modèle pour les métriques système en temps réel
@JsonSerializable(fieldRename: FieldRename.none)
class SystemMetricsModel {
  // Métriques CPU
  final double? cpuUsagePercent;
  final int? availableProcessors;
  final double? systemLoadAverage;

  // Métriques mémoire
  final int? totalMemoryBytes;
  final int? usedMemoryBytes;
  final int? freeMemoryBytes;
  final int? maxMemoryBytes;
  final double? memoryUsagePercent;
  final String? totalMemoryFormatted;
  final String? usedMemoryFormatted;
  final String? freeMemoryFormatted;

  // Métriques disque
  final int? totalDiskBytes;
  final int? usedDiskBytes;
  final int? freeDiskBytes;
  final double? diskUsagePercent;
  final String? totalDiskFormatted;
  final String? usedDiskFormatted;
  final String? freeDiskFormatted;

  // Métriques utilisateurs
  final int? activeUsersCount;
  final int? totalUsersCount;
  final int? activeSessionsCount;
  final int? failedLoginAttempts24h;

  // Métriques API
  final int? apiRequestsLastHour;
  final int? apiRequestsToday;
  final double? averageResponseTimeMs;
  final int? totalRequestsCount;

  // Métriques base de données
  final int? dbConnectionPoolSize;
  final int? dbActiveConnections;
  final int? dbIdleConnections;
  final bool? dbHealthy;

  // Métriques erreurs et logs
  final int? criticalErrorsCount;
  final int? warningsCount;
  final int? infoLogsCount;
  final int? debugLogsCount;
  final int? totalLogsCount;

  // Métriques réseau
  final double? networkBytesReceivedPerSec;
  final double? networkBytesSentPerSec;
  final String? networkInFormatted;
  final String? networkOutFormatted;

  // Métriques système
  final String? systemStatus;
  final int? uptimeMillis;
  final String? uptimeFormatted;
  final String? startTime;
  final String? currentTime;
  final String? javaVersion;
  final String? quarkusVersion;
  final String? applicationVersion;

  // Métriques maintenance
  final String? lastBackup;
  final String? nextScheduledMaintenance;
  final String? lastMaintenance;

  // URLs
  final String? apiBaseUrl;
  final String? authServerUrl;
  final String? cdnUrl;

  // Cache
  final int? totalCacheSizeBytes;
  final String? totalCacheSizeFormatted;
  final int? totalCacheEntries;

  const SystemMetricsModel({
    this.cpuUsagePercent,
    this.availableProcessors,
    this.systemLoadAverage,
    this.totalMemoryBytes,
    this.usedMemoryBytes,
    this.freeMemoryBytes,
    this.maxMemoryBytes,
    this.memoryUsagePercent,
    this.totalMemoryFormatted,
    this.usedMemoryFormatted,
    this.freeMemoryFormatted,
    this.totalDiskBytes,
    this.usedDiskBytes,
    this.freeDiskBytes,
    this.diskUsagePercent,
    this.totalDiskFormatted,
    this.usedDiskFormatted,
    this.freeDiskFormatted,
    this.activeUsersCount,
    this.totalUsersCount,
    this.activeSessionsCount,
    this.failedLoginAttempts24h,
    this.apiRequestsLastHour,
    this.apiRequestsToday,
    this.averageResponseTimeMs,
    this.totalRequestsCount,
    this.dbConnectionPoolSize,
    this.dbActiveConnections,
    this.dbIdleConnections,
    this.dbHealthy,
    this.criticalErrorsCount,
    this.warningsCount,
    this.infoLogsCount,
    this.debugLogsCount,
    this.totalLogsCount,
    this.networkBytesReceivedPerSec,
    this.networkBytesSentPerSec,
    this.networkInFormatted,
    this.networkOutFormatted,
    this.systemStatus,
    this.uptimeMillis,
    this.uptimeFormatted,
    this.startTime,
    this.currentTime,
    this.javaVersion,
    this.quarkusVersion,
    this.applicationVersion,
    this.lastBackup,
    this.nextScheduledMaintenance,
    this.lastMaintenance,
    this.apiBaseUrl,
    this.authServerUrl,
    this.cdnUrl,
    this.totalCacheSizeBytes,
    this.totalCacheSizeFormatted,
    this.totalCacheEntries,
  });

  factory SystemMetricsModel.fromJson(Map<String, dynamic> json) =>
      _$SystemMetricsModelFromJson(json);

  Map<String, dynamic> toJson() => _$SystemMetricsModelToJson(this);

  /// Helper pour formater un pourcentage
  String formatPercent(double? percent) {
    if (percent == null) return '0%';
    return '${percent.toStringAsFixed(1)}%';
  }
}
