// Version: 1.3.0 | Created: 2026-04-01 | Updated: 2026-04-27
// Rooms repository. Reads room list from the Matrix SDK client.

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

import '../../../core/network/matrix_client.dart';
import '../../../shared/utils/mxc_url.dart';
import '../../../shared/utils/room_preview.dart';
import '../domain/room_model.dart';

part 'rooms_repository.g.dart';

@riverpod
RoomsRepository roomsRepository(Ref ref) {
  return RoomsRepository(client: ref.watch(matrixClientProvider));
}

class RoomsRepository {
  RoomsRepository({required Client client}) : _client = client;

  final Client _client;

  /// Returns the current room list, sorted unread-first then by last activity.
  List<RoomModel> getRooms() {
    final rooms = _client.rooms;
    final models = rooms.map(_toModel).toList();

    models.sort((a, b) {
      // Unread rooms first.
      if (a.unreadCount != b.unreadCount) {
        return b.unreadCount.compareTo(a.unreadCount);
      }
      // Then by most recent activity.
      final aTime = a.lastActivityAt ?? DateTime(0);
      final bTime = b.lastActivityAt ?? DateTime(0);
      return bTime.compareTo(aTime);
    });

    return models;
  }

  /// Emits current rooms immediately, then re-emits on every sync.
  /// Immediate yield prevents indefinite spinner while waiting for first sync.
  Stream<List<RoomModel>> watchRooms() async* {
    yield getRooms();
    yield* _client.onSync.stream.map((_) => getRooms());
  }

  RoomModel _toModel(Room room) {
    return RoomModel(
      id: room.id,
      displayName: room.getLocalizedDisplayname(),
      avatarUrl: resolveMxcUrl(_client, room.avatar),
      lastMessagePreview: lastMessagePreview(room),
      lastActivityAt: room.lastEvent?.originServerTs ?? room.timeCreated,
      unreadCount: room.notificationCount,
      isDirect: room.isDirectChat,
    );
  }
}
