import 'package:flutter_bloc/flutter_bloc.dart'; import '../../data/repositories/auth_repository_impl.dart'; import '../../domain/usecases/auth_usecases.dart'; import 'auth_event.dart'; import 'auth_state.dart'; /// BLoC principal de autenticación. /// /// Gestiona el ciclo de vida completo de la identidad del usuario: /// verificación de sesión persistida → login → sesión activa → logout. /// /// El token JWT simulado se almacena en el estado [AuthAuthenticated] /// y estará disponible para inyectarse en headers HTTP en fases futuras. class AuthBloc extends Bloc { final LoginUseCase _loginUseCase; final LogoutUseCase _logoutUseCase; final GetStoredSessionUseCase _getStoredSessionUseCase; AuthBloc({ required LoginUseCase loginUseCase, required LogoutUseCase logoutUseCase, required GetStoredSessionUseCase getStoredSessionUseCase, }) : _loginUseCase = loginUseCase, _logoutUseCase = logoutUseCase, _getStoredSessionUseCase = getStoredSessionUseCase, super(const AuthInitial()) { on(_onSessionCheckRequested); on(_onLoginRequested); on(_onLogoutRequested); } /// Verifica si hay sesión activa al iniciar la app. Future _onSessionCheckRequested( AuthSessionCheckRequested event, Emitter emit, ) async { emit(const AuthCheckingSession()); try { final user = await _getStoredSessionUseCase.execute(); if (user != null) { emit(AuthAuthenticated(user: user)); } else { emit(const AuthUnauthenticated()); } } catch (_) { emit(const AuthUnauthenticated()); } } /// Procesa la solicitud de login con las credenciales del usuario. Future _onLoginRequested( AuthLoginRequested event, Emitter emit, ) async { emit(const AuthLoading()); try { final user = await _loginUseCase.execute( identifier: event.identifier, password: event.password, ); emit(AuthAuthenticated(user: user)); } on AuthException catch (e) { emit(AuthFailure(message: e.message, errorCode: e.code)); } on ArgumentError catch (e) { emit(AuthFailure(message: e.message.toString())); } catch (e) { emit(const AuthFailure( message: 'Error inesperado. Por favor intenta de nuevo.', errorCode: 'UNKNOWN', )); } } /// Cierra la sesión y limpia el estado local. Future _onLogoutRequested( AuthLogoutRequested event, Emitter emit, ) async { emit(const AuthLoading()); try { await _logoutUseCase.execute(); } finally { // Siempre transiciona a no autenticado, incluso si falla la limpieza emit(const AuthUnauthenticated()); } } }