using System.Text.Json;
using System.Text.Json.Serialization;

public sealed class BloodTypeJsonConverter : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert) =>
        typeToConvert == typeof(BloodType) || typeToConvert == typeof(BloodType?);

    public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
    {
        if (typeToConvert == typeof(BloodType))
            return new BloodTypeConverter();

        return new NullableBloodTypeConverter();
    }

    private sealed class BloodTypeConverter : JsonConverter<BloodType>
    {
        public override BloodType Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
            => DbStringEnumJson.Read(ref reader, BloodTypeExtensions.FromDbString);

        public override void Write(Utf8JsonWriter writer, BloodType value, JsonSerializerOptions options)
            => writer.WriteStringValue(value.ToDbString());
    }

    private sealed class NullableBloodTypeConverter : JsonConverter<BloodType?>
    {
        public override BloodType? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            if (reader.TokenType == JsonTokenType.Null)
                return null;

            return DbStringEnumJson.Read(ref reader, BloodTypeExtensions.FromDbString);
        }

        public override void Write(Utf8JsonWriter writer, BloodType? value, JsonSerializerOptions options)
        {
            if (value is null)
                writer.WriteNullValue();
            else
                writer.WriteStringValue(value.Value.ToDbString());
        }
    }
}
