// Version: 1.1.0 | Created: 2026-04-01
// Riverpod providers for chat timeline, send, upload, react, reply.

import 'package:matrix/matrix.dart' show MatrixFile;
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../data/chat_repository.dart';
import '../domain/message_model.dart';

part 'chat_controller.g.dart';

/// Streams the message list for [roomId].
@riverpod
Stream<List<MessageModel>> chatTimeline(Ref ref, String roomId) {
  final repo = ref.watch(chatRepositoryProvider);
  return repo.watchTimeline(roomId);
}

/// Sends a text message. Returns an error string on failure, null on success.
/// Also handles sending replies when [inReplyToEventId] is set.
@riverpod
class SendMessage extends _$SendMessage {
  @override
  bool build() => false; // isSending

  Future<String?> send(
    String roomId,
    String text, {
    String? inReplyToEventId,
  }) async {
    if (text.trim().isEmpty) return null;
    state = true;
    try {
      await ref
          .read(chatRepositoryProvider)
          .sendTextMessage(roomId, text, inReplyToEventId: inReplyToEventId);
      return null;
    } on Exception catch (e) {
      return e.toString();
    } finally {
      state = false;
    }
  }
}

/// Uploads a file and sends it as a room message.
/// State: null = idle, empty string = uploading, non-empty = error message.
@riverpod
class UploadFile extends _$UploadFile {
  @override
  String? build() => null; // null = idle

  Future<void> upload(String roomId, MatrixFile file) async {
    state = ''; // uploading
    try {
      await ref.read(chatRepositoryProvider).sendFile(roomId, file);
      state = null; // success — back to idle
    } on Exception catch (e) {
      state = e.toString(); // error
    }
  }

  void clearError() => state = null;
}

/// Sends an emoji reaction to [eventId].
@riverpod
class SendReaction extends _$SendReaction {
  @override
  bool build() => false;

  Future<String?> react(String roomId, String eventId, String emoji) async {
    state = true;
    try {
      await ref
          .read(chatRepositoryProvider)
          .sendReaction(roomId, eventId, emoji);
      return null;
    } on Exception catch (e) {
      return e.toString();
    } finally {
      state = false;
    }
  }
}

/// Deletes (redacts) a message by eventId.
@riverpod
class DeleteMessage extends _$DeleteMessage {
  @override
  bool build() => false;

  Future<String?> delete(String roomId, String eventId) async {
    state = true;
    try {
      await ref.read(chatRepositoryProvider).redactEvent(roomId, eventId);
      return null;
    } on Exception catch (e) {
      return e.toString();
    } finally {
      state = false;
    }
  }
}
