// lib/services/user_preferences_service.dart

import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:environment_monitoring_app/services/api_service.dart'; // Contains DatabaseHelper
import 'package:environment_monitoring_app/services/database_helper.dart';

/// A dedicated service to manage the user's local preferences for
/// module-specific submission destinations.
class UserPreferencesService {
  final DatabaseHelper _dbHelper = DatabaseHelper();
  static const _defaultPrefsSavedKey = 'default_preferences_saved';

  // Moved from settings.dart for central access
  // This list now includes all your modules
  final List<Map<String, String>> _configurableModules = [
    {'key': 'marine_tarball', 'name': 'Marine Tarball'},
    {'key': 'marine_in_situ', 'name': 'Marine In-Situ'},
    {'key': 'marine_investigative', 'name': 'Marine Investigative'},
    {'key': 'marine_report', 'name': 'Marine Report'},
    {'key': 'river_in_situ', 'name': 'River In-Situ'},
    {'key': 'river_triennial', 'name': 'River Triennial'},
    {'key': 'river_investigative', 'name': 'River Investigative'},
    {'key': 'air_installation', 'name': 'Air Installation'},
    {'key': 'air_collection', 'name': 'Air Collection'},
  ];

  /// Checks if default preferences have been set. If not, it applies
  /// and saves the default submission destinations for all modules.
  /// This ensures the app is ready for submissions immediately after the first login.
  Future<void> applyAndSaveDefaultPreferencesIfNeeded() async {
    final prefs = await SharedPreferences.getInstance();
    if (prefs.getBool(_defaultPrefsSavedKey) ?? false) {
      // Defaults have already been saved for this session, do nothing.
      return;
    }

    debugPrint("Checking availability of configs for default preference application...");

    try {
      // Get all possible configs from the database just once
      final allApiConfigs = await _dbHelper.loadApiConfigs() ?? [];
      final allFtpConfigs = await _dbHelper.loadFtpConfigs() ?? [];

      // --- CRITICAL CHECK ---
      // If we haven't synced data from the server yet, do NOT attempt to apply defaults.
      // If we proceed now, we would save "empty" preferences and the flag would be set to true,
      // preventing the defaults from ever being applied correctly later.
      if (allApiConfigs.isEmpty && allFtpConfigs.isEmpty) {
        debugPrint("No API or FTP configs found in local DB. Skipping default application. Will retry later.");
        return;
      }

      debugPrint("Configs found. Applying and auto-saving default submission preferences.");

      for (var module in _configurableModules) {
        final moduleKey = module['key']!;

        // 1. Save master switches to enable API and FTP for the module.
        // FORCE them to be TRUE by default.
        await saveModulePreference(
          moduleName: moduleKey,
          isApiEnabled: true,
          isFtpEnabled: true,
        );

        // 2. Determine default API links
        final defaultApiLinks = allApiConfigs.map((config) {
          // Robust check for active status (handles int 1, string '1', bool true)
          final activeVal = config['is_active'];
          final bool isActive = activeVal == 1 || activeVal == true || activeVal.toString() == '1';
          final bool isPstwHq = (config['config_name'] == 'PSTW_HQ');

          bool isEnabled;

          // --- MODIFIED: Special logic for Marine Report ---
          // For marine_report, ONLY tick PSTW_HQ by default. Ignore other active APIs.
          if (moduleKey == 'marine_report') {
            isEnabled = isPstwHq;
          } else {
            // For other modules, tick if Active OR PSTW_HQ
            isEnabled = isActive || isPstwHq;
          }

          return {...config, 'is_enabled': isEnabled};
        }).toList();

        // 3. Determine default FTP links
        // Handle mapping 'marine_in_situ' -> 'marine_manual'
        String expectedFtpModuleKey = moduleKey;
        if (moduleKey == 'marine_in_situ') {
          expectedFtpModuleKey = 'marine_manual';
        } else if (moduleKey == 'river_in_situ') {
          expectedFtpModuleKey = 'river_manual';
        }

        final defaultFtpLinks = allFtpConfigs.map((config) {
          final String configModule = config['ftp_module'] ?? '';

          // Robust check for active status (Handles your SQL data where is_active is 1)
          final activeVal = config['is_active'];
          final bool isActive = activeVal == 1 || activeVal == true || activeVal.toString() == '1';

          // Enable if the config's module matches the current moduleKey AND it's active
          bool isEnabled = (configModule == expectedFtpModuleKey) && isActive;

          return {...config, 'is_enabled': isEnabled};
        }).toList();
        // --- END MODIFICATION ---

        // 4. Save the default links to the database.
        await saveApiLinksForModule(moduleKey, defaultApiLinks);
        await saveFtpLinksForModule(moduleKey, defaultFtpLinks);
      }

      // 5. Set the flag to prevent this from running again until next login.
      await prefs.setBool(_defaultPrefsSavedKey, true);
      debugPrint("Default submission preferences have been auto-saved.");

    } catch (e) {
      debugPrint("Error auto-saving default preferences: $e");
    }
  }


  /// Retrieves a module's master submission preferences.
  /// This method now returns a default TRUE object if no preference is found.
  Future<Map<String, dynamic>?> getModulePreference(String moduleName) async {
    final preference = await _dbHelper.getModulePreference(moduleName);
    if (preference != null) {
      return preference;
    }
    // Return default enabled state (TRUE) if not found in DB yet
    return {'is_api_enabled': true, 'is_ftp_enabled': true};
  }

  /// Saves or updates a module's master on/off switches for API and FTP submissions.
  Future<void> saveModulePreference({
    required String moduleName,
    required bool isApiEnabled,
    required bool isFtpEnabled,
  }) async {
    await _dbHelper.saveModulePreference(
      moduleName: moduleName,
      isApiEnabled: isApiEnabled,
      isFtpEnabled: isFtpEnabled,
    );
  }

  /// Retrieves all available API configurations and merges them with the user's
  /// saved preferences for a specific module.
  ///
  /// This is primarily for the Settings UI to display all possible destinations
  /// with their current enabled/disabled state (e.g., checkboxes).
  Future<List<Map<String, dynamic>>> getAllApiConfigsWithModulePreferences(String moduleName) async {
    // 1. Get all possible API destinations that have been synced to the device.
    final allApiConfigs = await _dbHelper.loadApiConfigs() ?? [];
    if (allApiConfigs.isEmpty) return [];

    // 2. Get the specific links the user has previously saved for this module.
    final savedLinks = await _dbHelper.getAllApiLinksForModule(moduleName);

    // 3. Merge the two lists.
    return allApiConfigs.map((config) {
      final configId = config['api_config_id'];
      bool isEnabled;

      // --- START MODIFICATION: Corrected Merge Logic ---
      Map<String, dynamic>? matchingLink;
      try {
        matchingLink = savedLinks.firstWhere(
              (link) => link['api_config_id'] == configId,
        );
      } catch (e) {
        matchingLink = null; // No match found
      }

      if (matchingLink != null) {
        // A preference exists. Use the saved value.
        isEnabled = matchingLink['is_enabled'] as bool? ?? false;
      } else {
        // No preference saved for this config. Apply default logic.
        // Robust check for active status
        final activeVal = config['is_active'];
        final bool isActive = activeVal == 1 || activeVal == true || activeVal.toString() == '1';
        final bool isPstwHq = (config['config_name'] == 'PSTW_HQ');

        // --- MODIFIED: Special logic for Marine Report ---
        if (moduleName == 'marine_report') {
          isEnabled = isPstwHq;
        } else {
          isEnabled = isActive || isPstwHq;
        }
      }
      // --- END MODIFICATION ---

      // Return a new map containing the original config details plus the 'is_enabled' flag.
      return {
        ...config,
        'is_enabled': isEnabled,
      };
    }).toList();
  }

  /// Retrieves all available FTP configurations and merges them with the user's
  /// saved preferences for a specific module. (For the Settings UI).
  Future<List<Map<String, dynamic>>> getAllFtpConfigsWithModulePreferences(String moduleName) async {
    final allFtpConfigs = await _dbHelper.loadFtpConfigs() ?? [];
    if (allFtpConfigs.isEmpty) return [];

    final savedLinks = await _dbHelper.getAllFtpLinksForModule(moduleName);

    // Handle mapping 'marine_in_situ' -> 'marine_manual'
    String expectedFtpModuleKey = moduleName;
    if (moduleName == 'marine_in_situ') {
      expectedFtpModuleKey = 'marine_manual';
    } else if (moduleName == 'river_in_situ') {
      expectedFtpModuleKey = 'river_manual';
    }

    return allFtpConfigs.map((config) {
      final configId = config['ftp_config_id'];
      bool isEnabled;

      // --- START MODIFICATION: Corrected Merge Logic ---
      Map<String, dynamic>? matchingLink;
      try {
        matchingLink = savedLinks.firstWhere(
              (link) => link['ftp_config_id'] == configId,
        );
      } catch (e) {
        matchingLink = null; // No match found
      }

      if (matchingLink != null) {
        // A preference exists. Use the saved value.
        isEnabled = matchingLink['is_enabled'] as bool? ?? false;
      } else {
        // No preference saved for this config. Apply default logic.
        final String configModule = config['ftp_module'] ?? '';
        // Robust check for active status
        final activeVal = config['is_active'];
        final bool isActive = activeVal == 1 || activeVal == true || activeVal.toString() == '1';

        // Use the mapped key for comparison
        isEnabled = (configModule == expectedFtpModuleKey) && isActive;
      }
      // --- END MODIFICATION ---

      return {
        ...config,
        'is_enabled': isEnabled,
      };
    }).toList();
  }

  /// Saves the complete set of enabled/disabled API links for a specific module.
  /// This will replace all previous links for that module.
  Future<void> saveApiLinksForModule(String moduleName, List<Map<String, dynamic>> links) async {
    await _dbHelper.saveApiLinksForModule(moduleName, links);
  }

  /// Saves the complete set of enabled/disabled FTP links for a specific module.
  Future<void> saveFtpLinksForModule(String moduleName, List<Map<String, dynamic>> links) async {
    await _dbHelper.saveFtpLinksForModule(moduleName, links);
  }

  /// Retrieves only the API configurations that are actively enabled for a given module.
  ///
  /// This is primarily for the submission services to know exactly which
  /// destinations to send data to.
  Future<List<Map<String, dynamic>>> getEnabledApiConfigsForModule(String moduleName) async {
    // 1. Check the master switch for the module.
    final pref = await getModulePreference(moduleName); // Use method that has default
    if (pref == null || !(pref['is_api_enabled'] as bool)) {
      debugPrint("API submissions are disabled for module '$moduleName'.");
      return []; // Return empty list if API is disabled or not set.
    }

    // 2. Get all configs with their preference flags.
    final allConfigsWithPrefs = await getAllApiConfigsWithModulePreferences(moduleName);

    // 3. Filter for only those that are enabled.
    final enabledConfigs = allConfigsWithPrefs.where((config) => config['is_enabled'] == true).toList();

    debugPrint("Found ${enabledConfigs.length} enabled API destinations for module '$moduleName'.");
    return enabledConfigs;
  }

  /// Retrieves only the FTP configurations that are actively enabled for a given module.
  Future<List<Map<String, dynamic>>> getEnabledFtpConfigsForModule(String moduleName) async {
    final pref = await getModulePreference(moduleName); // Use method that has default
    if (pref == null || !(pref['is_ftp_enabled'] as bool)) {
      debugPrint("FTP submissions are disabled for module '$moduleName'.");
      return [];
    }

    final allConfigsWithPrefs = await getAllFtpConfigsWithModulePreferences(moduleName);
    final enabledConfigs = allConfigsWithPrefs.where((config) => config['is_enabled'] == true).toList();

    debugPrint("Found ${enabledConfigs.length} enabled FTP destinations for module '$moduleName'.");
    return enabledConfigs;
  }
}