using System;
using System.Collections.Generic;
using InABox.Core;

namespace InABox.Rpc
{
    public class RpcSaveResult : IRpcCommandResult
    {
        
        public Type Type { get; set; }
        public Dictionary<string, object?>[] Deltas { get; set; }

        public RpcSaveResult()
        {
            Deltas = Array.Empty<Dictionary<string, object?>>();
        }
        
        public void SerializeBinary(CoreBinaryWriter writer)
        {
            writer.Write(Type.EntityName());
            writer.Write(Deltas.Length);
            foreach (var delta in Deltas)
            {
                writer.Write(delta.Count);
                foreach (var (key, value) in delta)
                {
                    writer.Write(key);
                    var prop = DatabaseSchema.Property(Type, key);
                    //var prop = CoreUtils.GetProperty(Type, key);
                    writer.WriteBinaryValue(prop?.PropertyType ?? typeof(object), value);
                }
            }
        }

        public void DeserializeBinary(CoreBinaryReader reader)
        {
            var deltas = new List<Dictionary<string, object?>>();

            var typename = reader.ReadString();
            Type = CoreUtils.GetEntity(typename);

            var deltacount = reader.ReadInt32();
            for (int iDelta = 0; iDelta < deltacount; iDelta++)
            {
                var delta = new Dictionary<string, object?>();
                var keycount = reader.ReadInt32();
                for (int iKey = 0; iKey < keycount; iKey++)
                {
                    var key = reader.ReadString();
                    var prop = DatabaseSchema.Property(Type, key);
                    //var prop = CoreUtils.GetProperty(Type, key);
                    var value = reader.ReadBinaryValue(prop?.PropertyType ?? typeof(object));
                    delta[key] = value;
                }
                deltas.Add(delta);
            }
            Deltas = deltas.ToArray();
        }

        public string? FullDescription() => null;
    }
}