import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'dart:convert';

import 'package:environment_monitoring_app/services/api_service.dart';

/// A comprehensive provider to manage user authentication, session state,
/// and cached master data for offline use.
class AuthProvider with ChangeNotifier {
  final ApiService _apiService = ApiService();
  final DatabaseHelper _dbHelper = DatabaseHelper();

  // --- 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;
  bool _isFirstLogin = true;
  DateTime? _lastSyncTimestamp;
  bool get isLoading => _isLoading;
  bool get isFirstLogin => _isFirstLogin;
  DateTime? get lastSyncTimestamp => _lastSyncTimestamp;

  // --- 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;
  // --- ADDED FOR STATE LIST ---
  List<Map<String, dynamic>>? _states;

  // --- 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;
  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;
  // --- ADDED FOR STATE LIST ---
  List<Map<String, dynamic>>? get states => _states;

  // --- SharedPreferences Keys (made public for BaseApiService) ---
  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';

  AuthProvider() {
    debugPrint('AuthProvider: Initializing...');
    _loadSessionAndSyncData();
  }

  /// Loads the user session from storage and then triggers a data sync.
  Future<void> _loadSessionAndSyncData() async {
    _isLoading = true;
    notifyListeners();

    final prefs = await SharedPreferences.getInstance();
    _jwtToken = prefs.getString(tokenKey);
    _userEmail = prefs.getString(userEmailKey);
    _isFirstLogin = prefs.getBool(isFirstLoginKey) ?? true;
    final lastSyncMillis = prefs.getInt(lastSyncTimestampKey);
    if (lastSyncMillis != null) {
      _lastSyncTimestamp = DateTime.fromMillisecondsSinceEpoch(lastSyncMillis);
    }

    // Always load from local DB first for instant startup
    await _loadDataFromCache();

    if (_jwtToken != null) {
      debugPrint('AuthProvider: Session loaded. Triggering online sync.');
      // Don't await here to allow the UI to build instantly with cached data
      syncAllData();
    } else {
      debugPrint('AuthProvider: No active session. App is in offline mode.');
    }

    _isLoading = false;
    notifyListeners();
  }

  /// The main function to sync all app data. It checks for an internet connection
  /// and fetches from the server if available, otherwise it relies on the local cache.
  Future<void> syncAllData({bool forceRefresh = false}) async {
    final connectivityResult = await Connectivity().checkConnectivity();
    if (connectivityResult != ConnectivityResult.none) {
      debugPrint("AuthProvider: Device is ONLINE. Fetching fresh data from server.");
      await _fetchDataFromServer();
    } else {
      debugPrint("AuthProvider: Device is OFFLINE. Data is already loaded from cache.");
    }
    notifyListeners();
  }

  /// A dedicated method to refresh only the profile.
  Future<void> refreshProfile() async {
    final result = await _apiService.refreshProfile();
    if (result['success']) {
      // Update the profile data in the provider state
      _profileData = result['data'];
      // Persist the updated profile data in SharedPreferences
      final prefs = await SharedPreferences.getInstance();
      await prefs.setString(profileDataKey, jsonEncode(_profileData));
      notifyListeners();
    }
  }

  /// Fetches all master data from the server and caches it locally.
  Future<void> _fetchDataFromServer() async {
    final result = await _apiService.syncAllData();
    if (result['success']) {
      final data = result['data'];
      _profileData = data['profile'];
      _allUsers = data['allUsers'] != null ? List<Map<String, dynamic>>.from(data['allUsers']) : null;
      _tarballStations = data['tarballStations'] != null ? List<Map<String, dynamic>>.from(data['tarballStations']) : null;
      _manualStations = data['manualStations'] != null ? List<Map<String, dynamic>>.from(data['manualStations']) : null;
      _tarballClassifications = data['tarballClassifications'] != null ? List<Map<String, dynamic>>.from(data['tarballClassifications']) : null;
      _riverManualStations = data['riverManualStations'] != null ? List<Map<String, dynamic>>.from(data['riverManualStations']) : null;
      _riverTriennialStations = data['riverTriennialStations'] != null ? List<Map<String, dynamic>>.from(data['riverTriennialStations']) : null;
      _departments = data['departments'] != null ? List<Map<String, dynamic>>.from(data['departments']) : null;
      _companies = data['companies'] != null ? List<Map<String, dynamic>>.from(data['companies']) : null;
      _positions = data['positions'] != null ? List<Map<String, dynamic>>.from(data['positions']) : null;
      _airClients = data['airClients'] != null ? List<Map<String, dynamic>>.from(data['airClients']) : null;
      _airManualStations = data['airManualStations'] != null ? List<Map<String, dynamic>>.from(data['airManualStations']) : null;

      // --- ADDED FOR STATE LIST ---
      // Note: `syncAllData` in ApiService must be updated to fetch 'states'
      _states = data['states'] != null ? List<Map<String, dynamic>>.from(data['states']) : null;

      await setLastSyncTimestamp(DateTime.now());
    }
  }

  /// Loads all master data from the local cache using DatabaseHelper.
  Future<void> _loadDataFromCache() async {
    _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();

    // --- ADDED FOR STATE LIST ---
    // Note: `loadStates()` must be added to your DatabaseHelper class
    _states = await _dbHelper.loadStates();

    debugPrint("AuthProvider: All master data loaded from local DB cache.");
  }

  // --- Methods for UI interaction ---

  /// Handles the login process, saving session data and triggering a full data sync.
  Future<void> login(String token, Map<String, dynamic> profile) async {
    _jwtToken = token;
    _userEmail = profile['email'];
    _profileData = profile;

    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(tokenKey, token);
    await prefs.setString(userEmailKey, _userEmail!);
    await prefs.setString(profileDataKey, jsonEncode(profile));
    await _dbHelper.saveProfile(profile);

    debugPrint('AuthProvider: Login successful. Session and profile persisted.');
    await syncAllData(forceRefresh: true);
  }

  Future<void> setProfileData(Map<String, dynamic> data) async {
    _profileData = data;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(profileDataKey, jsonEncode(data));
    await _dbHelper.saveProfile(data); // Also save to local DB
    notifyListeners();
  }

  Future<void> setLastSyncTimestamp(DateTime timestamp) async {
    _lastSyncTimestamp = timestamp;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setInt(lastSyncTimestampKey, timestamp.millisecondsSinceEpoch);
    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;
    _allUsers = null;
    _tarballStations = null;
    _manualStations = null;
    _tarballClassifications = null;
    _riverManualStations = null;
    _riverTriennialStations = null;
    _departments = null;
    _companies = null;
    _positions = null;
    _airClients = null;
    _airManualStations = null;

    // --- ADDED FOR STATE LIST ---
    _states = null;

    final prefs = await SharedPreferences.getInstance();
    await prefs.clear();
    await prefs.setBool(isFirstLoginKey, true);

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

  Future<Map<String, dynamic>> resetPassword(String email) {
    return _apiService.post('auth/forgot-password', {'email': email});
  }
}