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

namespace CounterDrone.Core.Reporting
{
    /// <summary>ReportBlock 多态序列化转换器</summary>
    public class ReportBlockConverter : JsonConverter<ReportBlock>
    {
        public override ReportBlock Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            using var doc = JsonDocument.ParseValue(ref reader);
            var root = doc.RootElement;
            if (!root.TryGetProperty("$blockType", out var typeProp))
                throw new JsonException("缺少 $blockType 字段");

            var typeName = typeProp.GetString();
            var rawText = root.GetRawText();
            return typeName switch
            {
                "KeyValueBlock" => JsonSerializer.Deserialize<KeyValueBlock>(rawText, options)!,
                "TableBlock" => JsonSerializer.Deserialize<TableBlock>(rawText, options)!,
                "TextBlock" => JsonSerializer.Deserialize<TextBlock>(rawText, options)!,
                _ => throw new JsonException($"未知的 block 类型: {typeName}"),
            };
        }

        public override void Write(Utf8JsonWriter writer, ReportBlock value, JsonSerializerOptions options)
        {
            writer.WriteStartObject();
            writer.WriteString("$blockType", value.GetType().Name);
            switch (value)
            {
                case KeyValueBlock kv:
                    writer.WriteString(nameof(kv.LabelHeader), kv.LabelHeader);
                    writer.WriteString(nameof(kv.ValueHeader), kv.ValueHeader);
                    writer.WritePropertyName(nameof(kv.Items));
                    JsonSerializer.Serialize(writer, kv.Items, options);
                    break;
                case TableBlock tb:
                    writer.WriteString(nameof(tb.Caption), tb.Caption);
                    writer.WritePropertyName(nameof(tb.Headers));
                    JsonSerializer.Serialize(writer, tb.Headers, options);
                    writer.WritePropertyName(nameof(tb.Rows));
                    JsonSerializer.Serialize(writer, tb.Rows, options);
                    break;
                case TextBlock text:
                    writer.WriteString(nameof(text.Text), text.Text);
                    writer.WriteBoolean(nameof(text.Bold), text.Bold);
                    break;
            }
            writer.WriteEndObject();
        }
    }
}
