import 'dart:async';
import 'dart:convert';

import 'package:frontend/providers/web_socket.dart';
import 'package:logging/logging.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:shared_models/room.dart';

part 'game_messages.g.dart';

final _logger = Logger('GameMessageNotifier');

@riverpod
class GameMessageNotifier extends _$GameMessageNotifier {
  StreamSubscription<GameRoomMessage?>? _sub;

  @override
  Stream<GameRoomMessage?> build() {
    final Stream<dynamic>? stream = ref.watch(webSocketStreamProvider);
    if (stream == null) {
      return Stream.empty();
    }

    final Stream<GameRoomMessage?> gameRoomStream = stream.map((message) {
      try {
        if (message is String) {
          return GameRoomMessage.fromJson(jsonDecode(message) as Map<String, dynamic>);
        } else {
          _logger.info('Recieved non-string message in socket: $message');
          return null;
        }
      } catch (e) {
        _logger.severe('Error parsing message: Type `${message.runtimeType}` $message', e, StackTrace.current);
        return null;
      }
    });
    _sub = gameRoomStream.listen(
      (event) => state = AsyncValue.data(event),
    );
    return gameRoomStream;
  }

  // Cancel the gameroom stream subscription
  void close() {
    _sub?.cancel();
  }
}