import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../domain/entities/chat.dart'; import '../../domain/entities/message.dart'; import '../../domain/repositories/chat_repository.dart'; import 'chat_event.dart'; import 'chat_state.dart'; class ChatBloc extends Bloc { final ChatRepository chatRepository; StreamSubscription? _messageSubscription; ChatBloc({required this.chatRepository}) : super(const ChatState.initial()) { on(_onStarted); on(_onChatsLoaded); on(_onChatSelected); on(_onMessagesRequested); on(_onMessageSent); on(_onFavoritesRequested); _messageSubscription = chatRepository.messageStream.listen((message) { // Handle real-time messages add(ChatEvent.messagesRequested(message.chatId)); }); } Future _onStarted(ChatEventStarted event, Emitter emit) async { // Start SignalR in background chatRepository.initSignalR().catchError((e) { // Log or handle SignalR init error }); // Immediately trigger chats loading add(const ChatEvent.chatsLoaded()); } Future _onChatsLoaded(ChatEventChatsLoaded event, Emitter emit) async { emit(const ChatState.loading()); final result = await chatRepository.getChats(currentUserId: event.currentUserId); result.fold( (error) => emit(ChatState.error(error.message ?? 'Failed to load chats')), (chats) => emit(ChatState.chatsLoaded(chats)), ); } Future _onChatSelected(ChatEventChatSelected event, Emitter emit) async { emit(const ChatState.loading()); final chatResult = await chatRepository.getChatById(event.chatId); final messagesResult = await chatRepository.getMessages(event.chatId); chatResult.fold( (error) => emit(ChatState.error(error.message ?? 'Failed to load chat')), (chat) { messagesResult.fold( (error) => emit(ChatState.chatSelected(chat, [])), (messages) => emit(ChatState.chatSelected(chat, messages)), ); }, ); } Future _onMessagesRequested(ChatEventMessagesRequested event, Emitter emit) async { final result = await chatRepository.getMessages(event.chatId); result.fold( (error) => emit(ChatState.error(error.message ?? 'Failed to load messages')), (messages) => emit(ChatState.messagesLoaded(messages)), ); } Future _onMessageSent(ChatEventMessageSent event, Emitter emit) async { final result = await chatRepository.sendMessage(event.chatId, event.content); result.fold( (error) => emit(ChatState.error(error.message ?? 'Failed to send message')), (_) => add(ChatEvent.messagesRequested(event.chatId)), ); } Future _onFavoritesRequested(ChatEventFavoritesRequested event, Emitter emit) async { emit(const ChatState.loading()); final result = await chatRepository.getOrCreateFavorites(); result.fold( (error) => emit(ChatState.error(error.message ?? 'Failed to open Favorites')), (chat) => add(ChatEvent.chatSelected(chat.id)), ); } @override Future close() { _messageSubscription?.cancel(); chatRepository.disposeSignalR(); return super.close(); } }