import 'package:riverpod_annotation/riverpod_annotation.dart'; import '../../../core/api/api_client.dart'; import '../domain/bracket.dart'; part 'brackets_repository.g.dart'; class BracketsRepository { BracketsRepository(this._api); final ApiClient _api; Future> fetchBrackets() async { final data = await _api.get('/brackets/index.php'); final list = (data['brackets'] as List?) ?? []; return list.whereType>().map(Bracket.fromJson).toList(); } Future getBracket(String id) async { try { final data = await _api.get('/brackets/detail.php', params: {'id': id}); return Bracket.fromJson(data); } on ApiException catch (e) { if (e.statusCode == 404) return null; rethrow; } } Future createBracket(Bracket bracket) async { final data = await _api.post('/brackets/index.php', bracket.toJson()); return data['id'] as String; } Future updateBracket(Bracket bracket) async { final data = await _api.put( '/brackets/detail.php', bracket.toJson(), params: {'id': bracket.id}, ); return Bracket.fromJson(data); } Future deleteBracket(String id) async { await _api.delete('/brackets/detail.php', params: {'id': id}); } Future updateMatch( String bracketId, String roundLabel, BracketMatch match, ) async { final bracket = await getBracket(bracketId); if (bracket == null) return; final rounds = bracket.rounds.map((round) { if (round.label != roundLabel) return round; final updatedMatches = round.matches .map((m) => m.id == match.id ? match : m) .toList(growable: false); return round.copyWith(matches: updatedMatches); }).toList(growable: false); await updateBracket(bracket.copyWith(rounds: rounds)); } Stream> watchBrackets() async* { yield await fetchBrackets(); await for (final _ in Stream.periodic(const Duration(seconds: 30))) { yield await fetchBrackets(); } } } @Riverpod(keepAlive: true) BracketsRepository bracketsRepository(BracketsRepositoryRef ref) { return BracketsRepository(ref.watch(apiClientProvider)); } @riverpod Stream> bracketsStream(BracketsStreamRef ref) { return ref.watch(bracketsRepositoryProvider).watchBrackets(); }