// lib/services/submission_ftp_service.dart

import 'dart:io';
import 'package:flutter/foundation.dart';
import 'dart:convert'; // Added for jsonEncode
import 'package:path/path.dart' as p; // Added for basename

import 'package:environment_monitoring_app/services/user_preferences_service.dart';
import 'package:environment_monitoring_app/services/ftp_service.dart';
import 'package:environment_monitoring_app/services/retry_service.dart';
// Import necessary services and models if needed for queueFtpTasksForSkippedAttempt
import 'package:environment_monitoring_app/services/zipping_service.dart';
//import 'package:environment_monitoring_app/services/api_service.dart'; // For DatabaseHelper
import 'package:environment_monitoring_app/services/database_helper.dart';

/// A generic, reusable service for handling the FTP submission process.
/// It respects user preferences for enabled destinations for any given module.
class SubmissionFtpService {
  final UserPreferencesService _userPreferencesService = UserPreferencesService();
  final FtpService _ftpService = FtpService();
  final RetryService _retryService = RetryService();
  // Add ZippingService and DatabaseHelper if queueFtpTasksForSkippedAttempt needs them
  final ZippingService _zippingService = ZippingService();
  final DatabaseHelper _dbHelper = DatabaseHelper();


  /// Submits a file to all enabled FTP destinations for a given module.
  ///
  /// This method works differently from the API service. It attempts to upload
  /// to ALL enabled destinations. It returns a summary of success/failure for each.
  /// If any upload fails, it is queued for individual retry.
  /// The overall result is considered successful if there are no hard errors
  /// during the process, even if some uploads are queued.
  Future<Map<String, dynamic>> submit({
    required String moduleName,
    required File fileToUpload,
    required String remotePath,
  }) async {
    final destinations = await _userPreferencesService.getEnabledFtpConfigsForModule(moduleName);

    if (destinations.isEmpty) {
      debugPrint("SubmissionFtpService: No enabled FTP destinations for module '$moduleName'. Skipping.");
      // Return success with a specific status indicating no config
      return {
        'success': true, // Process succeeded because there was nothing to do
        'message': 'No FTP destinations enabled for this module.',
        'statuses': [{'status': 'Not Configured', 'message': 'No destinations enabled.', 'success': true}]
      };
    }

    final List<Map<String, dynamic>> statuses = [];
    bool allSucceededOrNotConfigured = true; // Track if all attempts either succeeded or weren't configured

    for (final dest in destinations) {
      final configName = dest['config_name'] as String? ?? 'Unknown FTP';
      final int? configId = dest['ftp_config_id'] as int?; // Get the config ID

      // Skip if config ID is missing (should not happen with DB data)
      if (configId == null) {
        debugPrint("SubmissionFtpService: Skipping destination '$configName' due to missing config ID.");
        statuses.add({
          'config_name': configName,
          'status': 'Error',
          'success': false,
          'message': 'Configuration ID missing.',
        });
        allSucceededOrNotConfigured = false;
        continue;
      }

      debugPrint("SubmissionFtpService: Attempting to upload to '$configName' (ID: $configId)");

      final result = await _ftpService.uploadFile(
        config: dest,
        fileToUpload: fileToUpload,
        remotePath: remotePath,
      );

      statuses.add({
        'config_name': configName,
        'ftp_config_id': configId, // Include ID in status
        'success': result['success'],
        'message': result['message'],
        'status': result['success'] ? 'Success' : 'Failed', // Add status text
      });

      if (result['success'] != true) {
        allSucceededOrNotConfigured = false;
        // If an individual upload fails, queue it for manual retry.
        debugPrint("SubmissionFtpService: Upload to '$configName' (ID: $configId) failed. Queuing for retry.");
        // --- START FIX: Add ftpConfigId ---
        await _retryService.addFtpToQueue(
          localFilePath: fileToUpload.path,
          remotePath: remotePath,
          ftpConfigId: configId, // Pass the specific config ID
        );
        // --- END FIX ---
      }
    }

    if (allSucceededOrNotConfigured) {
      return {
        'success': true,
        'message': 'File successfully uploaded to all enabled FTP destinations.',
        'statuses': statuses,
      };
    } else {
      return {
        'success': true, // The process itself succeeded (attempted all), even if some uploads were queued.
        'message': 'One or more FTP uploads failed and have been queued for retry.',
        'statuses': statuses,
      };
    }
  }

  /// Manually queues FTP tasks when the initial FTP attempt is skipped (e.g., due to session expiry).
  Future<void> queueFtpTasksForSkippedAttempt({
    required String moduleName,
    required Map<String, dynamic> dataJson, // The data model converted to JSON (toDbJson)
    required Map<String, File> imageFiles,
    required String baseFileName, // Base name for zip files
  }) async {
    debugPrint("Manually queuing FTP tasks for skipped attempt (Module: $moduleName).");
    final ftpConfigs = await _dbHelper.loadFtpConfigs() ?? [];
    if (ftpConfigs.isEmpty) {
      debugPrint("Cannot queue skipped FTP tasks: No FTP configurations found.");
      return;
    }

    // 1. Create Data ZIP (in temp directory)
    final dataZip = await _zippingService.createDataZip(
      // Adapt jsonDataMap based on module if needed, using dataJson
      jsonDataMap: {'db.json': jsonEncode(dataJson)}, // Default, adjust per module if needed
      baseFileName: baseFileName,
      destinationDir: null, // Save to temp dir
    );

    // 2. Create Image ZIP (in temp directory)
    File? imageZip;
    if (imageFiles.isNotEmpty) {
      imageZip = await _zippingService.createImageZip(
        imageFiles: imageFiles.values.toList(),
        baseFileName: baseFileName,
        destinationDir: null, // Save to temp dir
      );
    }

    // 3. Queue uploads for each config
    for (final config in ftpConfigs) {
      final configId = config['ftp_config_id'];
      if (configId != null) {
        // Queue data zip upload
        if (dataZip != null) {
          await _retryService.addFtpToQueue(
              localFilePath: dataZip.path,
              remotePath: '/${p.basename(dataZip.path)}',
              ftpConfigId: configId
          );
          debugPrint("Queued skipped data ZIP upload for FTP config ID $configId");
        }
        // Queue image zip upload
        if (imageZip != null) {
          await _retryService.addFtpToQueue(
              localFilePath: imageZip.path,
              remotePath: '/${p.basename(imageZip.path)}',
              ftpConfigId: configId
          );
          debugPrint("Queued skipped image ZIP upload for FTP config ID $configId");
        }
      }
    }
    // Temporary ZIP files will be cleaned up by OS eventually, or handled by retry logic upon success/failure.
  }

}