import 'dart:async';
import 'dart:isolate';

import 'package:logging/logging.dart';
import 'package:shared_models/room.dart';

class LiveGameRoomData {
  LiveGameRoomData({
    required this.wsSendPort,
    required this.roomUuid,
  });

  final SendPort wsSendPort;
  final String roomUuid;
}

class LiveGameRoom {
  LiveGameRoom({
    required this.receivePort,
    required this.wsSendPort,
    required this.logger,
    required this.streamSubscription,
    required this.roomUuid,
  });

  Timer? gameLoop;
  // final Map<String, PlayerState> players = {};
  final ReceivePort receivePort;
  final SendPort wsSendPort;
  final Logger logger;
  final StreamSubscription<dynamic> streamSubscription;
  final String roomUuid;

  static void spawn(LiveGameRoomData data) {
    // Create new isolate for this room
    // Return handle for communication
    final receivePort = ReceivePort();
    data.wsSendPort.send(receivePort.sendPort);
    final logger = Logger('LiveGameRoom-${data.roomUuid}');

    // ignore: cancel_subscriptions
    final streamSubscription = receivePort.listen(logger.info);

    LiveGameRoom(
      receivePort: receivePort,
      wsSendPort: data.wsSendPort,
      logger: logger,
      streamSubscription: streamSubscription,
      roomUuid: data.roomUuid,
    ).start();

    return;
  }

  void start() {
    gameLoop = Timer.periodic(const Duration(milliseconds: 3500), update);
  }

  void update(Timer timer) {
    logger.finest('Room $roomUuid tick: ${timer.tick}');
    wsSendPort.send(
      PingMessage.now(
        roomUuid,
        dest: PingDestination.client,
        userUuid: '',
      ),
    );
  }

  void close() {
    streamSubscription.cancel();
  }
}