using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace AsbCloudWebApi.IntegrationTests.Converters;

public class ValidationResultConverter : JsonConverter<ValidationResult>
{
   public override ValidationResult Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
   {
      if (reader.TokenType != JsonTokenType.StartObject)
      {
         throw new JsonException("Expected the start of an object.");
      }

      string? errorMessage = null;
      List<string>? memberNames = null;

      while (reader.Read())
      {
         if (reader.TokenType == JsonTokenType.EndObject)
         {
            break;
         }

         if (reader.TokenType != JsonTokenType.PropertyName)
         {
            throw new JsonException($"Unexpected token type: {reader.TokenType}");
         }

         var propertyName = reader.GetString();
         reader.Read();

         switch (propertyName)
         {
            case "errorMessage":
               errorMessage = reader.GetString();
               break;
            case "memberNames":
               if (reader.TokenType != JsonTokenType.StartArray)
               {
                  throw new JsonException("Expected the start of an array for 'memberNames'.");
               }
               memberNames = new List<string>();
               while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
               {
                  memberNames.Add(reader.GetString() ?? string.Empty);
               }
               break;
            default:
               reader.Skip();
               break;
         }
      }

      if (errorMessage == null)
      {
         throw new JsonException("Missing 'errorMessage' property.");
      }

      return new ValidationResult(errorMessage, memberNames ?? Enumerable.Empty<string>());
   }

   public override void Write(Utf8JsonWriter writer, ValidationResult value, JsonSerializerOptions options)
   {
      throw new NotImplementedException();
   }
}