/// BLoC pour la gestion du profil utilisateur library profile_bloc; import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:injectable/injectable.dart'; import 'package:dio/dio.dart'; import '../../domain/usecases/get_profile.dart'; import '../../domain/usecases/update_profile.dart'; import '../../domain/repositories/profile_repository.dart'; import '../../../members/data/models/membre_complete_model.dart'; part 'profile_event.dart'; part 'profile_state.dart'; /// BLoC pour la gestion du profil (Clean Architecture) @injectable class ProfileBloc extends Bloc { final GetProfile _getProfile; final UpdateProfile _updateProfile; final IProfileRepository _repository; // Pour méthodes non-couvertes (getProfileByEmail) ProfileBloc( this._getProfile, this._updateProfile, this._repository, ) : super(const ProfileInitial()) { on(_onLoadMe); on(_onLoadMyProfile); on(_onUpdateMyProfile); } /// Charge le profil du membre connecté Future _onLoadMe( LoadMe event, Emitter emit, ) async { try { emit(const ProfileLoading()); final membre = await _getProfile(); if (membre != null) { emit(ProfileLoaded(membre)); } else { emit(const ProfileNotFound()); } } on DioException catch (e) { emit(ProfileError(_networkErrorMessage(e))); } catch (e) { emit(ProfileError('Erreur lors du chargement du profil : $e')); } } /// Charge le profil par email (recherche) /// Note: Cette méthode utilise directement le repository car elle n'a pas de use case dédié Future _onLoadMyProfile( LoadMyProfile event, Emitter emit, ) async { try { emit(const ProfileLoading()); final membre = await _repository.getProfileByEmail(event.email); if (membre != null) { emit(ProfileLoaded(membre)); } else { emit(const ProfileNotFound()); } } on DioException catch (e) { emit(ProfileError(_networkErrorMessage(e))); } catch (e) { emit(ProfileError('Erreur lors du chargement du profil : $e')); } } /// Met à jour le profil Future _onUpdateMyProfile( UpdateMyProfile event, Emitter emit, ) async { final currentState = state; try { if (currentState is ProfileLoaded) { emit(ProfileUpdating(currentState.membre)); } final updated = await _updateProfile(event.membreId, event.membre); emit(ProfileUpdated(updated)); } on DioException catch (e) { if (currentState is ProfileLoaded) { emit(ProfileLoaded(currentState.membre)); } emit(ProfileError(_networkErrorMessage(e))); } catch (e) { emit(ProfileError('Erreur lors de la mise à jour du profil : $e')); } } String _networkErrorMessage(DioException e) { switch (e.type) { case DioExceptionType.connectionTimeout: case DioExceptionType.sendTimeout: case DioExceptionType.receiveTimeout: return 'Délai de connexion dépassé.'; case DioExceptionType.badResponse: final code = e.response?.statusCode; if (code == 401) return 'Non autorisé. Veuillez vous reconnecter.'; if (code == 403) return 'Accès refusé.'; if (code == 404) return 'Profil non trouvé.'; if (code != null && code >= 500) return 'Erreur serveur.'; return 'Erreur de communication avec le serveur.'; default: return 'Erreur réseau. Vérifiez votre connexion.'; } } }