89 lines
2.8 KiB
Dart
89 lines
2.8 KiB
Dart
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<AuthEvent, AuthState> {
|
|
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<AuthSessionCheckRequested>(_onSessionCheckRequested);
|
|
on<AuthLoginRequested>(_onLoginRequested);
|
|
on<AuthLogoutRequested>(_onLogoutRequested);
|
|
}
|
|
|
|
/// Verifica si hay sesión activa al iniciar la app.
|
|
Future<void> _onSessionCheckRequested(
|
|
AuthSessionCheckRequested event,
|
|
Emitter<AuthState> 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<void> _onLoginRequested(
|
|
AuthLoginRequested event,
|
|
Emitter<AuthState> 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<void> _onLogoutRequested(
|
|
AuthLogoutRequested event,
|
|
Emitter<AuthState> emit,
|
|
) async {
|
|
emit(const AuthLoading());
|
|
try {
|
|
await _logoutUseCase.execute();
|
|
} finally {
|
|
// Siempre transiciona a no autenticado, incluso si falla la limpieza
|
|
emit(const AuthUnauthenticated());
|
|
}
|
|
}
|
|
}
|