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';

class MarineApiService {
  final BaseApiService _baseService = BaseApiService();
  final TelegramService _telegramService = TelegramService();
  final SettingsService _settingsService = SettingsService();

  Future<Map<String, dynamic>> getTarballStations() {
    return _baseService.get('marine/tarball/stations');
  }

  Future<Map<String, dynamic>> getManualStations() {
    return _baseService.get('marine/manual/stations');
  }

  Future<Map<String, dynamic>> getTarballClassifications() {
    return _baseService.get('marine/tarball/classifications');
  }

  /// Orchestrates a two-step submission process for tarball samples. (Unchanged)
  /// Returns a detailed status code and the report ID upon success.
  Future<Map<String, dynamic>> submitTarballSample({
    required Map<String, String> formData,
    required Map<String, File?> imageFiles,
  }) async {
    // --- Step 1: Submit Text Data Only ---
    debugPrint("Step 1: Submitting tarball form data to the server...");
    final dataResult = await _baseService.post('marine/tarball/sample', formData);

    if (dataResult['success'] != true) {
      // Data submission failed. This is an L1 failure.
      return {
        'status': 'L1',
        'success': false,
        'message': 'Failed to submit data to server: ${dataResult['message']}',
        'reportId': null,
      };
    }
    debugPrint("Step 1 successful. Tarball data submitted.");

    // --- Step 2: Upload Image Files ---
    final recordId = dataResult['data']?['autoid'];
    if (recordId == null) {
      // Data was saved, but we can't link the images. This is an L2 failure.
      return {
        'status': 'L2',
        'success': false,
        'message': 'Data submitted, but failed to get a record ID to link images.',
        'reportId': null,
      };
    }

    final filesToUpload = <String, File>{};
    imageFiles.forEach((key, value) {
      if (value != null) filesToUpload[key] = value;
    });

    if (filesToUpload.isEmpty) {
      // If there are no images, the process is complete.
      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) {
      // Image upload failed. This is an L2 failure.
      return {
        'status': 'L2',
        'success': false,
        'message': 'Data submitted to server, but image upload failed: ${imageResult['message']}',
        'reportId': recordId,
      };
    }

    // Both steps were successful.
    return {
      'status': 'L3',
      'success': true,
      'message': 'Data and images submitted to server successfully.',
      'reportId': recordId,
    };
  }

  /// Orchestrates a two-step submission process for in-situ samples.
  Future<Map<String, dynamic>> submitInSituSample({
    required Map<String, String> formData,
    required Map<String, File?> imageFiles,
  }) async {
    // --- Step 1: Submit Form Data ---
    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.");

    // --- Step 2: Upload Image Files ---
    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 = <String, File>{};
    imageFiles.forEach((key, value) {
      if (value != null) filesToUpload[key] = value;
    });

    if (filesToUpload.isEmpty) {
      // Handle alert for successful data-only submission.
      _handleInSituSuccessAlert(formData, 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(),
      };
    }

    // Handle alert for successful data and image submission.
    _handleInSituSuccessAlert(formData, isDataOnly: false);

    return {
      'status': 'L3',
      'success': true,
      'message': 'In-situ data and images submitted successfully.',
      'reportId': recordId.toString(),
    };
  }

  /// A private helper method to build and send the detailed in-situ alert.
  Future<void> _handleInSituSuccessAlert(Map<String, String> formData, {required bool isDataOnly}) async {
    try {
      final groupChatId = await _settingsService.getInSituChatId();
      if (groupChatId.isNotEmpty) {
        // Extract data from the formData map with fallbacks
        final submissionType = isDataOnly ? "(Data Only)" : "(Data & Images)";
        final stationName = formData['man_station_name'] ?? 'N/A';
        final stationCode = formData['man_station_code'] ?? 'N/A';
        final submissionDate = formData['sampling_date'] ?? DateFormat('yyyy-MM-dd').format(DateTime.now());
        final submitter = formData['first_sampler_name'] ?? 'N/A';
        final manualsondeID = formData['man_sondeID'] ?? 'N/A';
        //final distanceKm = double.tryParse(formData['distance_difference_km'] ?? '0') ?? 0;
        //final distanceMeters = (distanceKm * 1000).toStringAsFixed(0);
        //final distanceRemarks = formData['distance_difference_remarks'];

        final distanceKm = double.tryParse(formData['man_distance_difference'] ?? '0') ?? 0;
        final distanceMeters = (distanceKm * 1000).toStringAsFixed(0);
        final distanceRemarks = formData['man_distance_difference_remarks'] ?? 'N/A';


        // Build the message using a StringBuffer for clarity
        final buffer = StringBuffer();
        buffer.writeln('✅ *In-Situ Sample ${submissionType} Submitted:*');
        buffer.writeln(); // Blank line
        buffer.writeln('*Station Name & Code:* $stationName ($stationCode)');
        buffer.writeln('*Date of Submitted:* $submissionDate');
        buffer.writeln('*Submitted by User:* $submitter');
        buffer.writeln('*Sonde ID:* $manualsondeID');
        buffer.writeln('*Status of Submission:* Successful');

        // Only include the Alert section if distance or remarks are relevant
        if (distanceKm > 0 || (distanceRemarks != null && distanceRemarks.isNotEmpty)) {
          buffer.writeln(); // Blank line
          buffer.writeln('🔔 *Alert:*');
          buffer.writeln('*Distance from station:* $distanceMeters meters');
          if (distanceRemarks != null && distanceRemarks.isNotEmpty) {
            buffer.writeln('*Remarks for distance:* $distanceRemarks');
          }
        }

        final String message = buffer.toString();

        // Try to send immediately, or queue on failure
        final bool wasSent = await _telegramService.sendAlertImmediately('marine_in_situ', message);
        if (!wasSent) {
          await _telegramService.queueMessage('marine_in_situ', message);
        }
      }
    } catch (e) {
      debugPrint("Failed to handle Telegram alert: $e");
    }
  }
}