/// BLoC de gestion de la messagerie
library messaging_bloc;

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart';
import '../../domain/usecases/get_conversations.dart';
import '../../domain/usecases/get_messages.dart';
import '../../domain/usecases/send_message.dart';
import '../../domain/usecases/send_broadcast.dart';
import 'messaging_event.dart';
import 'messaging_state.dart';

@injectable
class MessagingBloc extends Bloc<MessagingEvent, MessagingState> {
  final GetConversations getConversations;
  final GetMessages getMessages;
  final SendMessage sendMessage;
  final SendBroadcast sendBroadcast;

  MessagingBloc({
    required this.getConversations,
    required this.getMessages,
    required this.sendMessage,
    required this.sendBroadcast,
  }) : super(MessagingInitial()) {
    on<LoadConversations>(_onLoadConversations);
    on<LoadMessages>(_onLoadMessages);
    on<SendMessageEvent>(_onSendMessage);
    on<SendBroadcastEvent>(_onSendBroadcast);
  }

  Future<void> _onLoadConversations(
    LoadConversations event,
    Emitter<MessagingState> emit,
  ) async {
    emit(MessagingLoading());

    final result = await getConversations(
      organizationId: event.organizationId,
      includeArchived: event.includeArchived,
    );

    result.fold(
      (failure) => emit(MessagingError(failure.message)),
      (conversations) => emit(ConversationsLoaded(conversations: conversations)),
    );
  }

  Future<void> _onLoadMessages(
    LoadMessages event,
    Emitter<MessagingState> emit,
  ) async {
    emit(MessagingLoading());

    final result = await getMessages(
      conversationId: event.conversationId,
      limit: event.limit,
      beforeMessageId: event.beforeMessageId,
    );

    result.fold(
      (failure) => emit(MessagingError(failure.message)),
      (messages) => emit(MessagesLoaded(
        conversationId: event.conversationId,
        messages: messages,
        hasMore: messages.length == (event.limit ?? 50),
      )),
    );
  }

  Future<void> _onSendMessage(
    SendMessageEvent event,
    Emitter<MessagingState> emit,
  ) async {
    final result = await sendMessage(
      conversationId: event.conversationId,
      content: event.content,
      attachments: event.attachments,
      priority: event.priority,
    );

    result.fold(
      (failure) => emit(MessagingError(failure.message)),
      (message) => emit(MessageSent(message)),
    );
  }

  Future<void> _onSendBroadcast(
    SendBroadcastEvent event,
    Emitter<MessagingState> emit,
  ) async {
    final result = await sendBroadcast(
      organizationId: event.organizationId,
      subject: event.subject,
      content: event.content,
      priority: event.priority,
      attachments: event.attachments,
    );

    result.fold(
      (failure) => emit(MessagingError(failure.message)),
      (message) => emit(BroadcastSent(message)),
    );
  }
}
