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

public class FlexibleTypeConverter<T> : JsonConverter<T>
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // Type 'T'에 따라 각 JSON 토큰 타입에 맞춰서 변환 시도
        switch (reader.TokenType)
        {
            case JsonTokenType.String:
                var strValue = reader.GetString();

                if (typeof(T) == typeof(int) && int.TryParse(strValue, out var intValue))
                    return (T)(object)intValue;

                if (typeof(T) == typeof(long) && long.TryParse(strValue, out var longValue))
                    return (T)(object)longValue;

                if (typeof(T) == typeof(double) && double.TryParse(strValue, out var doubleValue))
                    return (T)(object)doubleValue;

                if (typeof(T) == typeof(bool) && bool.TryParse(strValue, out var boolValue))
                    return (T)(object)boolValue;

                if (typeof(T) == typeof(string))
                    return (T)(object)strValue;

                break;

            case JsonTokenType.Number:
                if (typeof(T) == typeof(int))
                    return (T)(object)reader.GetInt32();

                if (typeof(T) == typeof(long))
                    return (T)(object)reader.GetInt64();

                if (typeof(T) == typeof(double))
                    return (T)(object)reader.GetDouble();

                break;

            case JsonTokenType.True:
            case JsonTokenType.False:
                if (typeof(T) == typeof(bool))
                    return (T)(object)reader.GetBoolean();
                break;

            case JsonTokenType.Null:
                if (typeToConvert.IsClass) return default;
                throw new JsonException($"Cannot convert null to type '{typeof(T)}'.");
        }

        throw new JsonException($"Unable to convert JSON token to type '{typeof(T)}'.");
    }

    public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        // Type 'T'에 따라 JSON 타입에 맞춰서 기록
        if (value == null)
        {
            writer.WriteNullValue();
            return;
        }

        switch (value)
        {
            case int intValue:
                writer.WriteNumberValue(intValue);
                break;

            case long longValue:
                writer.WriteNumberValue(longValue);
                break;

            case double doubleValue:
                writer.WriteNumberValue(doubleValue);
                break;

            case bool boolValue:
                writer.WriteBooleanValue(boolValue);
                break;

            case string stringValue:
                writer.WriteStringValue(stringValue);
                break;

            default:
                throw new JsonException($"Unsupported type '{typeof(T)}'.");
        }
    }
}