// lib/auth_provider.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; // Added import for post-frame callback
import 'package:shared_preferences/shared_preferences.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'dart:convert';
import 'package:bcrypt/bcrypt.dart'; // Import bcrypt
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; // Import secure storage
import 'package:environment_monitoring_app/services/api_service.dart';
//import 'package:environment_monitoring_app/services/api_service.dart';
import 'package:environment_monitoring_app/services/database_helper.dart';

import 'package:environment_monitoring_app/services/base_api_service.dart';
import 'package:environment_monitoring_app/services/server_config_service.dart';
import 'package:environment_monitoring_app/services/retry_service.dart';
import 'package:environment_monitoring_app/services/user_preferences_service.dart';

// Removed _CacheDataContainer class
// Removed _loadCacheDataFromIsolate function

class AuthProvider with ChangeNotifier {
  late final ApiService _apiService;
  late final DatabaseHelper _dbHelper;
  late final ServerConfigService _serverConfigService;
  late final RetryService _retryService;
  final UserPreferencesService _userPreferencesService = UserPreferencesService();

  // Initialize secure storage
  final _secureStorage = const FlutterSecureStorage();
  static const _passwordStorageKey = 'user_password';

  // --- Session & Profile State ---
  String? _jwtToken;
  String? _userEmail;
  Map<String, dynamic>? _profileData;
  bool get isLoggedIn => _jwtToken != null;
  String? get userEmail => _userEmail;
  Map<String, dynamic>? get profileData => _profileData;

  // --- App State ---
  bool _isLoading = true; // Keep true initially
  bool _isFirstLogin = true;
  DateTime? _lastSyncTimestamp;
  bool _isBackgroundLoading = false; // Added flag for background loading
  bool get isLoading => _isLoading;
  bool get isBackgroundLoading => _isBackgroundLoading;
  bool get isFirstLogin => _isFirstLogin;
  DateTime? get lastSyncTimestamp => _lastSyncTimestamp;

  bool _isSessionExpired = false;
  bool get isSessionExpired => _isSessionExpired;

  // --- Cached Master Data ---
  List<Map<String, dynamic>>? _allUsers;
  List<Map<String, dynamic>>? _tarballStations;
  List<Map<String, dynamic>>? _manualStations;
  List<Map<String, dynamic>>? _tarballClassifications;
  List<Map<String, dynamic>>? _riverManualStations;
  List<Map<String, dynamic>>? _riverTriennialStations;

  List<Map<String, dynamic>>? _departments;
  List<Map<String, dynamic>>? _companies;
  List<Map<String, dynamic>>? _positions;
  List<Map<String, dynamic>>? _airClients;
  List<Map<String, dynamic>>? _airManualStations;
  List<Map<String, dynamic>>? _states;
  List<Map<String, dynamic>>? _appSettings;
  List<Map<String, dynamic>>? _npeParameterLimits;
  List<Map<String, dynamic>>? _marineParameterLimits;
  List<Map<String, dynamic>>? _riverParameterLimits;
  List<Map<String, dynamic>>? _apiConfigs;
  List<Map<String, dynamic>>? _ftpConfigs;
  List<Map<String, dynamic>>? _documents;
  List<Map<String, dynamic>>? _pendingRetries;

  // --- Getters for UI access ---
  List<Map<String, dynamic>>? get allUsers => _allUsers;
  List<Map<String, dynamic>>? get tarballStations => _tarballStations;
  List<Map<String, dynamic>>? get manualStations => _manualStations;
  List<Map<String, dynamic>>? get tarballClassifications => _tarballClassifications;
  List<Map<String, dynamic>>? get riverManualStations => _riverManualStations;
  List<Map<String, dynamic>>? get riverTriennialStations => _riverTriennialStations;
  // --- ADDED: Getter for River Investigative Stations ---
  List<Map<String, dynamic>>? get riverInvestigativeStations => _riverManualStations;
  // --- END ADDED ---
  List<Map<String, dynamic>>? get departments => _departments;
  List<Map<String, dynamic>>? get companies => _companies;
  List<Map<String, dynamic>>? get positions => _positions;
  List<Map<String, dynamic>>? get airClients => _airClients;
  List<Map<String, dynamic>>? get airManualStations => _airManualStations;
  List<Map<String, dynamic>>? get states => _states;
  List<Map<String, dynamic>>? get appSettings => _appSettings;
  List<Map<String, dynamic>>? get npeParameterLimits => _npeParameterLimits;
  List<Map<String, dynamic>>? get marineParameterLimits => _marineParameterLimits;
  List<Map<String, dynamic>>? get riverParameterLimits => _riverParameterLimits;
  List<Map<String, dynamic>>? get apiConfigs => _apiConfigs;
  List<Map<String, dynamic>>? get ftpConfigs => _ftpConfigs;
  List<Map<String, dynamic>>? get documents => _documents;
  List<Map<String, dynamic>>? get pendingRetries => _pendingRetries;

  // --- SharedPreferences Keys ---
  static const String tokenKey = 'jwt_token';
  static const String userEmailKey = 'user_email';
  static const String profileDataKey = 'user_profile_data';
  static const String lastSyncTimestampKey = 'last_sync_timestamp';
  static const String isFirstLoginKey = 'is_first_login';
  static const String lastOnlineLoginKey = 'last_online_login';

  AuthProvider({
    required ApiService apiService,
    required DatabaseHelper dbHelper,
    required ServerConfigService serverConfigService,
    required RetryService retryService,
  })  : _apiService = apiService,
        _dbHelper = dbHelper,
        _serverConfigService = serverConfigService,
        _retryService = retryService {
    debugPrint('AuthProvider: Initializing...');
    _initializeAndLoadData(); // Use the updated method name
  }

  Future<bool> isConnected() async {
    final connectivityResult = await Connectivity().checkConnectivity();
    return !connectivityResult.contains(ConnectivityResult.none);
  }

  // Updated method using SchedulerBinding instead of compute
  Future<void> _initializeAndLoadData() async {
    _isLoading = true;
    notifyListeners(); // Notify UI about initial loading state

    // 1. Perform quick SharedPreferences reads first.
    final prefs = await SharedPreferences.getInstance();
    _jwtToken = prefs.getString(tokenKey);
    _userEmail = prefs.getString(userEmailKey);
    _isFirstLogin = prefs.getBool(isFirstLoginKey) ?? true;

    final profileJson = prefs.getString(profileDataKey);
    if (profileJson != null) {
      try {
        _profileData = jsonDecode(profileJson);
      } catch (e) {
        debugPrint("Failed to decode profile from prefs: $e");
        prefs.remove(profileDataKey);
      }
    }

    // --- START MODIFIED: Load server config with is_active check ---
    // Load server config early
    Map<String, dynamic>? activeApiConfig = await _serverConfigService.getActiveApiConfig();
    if (activeApiConfig == null) {
      debugPrint("AuthProvider: No active config in SharedPreferences. Checking local DB for 'is_active' flag...");
      // Load configs directly from DB helper (since cache isn't loaded yet)
      final allApiConfigs = await _dbHelper.loadApiConfigs();
      if (allApiConfigs != null && allApiConfigs.isNotEmpty) {
        try {
          // Find the first config marked as active. Note: 'is_active' might be 1 or true.
          activeApiConfig = allApiConfigs.firstWhere(
                (c) => c['is_active'] == 1 || c['is_active'] == true,
            orElse: () => allApiConfigs.first, // Fallback to just the first config if none are active
          );
          debugPrint("AuthProvider: Found active config in DB: ${activeApiConfig['config_name']}");
          await _serverConfigService.setActiveApiConfig(activeApiConfig);
        } catch (e) {
          debugPrint("AuthProvider: Error finding active config in DB. $e");
        }
      }
    }

    // If still no config (empty DB, first launch), set hardcoded default
    if (activeApiConfig == null) {
      debugPrint("AuthProvider: No active config found in DB. Setting default bootstrap URL.");
      final initialConfig = {
        'api_config_id': 0,
        'config_name': 'Default Server',
        'api_url': 'https://mms-apiv4.pstw.com.my/v1', // This is your bootstrap URL
      };
      await _serverConfigService.setActiveApiConfig(initialConfig);
    }
    // --- END MODIFIED ---

    final lastSyncString = prefs.getString(lastSyncTimestampKey);
    if (lastSyncString != null) {
      try {
        _lastSyncTimestamp = DateTime.parse(lastSyncString);
      } catch (e) {
        debugPrint("Error parsing last sync timestamp: $e");
        prefs.remove(lastSyncTimestampKey);
      }
    }

    // 2. Set isLoading to false *before* scheduling heavy work.
    _isLoading = false;
    notifyListeners(); // Let the UI build

    // 3. Schedule heavy database load *after* the first frame.
    SchedulerBinding.instance.addPostFrameCallback((_) async {
      debugPrint("AuthProvider: First frame built. Starting background cache load...");
      _isBackgroundLoading = true; // Indicate background activity
      notifyListeners(); // Show a secondary loading indicator if needed

      try {
        // Call the original cache loading method here
        await _loadDataFromCache();
        debugPrint("AuthProvider: Background cache load complete.");

        // After loading cache, check session status and potentially sync
        if (_jwtToken != null) {
          debugPrint('AuthProvider: Session loaded.');
          await _userPreferencesService.applyAndSaveDefaultPreferencesIfNeeded();
          // Decide whether to call checkAndTransition or validateAndRefresh here
          await checkAndTransitionToOnlineSession(); // Example: Check if transition needed
          await validateAndRefreshSession();       // Example: Validate if already online
        } else {
          debugPrint('AuthProvider: No active session. App is in offline mode.');
        }

      } catch (e) {
        debugPrint("AuthProvider: Error during background cache load: $e");
        // Handle error appropriately
      } finally {
        _isBackgroundLoading = false; // Background load finished
        notifyListeners(); // Update UI
      }
    });
  }

  /// Checks if the session is offline and attempts to transition to an online session by performing a silent re-login.
  /// Returns true if a successful transition occurred.
  Future<bool> checkAndTransitionToOnlineSession() async {
    // Condition 1: Check connectivity
    if (!(await isConnected())) {
      debugPrint("AuthProvider: No internet connection. Skipping transition check.");
      return false;
    }

    // Condition 2: Check if currently in an offline session state
    final bool inOfflineSession = _jwtToken != null && _jwtToken!.startsWith("offline-session-");
    if (!inOfflineSession) {
      // Already online or logged out, no transition needed.
      // --- START: FIX FOR DOUBLE SYNC ---
      // Removed the redundant syncAllData call from here.
      if(_jwtToken != null) {
        debugPrint("AuthProvider: Session is already online. Skipping transition sync.");
        // Consider calling validateAndRefreshSession() here instead if needed,
        // but avoid a full syncAllData().
      }
      // --- END: FIX FOR DOUBLE SYNC ---
      return false;
    }

    // Read password from secure storage
    final String? password = await _secureStorage.read(key: _passwordStorageKey);
    if (password == null || _userEmail == null) {
      debugPrint("AuthProvider: In offline session, but no password in secure storage for auto-relogin. Manual login required.");
      return false;
    }

    debugPrint("AuthProvider: Internet detected in offline session. Attempting silent re-login for $_userEmail...");

    try {
      final result = await _apiService.login(_userEmail!, password);

      if (result['success'] == true) {
        debugPrint("AuthProvider: Silent re-login successful. Transitioning to online session.");
        final String token = result['data']['token'];
        final Map<String, dynamic> profile = result['data']['profile'];

        // Use existing login method to set up session and trigger sync.
        await login(token, profile, password); // This call includes syncAllData

        notifyListeners(); // Ensure UI updates after state change
        return true;
      } else {
        // Silent login failed
        debugPrint("AuthProvider: Silent re-login failed: ${result['message']}");
        return false;
      }
    } catch (e) {
      debugPrint("AuthProvider: Silent re-login exception: $e");
      return false;
    }
  }

  Future<void> validateAndRefreshSession() async {
    if (!(await isConnected())) {
      debugPrint('AuthProvider: No connection, skipping session validation.');
      return;
    }

    if (_isSessionExpired) {
      debugPrint('AuthProvider: Session is marked as expired, manual login required.');
      return;
    }

    if (_jwtToken == null || _jwtToken!.startsWith("offline-session-")) {
      return; // No online session to validate
    }

    try {
      await _apiService.validateToken();
      debugPrint('AuthProvider: Session token is valid.');
    } on SessionExpiredException {
      debugPrint('AuthProvider: Session validation failed (token expired). Attempting silent re-login.');
      final bool reauthenticated = await attemptSilentRelogin();

      if (!reauthenticated) {
        debugPrint('AuthProvider: Silent re-login failed. Switching to session-expired offline mode.');
        _isSessionExpired = true;
        notifyListeners();
      } else {
        debugPrint('AuthProvider: Silent re-login successful. Session restored.');
      }
    } catch (e) {
      debugPrint('AuthProvider: An error occurred during session validation: $e');
    }
  }

  Future<bool> attemptSilentRelogin() async {
    if (!(await isConnected())) {
      debugPrint("AuthProvider: No internet for silent relogin.");
      return false;
    }

    final String? password = await _secureStorage.read(key: _passwordStorageKey);
    if (password == null || _userEmail == null) {
      debugPrint("AuthProvider: No cached credentials in secure storage for silent relogin.");
      return false;
    }

    debugPrint("AuthProvider: Session may be expired. Attempting silent re-login for $_userEmail...");
    try {
      final result = await _apiService.login(_userEmail!, password);
      if (result['success'] == true) {
        debugPrint("AuthProvider: Silent re-login successful.");
        final String token = result['data']['token'];
        final Map<String, dynamic> profile = result['data']['profile'];
        // Critical: Call the main login function to update token, profile, hash, etc.
        // BUT prevent it from triggering another full sync immediately if called during syncAllData
        await _updateSessionInternals(token, profile, password); // Use helper to avoid sync loop
        _isSessionExpired = false;
        notifyListeners();
        return true;
      } else {
        debugPrint("AuthProvider: Silent re-login failed: ${result['message']}");
        return false;
      }
    } catch (e) {
      debugPrint("AuthProvider: Silent re-login exception: $e");
      return false;
    }
  }

  // Helper to update session without triggering sync, used by attemptSilentRelogin
  Future<void> _updateSessionInternals(String token, Map<String, dynamic> profile, String password) async {
    _jwtToken = token;
    _userEmail = profile['email'];

    await _secureStorage.write(key: _passwordStorageKey, value: password);

    final Map<String, dynamic> profileWithToken = Map.from(profile);
    profileWithToken['token'] = token;
    _profileData = profileWithToken;

    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(tokenKey, token);
    await prefs.setString(userEmailKey, _userEmail!);
    await prefs.setString(profileDataKey, jsonEncode(_profileData));
    await prefs.setString(lastOnlineLoginKey, DateTime.now().toIso8601String()); // Update last online time
    await _dbHelper.saveProfile(_profileData!);

    try {
      debugPrint("AuthProvider: (Re-login) Hashing and caching password for offline login.");
      final String hashedPassword = await compute(hashPassword, password);
      await _dbHelper.upsertUserWithCredentials(
        profile: profile,
        passwordHash: hashedPassword,
      );
      debugPrint("AuthProvider: (Re-login) Credentials cached successfully.");
    } catch (e) {
      debugPrint("AuthProvider: (Re-login) Failed to cache password hash: $e");
    }
    // DO NOT call syncAllData here to prevent loops when called from syncAllData's catch block.
  }


  Future<void> syncAllData({bool forceRefresh = false}) async {
    if (!(await isConnected())) {
      debugPrint("AuthProvider: Device is OFFLINE. Skipping sync.");
      return;
    }

    if (_isSessionExpired) {
      debugPrint("AuthProvider: Skipping sync, session is expired. Manual login required.");
      throw Exception('Session expired. Please log in again to sync.');
    }

    if (_jwtToken == null || _jwtToken!.startsWith("offline-session-")) {
      debugPrint("AuthProvider: Skipping sync, session is offline or null.");
      return;
    }

    try {
      debugPrint("AuthProvider: Device is ONLINE. Starting delta sync.");
      final prefs = await SharedPreferences.getInstance();
      final String? lastSync = forceRefresh ? null : prefs.getString(lastSyncTimestampKey);

      final result = await _apiService.syncAllData(lastSyncTimestamp: lastSync);

      if (result['success']) {
        debugPrint("AuthProvider: Delta sync successful.");
        final newSyncTimestamp = DateTime.now().toUtc().toIso8601String();
        await prefs.setString(lastSyncTimestampKey, newSyncTimestamp);
        _lastSyncTimestamp = DateTime.parse(newSyncTimestamp);

        if (_isFirstLogin) {
          await setIsFirstLogin(false);
          debugPrint("AuthProvider: First successful sync complete. isFirstLogin flag set to false.");
        }

        await _loadDataFromCache(); // Reload data after successful sync
        notifyListeners();
      } else {
        debugPrint("AuthProvider: Delta sync failed logically. Message: ${result['message']}");
        throw Exception('Data sync failed. Please check the logs.');
      }
    } on SessionExpiredException {
      debugPrint("AuthProvider: Session expired during sync. Attempting silent re-login...");
      final bool reauthenticated = await attemptSilentRelogin();
      if (reauthenticated) {
        debugPrint("AuthProvider: Re-login successful. Retrying sync...");
        await syncAllData(forceRefresh: forceRefresh); // Retry the sync
      } else {
        debugPrint("AuthProvider: Re-login failed after session expired during sync. Switching to offline mode.");
        _isSessionExpired = true;
        notifyListeners();
        throw Exception('Session expired. App is now in offline mode.');
      }
    } catch (e) {
      debugPrint("AuthProvider: A general error occurred during sync: $e");
      rethrow;
    }
  }

  Future<void> syncRegistrationData() async {
    if (!(await isConnected())) {
      debugPrint("AuthProvider: Device is OFFLINE. Skipping registration data sync.");
      return;
    }

    debugPrint("AuthProvider: Fetching data for registration screen...");
    final result = await _apiService.syncRegistrationData();

    if (result['success']) {
      await _loadDataFromCache();
      notifyListeners();
      debugPrint("AuthProvider: Registration data loaded and UI notified.");
    } else {
      debugPrint("AuthProvider: Registration data sync failed.");
    }
  }

  Future<void> refreshProfile() async {
    if (!(await isConnected())) {
      debugPrint("AuthProvider: Device is OFFLINE. Skipping profile refresh.");
      return;
    }
    if (_isSessionExpired || _jwtToken == null || _jwtToken!.startsWith("offline-session-")) {
      debugPrint("AuthProvider: Skipping profile refresh, session is offline, expired, or null.");
      return;
    }

    try {
      final result = await _apiService.refreshProfile();
      if (result['success']) {
        await setProfileData(result['data']);
      }
    } on SessionExpiredException {
      debugPrint("AuthProvider: Session expired during profile refresh. Attempting silent re-login...");
      await attemptSilentRelogin(); // Attempt re-login but don't retry refresh automatically here
    } catch (e) {
      debugPrint("AuthProvider: Error during profile refresh: $e");
    }
  }

  Future<void> proactiveTokenRefresh() async {
    if (!(await isConnected())) {
      debugPrint('AuthProvider: No connection, skipping proactive token refresh.');
      return;
    }

    final prefs = await SharedPreferences.getInstance();
    final lastOnlineLoginString = prefs.getString(lastOnlineLoginKey);

    if (lastOnlineLoginString == null) {
      debugPrint('AuthProvider: No last online login timestamp found, skipping proactive refresh.');
      return;
    }

    try {
      final lastOnlineLogin = DateTime.parse(lastOnlineLoginString);
      if (DateTime.now().difference(lastOnlineLogin).inHours >= 24) {
        debugPrint('AuthProvider: Session is older than 24 hours. Attempting proactive silent re-login.');
        await attemptSilentRelogin();
      } else {
        debugPrint('AuthProvider: Session is fresh (< 24 hours old). No proactive refresh needed.');
      }
    } catch (e) {
      debugPrint('AuthProvider: Error during proactive token refresh check: $e');
    }
  }

  // This method performs the actual DB reads
  Future<void> _loadDataFromCache() async {
    final prefs = await SharedPreferences.getInstance();
    final profileJson = prefs.getString(profileDataKey);
    if (profileJson != null && _profileData == null) {
      try { _profileData = jsonDecode(profileJson); } catch(e) { /*...*/ }
    }
    _profileData ??= await _dbHelper.loadProfile();

    _allUsers = await _dbHelper.loadUsers();
    _tarballStations = await _dbHelper.loadTarballStations();
    _manualStations = await _dbHelper.loadManualStations();
    _tarballClassifications = await _dbHelper.loadTarballClassifications();
    _riverManualStations = await _dbHelper.loadRiverManualStations();
    _riverTriennialStations = await _dbHelper.loadRiverTriennialStations();

    _departments = await _dbHelper.loadDepartments();
    _companies = await _dbHelper.loadCompanies();
    _positions = await _dbHelper.loadPositions();
    _airClients = await _dbHelper.loadAirClients();
    _airManualStations = await _dbHelper.loadAirManualStations();
    _states = await _dbHelper.loadStates();
    _appSettings = await _dbHelper.loadAppSettings();
    _npeParameterLimits = await _dbHelper.loadNpeParameterLimits();
    _marineParameterLimits = await _dbHelper.loadMarineParameterLimits();
    _riverParameterLimits = await _dbHelper.loadRiverParameterLimits();
    _documents = await _dbHelper.loadDocuments();
    _apiConfigs = await _dbHelper.loadApiConfigs();
    _ftpConfigs = await _dbHelper.loadFtpConfigs();
    _pendingRetries = await _retryService.getPendingTasks(); // Use service here is okay
    debugPrint("AuthProvider: All master data loaded from local DB cache (background/sync).");
  }


  Future<void> refreshPendingTasks() async {
    _pendingRetries = await _retryService.getPendingTasks();
    notifyListeners();
  }

  Future<void> login(String token, Map<String, dynamic> profile, String password) async {
    // Call the internal helper first
    await _updateSessionInternals(token, profile, password);

    // Now proceed with post-login actions that *don't* belong in the helper
    debugPrint('AuthProvider: Login successful. Session and profile persisted.');
    // --- THIS IS THE LINE THAT FIXES THE TICKING ---
    await _userPreferencesService.applyAndSaveDefaultPreferencesIfNeeded();
    // ---
    // The main sync triggered by a direct user login
    await syncAllData(forceRefresh: true);
    // Notify listeners *after* sync is attempted (or throws)
    notifyListeners();
  }


  Future<bool> loginOffline(String email, String password) async {
    debugPrint("AuthProvider: Attempting offline login for user $email.");

    try {
      final String? storedHash = await _dbHelper.getUserPasswordHashByEmail(email);

      if (storedHash == null || storedHash.isEmpty) {
        debugPrint("AuthProvider DEBUG: Offline login failed for $email because NO HASH was found in local storage.");
        return false;
      }

      debugPrint("AuthProvider: Verifying password against stored hash...");
      final bool passwordMatches = await compute(verifyPassword, CheckPasswordParams(password, storedHash));

      if (passwordMatches) {
        debugPrint("AuthProvider: Offline password verification successful.");
        final Map<String, dynamic>? cachedProfile = await _dbHelper.loadProfileByEmail(email);
        if (cachedProfile == null) {
          debugPrint("AuthProvider DEBUG: Offline login failed because profile data was missing, even though password matched.");
          return false;
        }

        _jwtToken = "offline-session-${DateTime.now().millisecondsSinceEpoch}";
        _userEmail = email;

        await _secureStorage.write(key: _passwordStorageKey, value: password);

        final Map<String, dynamic> profileWithToken = Map.from(cachedProfile);
        profileWithToken['token'] = _jwtToken;
        _profileData = profileWithToken;

        final prefs = await SharedPreferences.getInstance();
        await prefs.setString(tokenKey, _jwtToken!);
        await prefs.setString(userEmailKey, _userEmail!);
        await prefs.setString(profileDataKey, jsonEncode(_profileData));

        // Load cache data immediately after offline login succeeds
        // This doesn't need the post-frame callback as it's triggered by user action
        await _loadDataFromCache();
        notifyListeners();
        return true;
      } else {
        debugPrint("AuthProvider DEBUG: Offline login failed because password did not match stored hash (Hash Mismatch).");
        return false;
      }
    } catch (e) {
      debugPrint("AuthProvider DEBUG: An unexpected error occurred during offline login process: $e");
      return false;
    }
  }

  Future<void> setProfileData(Map<String, dynamic> data) async {
    final String? existingToken = _profileData?['token'];
    _profileData = data;
    if (_profileData != null && existingToken != null) {
      _profileData!['token'] = existingToken;
    }

    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(profileDataKey, jsonEncode(_profileData));
    await _dbHelper.saveProfile(_profileData!);
    notifyListeners();
  }

  Future<void> setIsFirstLogin(bool value) async {
    _isFirstLogin = value;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool(isFirstLoginKey, value);
    notifyListeners();
  }

  Future<void> logout() async {
    debugPrint('AuthProvider: Initiating logout...');
    _jwtToken = null;
    _userEmail = null;
    _profileData = null;
    _lastSyncTimestamp = null;
    _isFirstLogin = true;
    _isSessionExpired = false;

    await _secureStorage.delete(key: _passwordStorageKey);

    // Clear cached data
    _allUsers = null;
    _tarballStations = null;
    _manualStations = null;
    _tarballClassifications = null;
    _riverManualStations = null;
    _riverTriennialStations = null;
    _departments = null;
    _companies = null;
    _positions = null;
    _airClients = null;
    _airManualStations = null;
    _states = null;
    _appSettings = null;
    _npeParameterLimits = null;
    _marineParameterLimits = null;
    _riverParameterLimits = null;
    _documents = null;
    _apiConfigs = null;
    _ftpConfigs = null;
    _pendingRetries = null;

    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(tokenKey);
    await prefs.remove(userEmailKey);
    await prefs.remove(profileDataKey);
    await prefs.remove(lastSyncTimestampKey);
    await prefs.remove(lastOnlineLoginKey);
    await prefs.remove('default_preferences_saved'); // Also clear user prefs flag
    await prefs.setBool(isFirstLoginKey, true);

    debugPrint('AuthProvider: All session and cached data cleared.');
    notifyListeners();
  }

  Future<Map<String, dynamic>> resetPassword(String email) {
    // Assuming _apiService has a method for this, otherwise implement it.
    // This looks correct based on your previous code structure.
    return _apiService.post('auth/forgot-password', {'email': email});
  }
}

// These remain unchanged as they are used by compute for password hashing/checking
class CheckPasswordParams {
  final String password;
  final String hash;
  CheckPasswordParams(this.password, this.hash);
}

String hashPassword(String password) {
  return BCrypt.hashpw(password, BCrypt.gensalt());
}

bool verifyPassword(CheckPasswordParams params) {
  return BCrypt.checkpw(params.password, params.hash);
}