// lib/services/telegram_service.dart import 'package:flutter/foundation.dart'; import 'package:sqflite/sqflite.dart'; import 'package:environment_monitoring_app/services/api_service.dart'; import 'package:environment_monitoring_app/services/settings_service.dart'; class TelegramService { // FIX: Change to a nullable, externally injected dependency. ApiService? _apiService; final DatabaseHelper _dbHelper = DatabaseHelper(); final SettingsService _settingsService = SettingsService(); bool _isProcessing = false; // FIX: Accept ApiService in the constructor to break the circular dependency at runtime. TelegramService({ApiService? apiService}) : _apiService = apiService; // FIX: Re-introduce the setter for circular injection (used in main.dart) void setApiService(ApiService apiService) { _apiService = apiService; } // MODIFIED: This method is now synchronous and requires the appSettings list. String _getChatIdForModule(String module, List>? appSettings) { switch (module) { case 'marine_in_situ': return _settingsService.getInSituChatId(appSettings); case 'marine_tarball': return _settingsService.getTarballChatId(appSettings); case 'air_manual': // ADDED THIS CASE return _settingsService.getAirManualChatId(appSettings); default: return ''; } } /// Tries to send an alert immediately over the network. /// Returns `true` on success, `false` on failure. // MODIFIED: This method now requires the appSettings list to be passed in. Future sendAlertImmediately(String module, String message, List>? appSettings) async { debugPrint("[TelegramService] Attempting to send alert immediately for module: $module"); String chatId = _getChatIdForModule(module, appSettings); if (chatId.isEmpty) { debugPrint("[TelegramService] ❌ Cannot send immediately. Chat ID for module '$module' is not configured."); return false; } // FIX: Check for the injected ApiService if (_apiService == null) { debugPrint("[TelegramService] ❌ ApiService is not available."); return false; } final result = await _apiService!.sendTelegramAlert( chatId: chatId, message: message, ); if (result['success'] == true) { debugPrint("[TelegramService] ✅ Alert sent immediately."); return true; } else { debugPrint("[TelegramService] ❌ Immediate send failed. Reason: ${result['message']}"); return false; } } /// Saves an alert to the local database queue. (This is now the fallback) // MODIFIED: This method now requires the appSettings list to be passed in. Future queueMessage(String module, String message, List>? appSettings) async { String chatId = _getChatIdForModule(module, appSettings); if (chatId.isEmpty) { debugPrint("[TelegramService] ❌ ERROR: Cannot queue alert. Chat ID for module '$module' is not configured."); return; } debugPrint("[TelegramService] ⬇️ Immediate send failed. Saving alert to local queue."); final db = await _dbHelper.database; await db.insert( 'alert_queue', { 'chat_id': chatId, 'message': message, 'created_at': DateTime.now().toIso8601String(), }, ); debugPrint("[TelegramService] ✅ Alert queued for module: $module"); } /// Processes all pending alerts in the queue. /// This method does NOT need changes because the chatId is already stored in the queue. Future processAlertQueue() async { if (_isProcessing) { debugPrint("[TelegramService] ⏳ Queue is already being processed. Skipping."); return; } _isProcessing = true; debugPrint("[TelegramService] ▶️ Starting to process alert queue..."); final db = await _dbHelper.database; final List> pendingAlerts = await db.query('alert_queue', orderBy: 'created_at'); if (pendingAlerts.isEmpty) { debugPrint("[TelegramService] ⏹️ Queue is empty. Nothing to process."); _isProcessing = false; return; } // FIX: Check for ApiService before starting the loop if (_apiService == null) { debugPrint("[TelegramService] ❌ ApiService is not available for processing queue."); _isProcessing = false; return; } debugPrint("[TelegramService] 🔎 Found ${pendingAlerts.length} pending alerts."); for (var alert in pendingAlerts) { final alertId = alert['id']; final chatId = alert['chat_id']; debugPrint("[TelegramService] - Processing alert ID: $alertId for Chat ID: $chatId"); final result = await _apiService!.sendTelegramAlert( chatId: chatId, message: alert['message'], ); if (result['success'] == true) { await db.delete('alert_queue', where: 'id = ?', whereArgs: [alertId]); debugPrint("[TelegramService] ✅ SUCCESS: Alert ID $alertId sent and removed from queue."); } else { debugPrint("[TelegramService] ❌ FAILED: Alert ID $alertId could not be sent. Reason: ${result['message']}"); } } debugPrint("[TelegramService] ⏹️ Finished processing alert queue."); _isProcessing = false; } }