import 'dart:async';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../models/message.dart';
import '../../services/message_service.dart';
import '../../repositories/message_repository.dart';
import 'message_event.dart';
import 'message_state.dart';

class MessageBloc extends Bloc<MessageEvent, MessageState> {
  final MessageService _messageService;
  StreamSubscription<List<Message>>? _messagesSubscription;

  MessageBloc({MessageService? messageService})
      : _messageService = messageService ?? MessageService(
          messageRepository: MessageRepository(),
        ),
        super(MessageInitial()) {
    on<LoadMessages>(_onLoadMessages);
    on<SendMessage>(_onSendMessage);
    on<DeleteMessage>(_onDeleteMessage);
    on<UpdateMessage>(_onUpdateMessage);
    on<ReactToMessage>(_onReactToMessage);
    on<RemoveReaction>(_onRemoveReaction);
    on<_MessagesUpdated>(_onMessagesUpdated);
  }

  Future<void> _onLoadMessages(
    LoadMessages event,
    Emitter<MessageState> emit,
  ) async {
    emit(MessageLoading());

    await _messagesSubscription?.cancel();

    _messagesSubscription = _messageService
        .getMessagesStream(event.groupId)
        .listen(
          (messages) {
            add(_MessagesUpdated(messages: messages, groupId: event.groupId));
          },
          onError: (error) {
            add(_MessagesError('Erreur lors du chargement des messages: $error'));
          },
        );
  }

  void _onMessagesUpdated(
    _MessagesUpdated event,
    Emitter<MessageState> emit,
  ) {
    emit(MessagesLoaded(messages: event.messages, groupId: event.groupId));
  }

  Future<void> _onSendMessage(
    SendMessage event,
    Emitter<MessageState> emit,
  ) async {
    try {
      // Juste effectuer l'action, le stream mettra à jour
      await _messageService.sendMessage(
        groupId: event.groupId,
        text: event.text,
        senderId: event.senderId,
        senderName: event.senderName,
      );
    } catch (e) {
      emit(MessageError('Erreur lors de l\'envoi du message: $e'));
    }
  }

  Future<void> _onDeleteMessage(
    DeleteMessage event,
    Emitter<MessageState> emit,
  ) async {
    try {
      // Ne pas émettre d'état, juste effectuer l'action
      // Le stream Firestore mettra à jour automatiquement
      await _messageService.deleteMessage(
        groupId: event.groupId,
        messageId: event.messageId,
      );
    } catch (e) {
      emit(MessageError('Erreur lors de la suppression du message: $e'));
    }
  }

  Future<void> _onUpdateMessage(
    UpdateMessage event,
    Emitter<MessageState> emit,
  ) async {
    try {
      // Ne pas émettre d'état, juste effectuer l'action
      // Le stream Firestore mettra à jour automatiquement
      await _messageService.updateMessage(
        groupId: event.groupId,
        messageId: event.messageId,
        newText: event.newText,
      );
    } catch (e) {
      emit(MessageError('Erreur lors de la modification du message: $e'));
    }
  }

  Future<void> _onReactToMessage(
    ReactToMessage event,
    Emitter<MessageState> emit,
  ) async {
    try {
      // Ne pas émettre d'état, juste effectuer l'action
      // Le stream Firestore mettra à jour automatiquement
      await _messageService.reactToMessage(
        groupId: event.groupId,
        messageId: event.messageId,
        userId: event.userId,
        reaction: event.reaction,
      );
    } catch (e) {
      emit(MessageError('Erreur lors de l\'ajout de la réaction: $e'));
    }
  }

  Future<void> _onRemoveReaction(
    RemoveReaction event,
    Emitter<MessageState> emit,
  ) async {
    try {
      // Ne pas émettre d'état, juste effectuer l'action
      // Le stream Firestore mettra à jour automatiquement
      await _messageService.removeReaction(
        groupId: event.groupId,
        messageId: event.messageId,
        userId: event.userId,
      );
    } catch (e) {
      emit(MessageError('Erreur lors de la suppression de la réaction: $e'));
    }
  }

  @override
  Future<void> close() {
    _messagesSubscription?.cancel();
    return super.close();
  }
}

// Events internes
class _MessagesUpdated extends MessageEvent {
  final List<Message> messages;
  final String groupId;

  const _MessagesUpdated({
    required this.messages,
    required this.groupId,
  });

  @override
  List<Object?> get props => [messages, groupId];
}

class _MessagesError extends MessageEvent {
  final String error;

  const _MessagesError(this.error);

  @override
  List<Object?> get props => [error];
}
