import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hl_lieferservice/domain/entity/car.dart'; import 'package:hl_lieferservice/domain/repository/cars_repository.dart'; import 'package:hl_lieferservice/widget/operations/bloc/operation_bloc.dart'; import 'package:hl_lieferservice/widget/operations/bloc/operation_event.dart'; import 'cars_event.dart'; import 'cars_state.dart'; /// Bloc für die Fahrzeugverwaltung des angemeldeten Fahrers. /// /// `personalnummer`/`teamId` wird **nicht mehr** in den Events /// übergeben — der Account kommt serverseitig aus dem JWT. /// Session-Expiry geht über den globalen Provider-Stream /// (KeycloakOidcTokenProvider → AuthSessionExpired), nicht über /// dieses Bloc. class CarsBloc extends Bloc { CarsBloc({required this.repository, required this.opBloc}) : super(const CarsInitial()) { on(_handleLoad); on(_handleAdd); on(_handleEdit); on(_handleDeactivate); } final CarsRepository repository; final OperationBloc opBloc; Future _handleLoad(CarLoad event, Emitter emit) async { if (state is CarsLoaded && !event.force) return; emit(const CarsLoading()); try { final cars = await repository.listMine(); emit(CarsLoaded(cars: cars)); } on CarsRepositoryException catch (e) { emit(CarsLoadingFailed(message: e.message)); } catch (_) { emit(const CarsLoadingFailed()); } } Future _handleAdd(CarAdd event, Emitter emit) async { final current = state; opBloc.add(StartOperation()); try { final created = await repository.create(plate: event.plate); if (current is CarsLoaded) { emit(current.copyWith(cars: [...current.cars, created])); } opBloc.add(FinishOperation(message: "Fahrzeug hinzugefügt")); } on CarsRepositoryException catch (e) { opBloc.add(FailOperation(message: e.message)); } catch (_) { opBloc.add( FailOperation(message: "Fehler beim Anlegen eines Fahrzeugs"), ); } } Future _handleEdit(CarEdit event, Emitter emit) async { final current = state; opBloc.add(StartOperation()); try { final updated = await repository.update( carId: event.carId, plate: event.plate, active: event.active, ); _emitReplaced(current, updated, emit); opBloc.add(FinishOperation(message: "Fahrzeug aktualisiert")); } on CarsRepositoryException catch (e) { opBloc.add(FailOperation(message: e.message)); } catch (_) { opBloc.add( FailOperation(message: "Fehler beim Aktualisieren des Fahrzeugs"), ); } } Future _handleDeactivate( CarDeactivate event, Emitter emit, ) async { final current = state; opBloc.add(StartOperation()); try { await repository.update(carId: event.carId, active: false); if (current is CarsLoaded) { // Inaktive Fahrzeuge raus aus der UI-Liste — die Liste zeigt // nur aktive (Default). emit( current.copyWith( cars: current.cars .where((c) => c.id != event.carId) .toList(growable: false), ), ); } opBloc.add(FinishOperation(message: "Fahrzeug deaktiviert")); } on CarsRepositoryException catch (e) { opBloc.add(FailOperation(message: e.message)); } catch (_) { opBloc.add( FailOperation(message: "Fehler beim Deaktivieren des Fahrzeugs"), ); } } void _emitReplaced( CarsState current, Car updated, Emitter emit, ) { if (current is! CarsLoaded) return; emit( current.copyWith( cars: current.cars .map((c) => c.id == updated.id ? updated : c) .toList(growable: false), ), ); } }