import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import '../models/user_model.dart';
import '../models/role_model.dart';
import '../models/notification_preferences_model.dart';
import '../utils/firebase_storage_manager.dart';
import '../services/api_service.dart';
import '../services/data_service.dart';
import '../utils/performance_monitor.dart';

class LocalUserProvider with ChangeNotifier {
  UserModel? _currentUser;
  RoleModel? _currentRole;
  FirebaseAuth? _auth;
  final FirebaseStorageManager _storageManager = FirebaseStorageManager();
  final DataService _dataService = DataService(apiService);

  bool _isLoadingUserData = false;
  DateTime? _lastUserDataLoad;

  UserModel? get currentUser => _currentUser;
  String? get uid => _currentUser?.uid;
  String? get firstName => _currentUser?.firstName;
  String? get lastName => _currentUser?.lastName;
  String? get role => _currentUser?.role ?? 'USER';
  String? get profilePhotoUrl => _currentUser?.profilePhotoUrl;
  String? get email => _currentUser?.email;
  String? get phoneNumber => _currentUser?.phoneNumber;
  RoleModel? get currentRole => _currentRole;
  List<String> get permissions => _currentRole?.permissions ?? [];
  bool get isLoadingUserData => _isLoadingUserData;

  /// Vérifie si les données utilisateur doivent être rechargées
  bool _shouldReloadUserData() {
    if (_currentUser == null) return true;
    if (_lastUserDataLoad == null) return true;

    final now = DateTime.now();
    final difference = now.difference(_lastUserDataLoad!);
    return difference.inMinutes > 5; // Cache de 5 minutes pour les données utilisateur
  }

  /// Charge les données de l'utilisateur actuel via Cloud Function
  Future<void> loadUserData({bool forceReload = false}) async {
    // Si FirebaseAuth n'est pas encore disponible
    final FirebaseAuth auth;
    try {
      auth = _getAuthInstance();
    } catch (e) {
      print('Auth instance not ready in loadUserData: $e');
      return;
    }

    if (auth.currentUser == null) {
      print('No current user in Auth');
      return;
    }

    // Bootstrap léger : rendre l'UID disponible tout de suite pour les écrans
    // qui en ont besoin, même si le profil complet n'est pas encore chargé.
    if (_currentUser == null) {
      final firebaseUser = auth.currentUser!;
      _currentUser = UserModel(
        uid: firebaseUser.uid,
        email: firebaseUser.email ?? '',
        firstName: '',
        lastName: '',
        role: 'USER',
        phoneNumber: '',
        profilePhotoUrl: firebaseUser.photoURL ?? '',
      );
      _currentRole = RoleModel(
        id: 'USER',
        name: '',
        permissions: const [],
      );
      notifyListeners();
    }

    // Éviter les rechargements inutiles
    if (!forceReload && !_shouldReloadUserData()) {
      print('Using cached user data');
      return;
    }

    // Éviter les appels simultanés
    if (_isLoadingUserData) {
      print('User data already loading, skipping');
      return;
    }

    _isLoadingUserData = true;
    PerformanceMonitor.start('LocalUserProvider.loadUserData');
    print('Loading user data for: ${_auth!.currentUser!.uid}');
    try {
      // Utiliser la Cloud Function getCurrentUser
      PerformanceMonitor.start('LocalUserProvider.getCurrentUser_API');
      final result = await apiService.call('getCurrentUser', {});
      PerformanceMonitor.end('LocalUserProvider.getCurrentUser_API');

      final userData = result['user'] as Map<String, dynamic>;

      print('User data loaded from API: ${userData['uid']}');

      // Extraire le rôle
      final roleData = userData['role'] as Map<String, dynamic>?;
      if (roleData != null) {
        _currentRole = RoleModel.fromMap(roleData, roleData['id'] as String);
      }

      // Créer le UserModel
      _currentUser = UserModel(
        uid: userData['uid'] as String,
        email: userData['email'] as String? ?? '',
        firstName: userData['firstName'] as String? ?? '',
        lastName: userData['lastName'] as String? ?? '',
        role: roleData?['id'] as String? ?? 'USER',
        phoneNumber: userData['phoneNumber'] as String? ?? '',
        profilePhotoUrl: userData['profilePhotoUrl'] as String? ?? '',
      );

      print('User data loaded successfully');
      _lastUserDataLoad = DateTime.now();
      _isLoadingUserData = false;
      notifyListeners();
      PerformanceMonitor.end('LocalUserProvider.loadUserData');
    } catch (e) {
      print('Error loading user data: $e');
      _isLoadingUserData = false;
      PerformanceMonitor.end('LocalUserProvider.loadUserData');
      rethrow;
    }
  }

  /// Met à jour l'utilisateur
  void setUser(UserModel user) {
    _currentUser = user;
    notifyListeners();
  }

  /// Efface les données utilisateur
  void clearUser() {
    _currentUser = null;
    _currentRole = null;
    _lastUserDataLoad = null;
    _isLoadingUserData = false;
    notifyListeners();
  }

  /// Mise à jour des informations utilisateur via Cloud Function
  Future<void> updateUserData({
    String? firstName,
    String? lastName,
    String? phoneNumber,
  }) async {
    if (_currentUser == null) return;
    try {
      await _dataService.updateUser(
        _currentUser!.uid,
        {
          'firstName': firstName ?? _currentUser!.firstName,
          'lastName': lastName ?? _currentUser!.lastName,
          'phoneNumber': phoneNumber ?? _currentUser!.phoneNumber,
        },
      );

      _currentUser = _currentUser!.copyWith(
        firstName: firstName,
        lastName: lastName,
        phoneNumber: phoneNumber,
      );
      notifyListeners();
    } catch (e) {
      debugPrint('Erreur mise à jour utilisateur : $e');
      rethrow;
    }
  }

  /// Mise à jour des préférences de notifications
  Future<void> updateNotificationPreferences(NotificationPreferences preferences) async {
    if (_currentUser == null) return;
    try {
      await _dataService.updateUser(
        _currentUser!.uid,
        {
          'notificationPreferences': preferences.toMap(),
        },
      );

      _currentUser = _currentUser!.copyWith(notificationPreferences: preferences);
      notifyListeners();
    } catch (e) {
      debugPrint('Erreur mise à jour préférences notifications : $e');
      rethrow;
    }
  }

  /// Changement de photo de profil
  Future<void> changeProfilePicture(XFile image) async {
    if (_currentUser == null) return;
    try {
      String? newProfilePhotoUrl = await _storageManager.sendProfilePicture(
        imageFile: image,
        uid: _currentUser!.uid,
      );
      if (newProfilePhotoUrl != null) {
        // Mettre à jour via Cloud Function
        await _dataService.updateUser(
          _currentUser!.uid,
          {'profilePhotoUrl': newProfilePhotoUrl},
        );

        _currentUser = _currentUser!.copyWith(profilePhotoUrl: newProfilePhotoUrl);
        notifyListeners();
      }
    } catch (e) {
      debugPrint('Erreur mise à jour photo de profil : $e');
      rethrow;
    }
  }

  /// Connexion
  Future<UserCredential> signInWithEmailAndPassword(
      String email, String password) async {
    try {
      final auth = _getAuthInstance();
      UserCredential userCredential = await auth.signInWithEmailAndPassword(
          email: email, password: password);
      // Note: loadUserData() sera appelé en arrière-plan dans main.dart
      // pour ne pas bloquer la navigation
      return userCredential;
    } catch (e) {
      throw FirebaseAuthException(code: 'login-failed', message: e.toString());
    }
  }

  /// Déconnexion
  Future<void> signOut() async {
    try {
      final auth = _getAuthInstance();
      await auth.signOut();
    } catch (e) {
      debugPrint('Error during signOut: $e');
    }
    clearUser();
  }

  FirebaseAuth _getAuthInstance() {
    try {
      _auth ??= FirebaseAuth.instance;
      return _auth!;
    } catch (e, st) {
      debugPrint('[LocalUserProvider] FirebaseAuth.instance access error: $e\n$st');
      throw Exception('FirebaseAuth not available');
    }
  }

  /// Vérifie si l'utilisateur a une permission spécifique
  bool hasPermission(String permission) {
    return _currentRole?.permissions.contains(permission) ?? false;
  }

  /// Vérifie si l'utilisateur a toutes les permissions données
  bool hasAllPermissions(List<String> permissions) {
    if (_currentRole == null) return false;
    return permissions.every((p) => _currentRole!.permissions.contains(p));
  }

  /// Vérifie si l'utilisateur a au moins une des permissions données
  bool hasAnyPermission(List<String> permissions) {
    if (_currentRole == null) return false;
    return permissions.any((p) => _currentRole!.permissions.contains(p));
  }
}
