import gleam/dict
import gleam/dynamic/decode
import gleam/int
import gleam/json
import player

pub type HostState {
  HostState(user_id: Int, game_id: String)
}

pub type HostClientMessages {
  ResetAllBuzers
  ResetPlayerBuzzer(user_id: Int)
  UpdateScore(user_id: Int, diff: Int)
  EndGame
}

pub fn host_client_messages_decoder() -> decode.Decoder(HostClientMessages) {
  use variant <- decode.field("type", decode.string)
  case variant {
    "ResetAllBuzers" -> decode.success(ResetAllBuzers)
    "ResetPlayerBuzzer" -> {
      use user_id <- decode.field("user_id", decode.int)
      decode.success(ResetPlayerBuzzer(user_id:))
    }
    "UpdateScore" -> {
      use user_id <- decode.field("user_id", decode.int)
      use diff <- decode.field("diff", decode.int)
      decode.success(UpdateScore(user_id:, diff:))
    }
    "EndGame" -> decode.success(EndGame)
    _ -> decode.failure(ResetAllBuzers, "HostClientMessages")
  }
}

pub type HostServerMessages {
  Ack
  UpdatePlayerStates(players: dict.Dict(Int, player.Player))
  ExitGame
}

pub fn encode_host_server_messages(
  host_server_messages: HostServerMessages,
) -> json.Json {
  case host_server_messages {
    Ack -> json.object([#("type", json.string("Ack"))])
    UpdatePlayerStates(..) ->
      json.object([
        #("type", json.string("UpdatePlayerStates")),
        #(
          "players",
          json.dict(
            host_server_messages.players,
            int.to_string,
            player.serialize,
          ),
        ),
      ])
    ExitGame -> json.object([#("type", json.string("ExitGame"))])
  }
}
