import 'package:json_annotation/json_annotation.dart';

part 'room.g.dart';

@JsonSerializable()
class CreateRoomRequest {
  final bool success;
  CreateRoomRequest({required this.success});
  factory CreateRoomRequest.fromJson(Map<String, dynamic> json) => _$CreateRoomRequestFromJson(json);

  Map<String, dynamic> toJson() => _$CreateRoomRequestToJson(this);
}

@JsonSerializable()
class CreateRoomResponse {
  final bool success;
  final String? roomCode;
  final String? error;

  CreateRoomResponse({required this.success, required this.roomCode, this.error});

  factory CreateRoomResponse.fromJson(Map<String, dynamic> json) => _$CreateRoomResponseFromJson(json);

  Map<String, dynamic> toJson() => _$CreateRoomResponseToJson(this);
}

sealed class GameRoomMessage {
  const GameRoomMessage();

  factory GameRoomMessage.fromJson(Map<String, dynamic> json) {
    return switch (json['type']) {
      'ping' => PingMessage.fromJson(json),
      'playerVote' => PlayerVoteMessage.fromJson(json),
      _ => throw Exception('Unknown message type'),
    };
  }

  Map<String, dynamic> toJson();
}

class PingMessage extends GameRoomMessage {
  final DateTime timestamp;

  const PingMessage({required this.timestamp});

  factory PingMessage.fromJson(Map<String, dynamic> json) =>
      PingMessage(timestamp: DateTime.parse(json['timestamp'] as String));

  @override
  Map<String, dynamic> toJson() => {
        'type': 'ping',
        'timestamp': timestamp.toIso8601String(),
      };
}

class PlayerVoteMessage extends GameRoomMessage {
  final String playerUuid;
  final int vote;

  const PlayerVoteMessage({required this.playerUuid, required this.vote});

  factory PlayerVoteMessage.fromJson(Map<String, dynamic> json) => PlayerVoteMessage(
        playerUuid: json['playerUuid'] as String,
        vote: json['vote'] as int,
      );

  @override
  Map<String, dynamic> toJson() => {
        'type': 'playerVote',
        'playerUuid': playerUuid,
        'vote': vote,
      };
}