// Version: 1.2.0 | Created: 2026-04-01 | Updated: 2026-04-02
// SpacesRepository — builds space list and child rooms from the Matrix SDK.
// A space is a room where isSpace == true.

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 '../domain/space_model.dart';

part 'spaces_repository.g.dart';

@riverpod
SpacesRepository spacesRepository(Ref ref) {
  return SpacesRepository(client: ref.watch(matrixClientProvider));
}

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

  final Client _client;

  /// Returns all rooms that are spaces.
  List<SpaceModel> getSpaces() {
    return _client.rooms.where((r) => r.isSpace).map(_toSpaceModel).toList();
  }

  /// Returns child rooms within [spaceId] that the client is a member of.
  ///
  /// SpaceChild gives us the roomId only. We look up the Room from the client
  /// to get display name and avatar. If the child room is not in the client's
  /// room list (not joined), it is omitted.
  List<SpaceRoomModel> getRoomsInSpace(String spaceId) {
    final space = _client.getRoomById(spaceId);
    if (space == null || !space.isSpace) return [];

    final result = <SpaceRoomModel>[];
    for (final child in space.spaceChildren) {
      final childRoomId = child.roomId;
      if (childRoomId == null) continue;

      final room = _client.getRoomById(childRoomId);
      if (room == null) continue; // not joined — skip

      result.add(
        SpaceRoomModel(
          id: room.id,
          displayName: room.getLocalizedDisplayname(),
          avatarUrl: resolveMxcUrl(_client, room.avatar),
          isDirect: room.isDirectChat,
        ),
      );
    }
    return result;
  }

  /// Stream that emits on every sync so the UI stays current.
  Stream<List<SpaceModel>> watchSpaces() async* {
    yield getSpaces();
    yield* _client.onSync.stream.map((_) => getSpaces());
  }

  SpaceModel _toSpaceModel(Room room) {
    return SpaceModel(
      id: room.id,
      displayName: room.getLocalizedDisplayname(),
      avatarUrl: resolveMxcUrl(_client, room.avatar),
      roomCount: room.spaceChildren.length,
    );
  }
}
