import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:intl/intl.dart'; import 'package:environment_monitoring_app/services/base_api_service.dart'; import 'package:environment_monitoring_app/services/telegram_service.dart'; import 'package:environment_monitoring_app/services/settings_service.dart'; import 'package:environment_monitoring_app/models/in_situ_sampling_data.dart'; import 'package:environment_monitoring_app/models/tarball_data.dart'; class MarineApiService { final BaseApiService _baseService = BaseApiService(); final TelegramService _telegramService = TelegramService(); // REMOVED: SettingsService is no longer called directly from this file for chat IDs. // final SettingsService _settingsService = SettingsService(); Future> getTarballStations() { return _baseService.get('marine/tarball/stations'); } Future> getManualStations() { return _baseService.get('marine/manual/stations'); } Future> getTarballClassifications() { return _baseService.get('marine/tarball/classifications'); } // MODIFIED: Method now requires the appSettings list. Future> submitTarballSample({ required Map formData, required Map imageFiles, required List>? appSettings, }) async { debugPrint("Step 1: Submitting tarball form data to the server..."); final dataResult = await _baseService.post('marine/tarball/sample', formData); if (dataResult['success'] != true) { return { 'status': 'L1', 'success': false, 'message': 'Failed to submit data to server: ${dataResult['message']}', 'reportId': null, }; } debugPrint("Step 1 successful. Tarball data submitted."); final recordId = dataResult['data']?['autoid']; if (recordId == null) { return { 'status': 'L2', 'success': false, 'message': 'Data submitted, but failed to get a record ID to link images.', 'reportId': null, }; } final filesToUpload = {}; imageFiles.forEach((key, value) { if (value != null) filesToUpload[key] = value; }); if (filesToUpload.isEmpty) { _handleTarballSuccessAlert(formData, appSettings, isDataOnly: true); return { 'status': 'L3', 'success': true, 'message': 'Data submitted successfully. No images were attached.', 'reportId': recordId, }; } debugPrint("Step 2: Uploading ${filesToUpload.length} tarball images for record ID: $recordId"); final imageResult = await _baseService.postMultipart( endpoint: 'marine/tarball/images', fields: {'autoid': recordId.toString()}, files: filesToUpload, ); if (imageResult['success'] != true) { return { 'status': 'L2', 'success': false, 'message': 'Data submitted to server, but image upload failed: ${imageResult['message']}', 'reportId': recordId, }; } _handleTarballSuccessAlert(formData, appSettings, isDataOnly: false); return { 'status': 'L3', 'success': true, 'message': 'Data and images submitted to server successfully.', 'reportId': recordId, }; } // MODIFIED: Method now requires the appSettings list. Future> submitInSituSample({ required Map formData, required Map imageFiles, required InSituSamplingData inSituData, required List>? appSettings, }) async { debugPrint("Step 1: Submitting in-situ form data to the server..."); final dataResult = await _baseService.post('marine/manual/sample', formData); if (dataResult['success'] != true) { return { 'status': 'L1', 'success': false, 'message': 'Failed to submit in-situ data: ${dataResult['message']}', 'reportId': null, }; } debugPrint("Step 1 successful. In-situ data submitted."); final recordId = dataResult['data']?['man_id']; if (recordId == null) { return { 'status': 'L2', 'success': false, 'message': 'In-situ data submitted, but failed to get a record ID for images.', 'reportId': null, }; } final filesToUpload = {}; imageFiles.forEach((key, value) { if (value != null) filesToUpload[key] = value; }); if (filesToUpload.isEmpty) { _handleInSituSuccessAlert(inSituData, appSettings, isDataOnly: true); return { 'status': 'L3', 'success': true, 'message': 'In-situ data submitted successfully. No images were attached.', 'reportId': recordId.toString(), }; } debugPrint("Step 2: Uploading ${filesToUpload.length} in-situ images for record ID: $recordId"); final imageResult = await _baseService.postMultipart( endpoint: 'marine/manual/images', fields: {'man_id': recordId.toString()}, files: filesToUpload, ); if (imageResult['success'] != true) { return { 'status': 'L2', 'success': false, 'message': 'In-situ data submitted, but image upload failed: ${imageResult['message']}', 'reportId': recordId.toString(), }; } _handleInSituSuccessAlert(inSituData, appSettings, isDataOnly: false); return { 'status': 'L3', 'success': true, 'message': 'In-situ data and images submitted successfully.', 'reportId': recordId.toString(), }; } // MODIFIED: Method now requires appSettings and calls the updated TelegramService. Future _handleTarballSuccessAlert(Map formData, List>? appSettings, {required bool isDataOnly}) async { try { final message = _generateTarballAlertMessage(formData, isDataOnly: isDataOnly); final bool wasSent = await _telegramService.sendAlertImmediately('marine_tarball', message, appSettings); if (!wasSent) { await _telegramService.queueMessage('marine_tarball', message, appSettings); } } catch (e) { debugPrint("Failed to handle Tarball Telegram alert: $e"); } } String _generateTarballAlertMessage(Map formData, {required bool isDataOnly}) { final submissionType = isDataOnly ? "(Data Only)" : "(Data & Images)"; final stationName = formData['tbl_station_name'] ?? 'N/A'; final stationCode = formData['tbl_station_code'] ?? 'N/A'; final classification = formData['classification_name'] ?? formData['classification_id'] ?? 'N/A'; final buffer = StringBuffer() ..writeln('✅ *Tarball Sample $submissionType Submitted:*') ..writeln() ..writeln('*Station Name & Code:* $stationName ($stationCode)') ..writeln('*Date of Submission:* ${formData['sampling_date']}') ..writeln('*Submitted by User:* ${formData['first_sampler_name'] ?? 'N/A'}') ..writeln('*Classification:* $classification') ..writeln('*Status of Submission:* Successful'); if (formData['distance_difference'] != null && double.tryParse(formData['distance_difference']!) != null && double.parse(formData['distance_difference']!) > 0) { buffer ..writeln() ..writeln('🔔 *Alert:*') ..writeln('*Distance from station:* ${(double.parse(formData['distance_difference']!) * 1000).toStringAsFixed(0)} meters'); if (formData['distance_difference_remarks'] != null && formData['distance_difference_remarks']!.isNotEmpty) { buffer.writeln('*Remarks for distance:* ${formData['distance_difference_remarks']}'); } } return buffer.toString(); } // MODIFIED: Method now requires appSettings and calls the updated TelegramService. Future _handleInSituSuccessAlert(InSituSamplingData data, List>? appSettings, {required bool isDataOnly}) async { try { final message = data.generateTelegramAlertMessage(isDataOnly: isDataOnly); final bool wasSent = await _telegramService.sendAlertImmediately('marine_in_situ', message, appSettings); if (!wasSent) { await _telegramService.queueMessage('marine_in_situ', message, appSettings); } } catch (e) { debugPrint("Failed to handle In-Situ Telegram alert: $e"); } } }