// hey import 'dart:async'; enum ConnectionState { disconnected, connecting, connected, ready, reconnecting, error, disabled, } // If you're touching ( you doing this rignt now ) this file, STOP IMEDIATLY! This is violiating TeamKomet code revision policy! // If you're touching ( you doing this rignt now ) this file, AND DONT WANT TO STOP! REFACTOR IT IMMEDIATLY TO MAKE SOME SENSE AND DONT LOOK LIKE SHIT BY AI class ConnectionInfo { final ConnectionState state; final DateTime timestamp; final String? message; final Map? metadata; final int? attemptNumber; final Duration? reconnectDelay; final String? serverUrl; final int? latency; ConnectionInfo({ required this.state, required this.timestamp, this.message, this.metadata, this.attemptNumber, this.reconnectDelay, this.serverUrl, this.latency, }); ConnectionInfo copyWith({ ConnectionState? state, DateTime? timestamp, String? message, Map? metadata, int? attemptNumber, Duration? reconnectDelay, String? serverUrl, int? latency, }) { return ConnectionInfo( state: state ?? this.state, timestamp: timestamp ?? this.timestamp, message: message ?? this.message, metadata: metadata ?? this.metadata, attemptNumber: attemptNumber ?? this.attemptNumber, reconnectDelay: reconnectDelay ?? this.reconnectDelay, serverUrl: serverUrl ?? this.serverUrl, latency: latency ?? this.latency, ); } bool get isActive => state == ConnectionState.ready || state == ConnectionState.connected; bool get canSendMessages => state == ConnectionState.ready; bool get isConnecting => state == ConnectionState.connecting || state == ConnectionState.reconnecting; bool get hasError => state == ConnectionState.error; bool get isDisconnected => state == ConnectionState.disconnected || state == ConnectionState.disabled; @override String toString() { final buffer = StringBuffer(); buffer.write('ConnectionInfo(state: $state'); if (message != null) buffer.write(', message: $message'); if (attemptNumber != null) buffer.write(', attempt: $attemptNumber'); if (serverUrl != null) buffer.write(', server: $serverUrl'); if (latency != null) buffer.write(', latency: ${latency}ms'); buffer.write(')'); return buffer.toString(); } } class ConnectionStateManager { static final ConnectionStateManager _instance = ConnectionStateManager._internal(); factory ConnectionStateManager() => _instance; ConnectionStateManager._internal(); ConnectionInfo _currentInfo = ConnectionInfo( state: ConnectionState.disconnected, timestamp: DateTime.now(), ); final StreamController _stateController = StreamController.broadcast(); ConnectionInfo get currentInfo => _currentInfo; Stream get stateStream => _stateController.stream; final List _stateHistory = []; List get stateHistory => List.unmodifiable(_stateHistory); void setState( ConnectionState newState, { String? message, Map? metadata, int? attemptNumber, Duration? reconnectDelay, String? serverUrl, int? latency, }) { final oldState = _currentInfo.state; final newInfo = _currentInfo.copyWith( state: newState, timestamp: DateTime.now(), message: message, metadata: metadata, attemptNumber: attemptNumber, reconnectDelay: reconnectDelay, serverUrl: serverUrl, latency: latency, ); _currentInfo = newInfo; _addToHistory(newInfo); _stateController.add(newInfo); _logStateChange(oldState, newState, message); } void updateMetadata(Map metadata) { final updatedInfo = _currentInfo.copyWith( metadata: {...?(_currentInfo.metadata), ...metadata}, ); _currentInfo = updatedInfo; _stateController.add(updatedInfo); } void updateReconnectDelay(Duration delay) { final updatedInfo = _currentInfo.copyWith(reconnectDelay: delay); _currentInfo = updatedInfo; _stateController.add(updatedInfo); } void updateLatency(int latencyMs) { final updatedInfo = _currentInfo.copyWith(latency: latencyMs); _currentInfo = updatedInfo; _stateController.add(updatedInfo); } Duration get timeInCurrentState { return DateTime.now().difference(_currentInfo.timestamp); } int get connectionAttempts { return _stateHistory .where((info) => info.state == ConnectionState.connecting) .length; } int get errorCount { return _stateHistory .where((info) => info.state == ConnectionState.error) .length; } double get averageLatency { final latencies = _stateHistory .where((info) => info.latency != null) .map((info) => info.latency!) .toList(); if (latencies.isEmpty) return 0.0; return latencies.reduce((a, b) => a + b) / latencies.length; } Map get stateStatistics { final stats = {}; for (final info in _stateHistory) { stats[info.state] = (stats[info.state] ?? 0) + 1; } return stats; } List getLastStates(int count) { final start = _stateHistory.length - count; return _stateHistory.sublist(start < 0 ? 0 : start); } void clearHistory() { _stateHistory.clear(); } void reset() { setState(ConnectionState.disconnected, message: 'Состояние сброшено'); clearHistory(); } void _addToHistory(ConnectionInfo info) { _stateHistory.add(info); if (_stateHistory.length > 50) { _stateHistory.removeAt(0); } } void _logStateChange( ConnectionState from, ConnectionState to, String? message, ) { final fromStr = _getStateDisplayName(from); final toStr = _getStateDisplayName(to); final messageStr = message != null ? ' ($message)' : ''; print('🔄 Состояние подключения: $fromStr → $toStr$messageStr'); } String _getStateDisplayName(ConnectionState state) { switch (state) { case ConnectionState.disconnected: return 'Отключен'; case ConnectionState.connecting: return 'Подключение'; case ConnectionState.connected: return 'Подключен'; case ConnectionState.ready: return 'Готов'; case ConnectionState.reconnecting: return 'Переподключение'; case ConnectionState.error: return 'Ошибка'; case ConnectionState.disabled: return 'Отключен'; } } void dispose() { _stateController.close(); } }