using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; namespace PrizeSystem { public class PrizeConverter : JsonConverter { public override Prize ReadJson( JsonReader reader, Type objectType, Prize existingValue, bool hasExistingValue, JsonSerializer serializer) { JObject jsonObject = JObject.Load(reader); JToken prizeTypeToken = jsonObject["PrizeType"]; if (prizeTypeToken == null) throw new JsonSerializationException("Missing PrizeType field"); PrizeType prizeType = prizeTypeToken.ToObject(serializer); return prizeType switch { PrizeType.None => new EmptyPrize(), PrizeType.Qr => new QrPrize(jsonObject.Value("PrizeText") ?? string.Empty), PrizeType.VitrinaBox => new VitrinaPrize( jsonObject["Boxes"]?.ToObject(serializer) ?? Array.Empty()), PrizeType.Hopper or PrizeType.Ticket or PrizeType.Marbles => new CountablePrize( jsonObject["Type"]?.ToObject(serializer) ?? GetCountableType(prizeType), jsonObject.Value("Amount") ?? 0), _ => throw new NotSupportedException($"Unknown prize type: {prizeType}") }; } public override void WriteJson(JsonWriter writer, Prize value, JsonSerializer serializer) { writer.WriteStartObject(); WriteProperty(writer, serializer, "PrizeType", value.PrizeType); switch (value) { case CountablePrize countablePrize: WriteProperty(writer, serializer, "Type", countablePrize.Type); WriteProperty(writer, serializer, "Amount", countablePrize.Amount); break; case QrPrize qrPrize: WriteProperty(writer, serializer, "PrizeText", qrPrize.PrizeText); break; case VitrinaPrize vitrinaPrize: WriteProperty(writer, serializer, "Boxes", vitrinaPrize.Boxes); break; } writer.WriteEndObject(); } private static void WriteProperty( JsonWriter writer, JsonSerializer serializer, string propertyName, object value) { writer.WritePropertyName(propertyName); serializer.Serialize(writer, value); } private static CountablePrizeType GetCountableType(PrizeType prizeType) { return prizeType switch { PrizeType.Hopper => CountablePrizeType.Hopper, PrizeType.Ticket => CountablePrizeType.Ticket, PrizeType.Marbles => CountablePrizeType.Marbles, _ => CountablePrizeType.Hopper }; } } }