import 'package:fl_lib/fl_lib.dart'; import 'package:server_box/data/model/server/connection_stat.dart'; class ConnectionStatsStore extends HiveStore { ConnectionStatsStore._() : super('connection_stats'); static final instance = ConnectionStatsStore._(); // Record a connection attempt void recordConnection(ConnectionStat stat) { final key = '${stat.serverId}_${ShortId.generate()}'; set(key, stat); _cleanOldRecords(stat.serverId); } // Clean records older than 30 days for a specific server void _cleanOldRecords(String serverId) { final cutoffTime = DateTime.now().subtract(const Duration(days: 30)); final allKeys = keys().toList(); final keysToDelete = []; for (final key in allKeys) { if (key.startsWith(serverId)) { final parts = key.split('_'); if (parts.length >= 2) { final timestamp = int.tryParse(parts.last); if (timestamp != null) { final recordTime = DateTime.fromMillisecondsSinceEpoch(timestamp); if (recordTime.isBefore(cutoffTime)) { keysToDelete.add(key); } } } } } for (final key in keysToDelete) { remove(key); } } // Get connection stats for a specific server ServerConnectionStats getServerStats(String serverId, String serverName) { final allStats = getConnectionHistory(serverId); if (allStats.isEmpty) { return ServerConnectionStats( serverId: serverId, serverName: serverName, totalAttempts: 0, successCount: 0, failureCount: 0, recentConnections: [], successRate: 0.0, ); } final totalAttempts = allStats.length; final successCount = allStats.where((s) => s.result.isSuccess).length; final failureCount = totalAttempts - successCount; final successRate = totalAttempts > 0 ? (successCount / totalAttempts) : 0.0; final successTimes = allStats .where((s) => s.result.isSuccess) .map((s) => s.timestamp) .toList(); final failureTimes = allStats .where((s) => !s.result.isSuccess) .map((s) => s.timestamp) .toList(); DateTime? lastSuccessTime; DateTime? lastFailureTime; if (successTimes.isNotEmpty) { successTimes.sort((a, b) => b.compareTo(a)); lastSuccessTime = successTimes.first; } if (failureTimes.isNotEmpty) { failureTimes.sort((a, b) => b.compareTo(a)); lastFailureTime = failureTimes.first; } // Get recent connections (last 20) final recentConnections = allStats.take(20).toList(); return ServerConnectionStats( serverId: serverId, serverName: serverName, totalAttempts: totalAttempts, successCount: successCount, failureCount: failureCount, lastSuccessTime: lastSuccessTime, lastFailureTime: lastFailureTime, recentConnections: recentConnections, successRate: successRate, ); } // Get connection history for a specific server List getConnectionHistory(String serverId) { final allKeys = keys().where((key) => key.startsWith(serverId)).toList(); final stats = []; for (final key in allKeys) { final stat = get( key, fromObj: (val) { if (val is ConnectionStat) return val; if (val is Map) { final map = val.toStrDynMap; if (map == null) return null; try { return ConnectionStat.fromJson(map as Map); } catch (e) { dprint('Parsing ConnectionStat from JSON', e); } } return null; }, ); if (stat != null) { stats.add(stat); } } // Sort by timestamp, newest first stats.sort((a, b) => b.timestamp.compareTo(a.timestamp)); return stats; } // Get all servers' stats List getAllServerStats() { final serverIds = {}; final serverNames = {}; // Get all unique server IDs for (final key in keys()) { final parts = key.split('_'); if (parts.length >= 2) { final serverId = parts[0]; serverIds.add(serverId); // Try to get server name from the stored stat final stat = get( key, fromObj: (val) { if (val is ConnectionStat) return val; if (val is Map) { final map = val.toStrDynMap; if (map == null) return null; try { return ConnectionStat.fromJson(map as Map); } catch (e) { dprint('Parsing ConnectionStat from JSON', e); } } return null; }, ); if (stat != null) { serverNames[serverId] = stat.serverName; } } } final allStats = []; for (final serverId in serverIds) { final serverName = serverNames[serverId] ?? serverId; final stats = getServerStats(serverId, serverName); allStats.add(stats); } return allStats; } // Clear all connection stats void clearAll() { box.clear(); } // Clear stats for a specific server void clearServerStats(String serverId) { final keysToDelete = keys().where((key) => key.startsWith(serverId)).toList(); for (final key in keysToDelete) { remove(key); } } }