using FLY.OBJComponents.IService;
using FLY.OBJComponents.OBJ_INTERFACE;
using FObjBase;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FLY.OBJComponents.Client
{
    public class JsonDistServiceClient : FObjServiceClient, IJsonDistService
    {
        public event JsonDistValueChangedEventHandler ValueChanged;

        public JsonDistServiceClient(UInt32 serviceId) : base(serviceId) { }
        
        public JsonDistServiceClient(UInt32 serviceId, string connName) : base(serviceId, connName) { }


        public void GetValue(string key, AsyncCBHandler asyncCB, object asyncContext)
        {
            var request = new JSONDIST_OBJ_INTERFACE.Pack_CallGetValueRequest()
            {
                key = key
            };

            string json = JsonConvert.SerializeObject(request);

            CurrObjSys.CallFunctionEx(mConn, mServerID, ID, JSONDIST_OBJ_INTERFACE.CALL_GetValue,
                Misc.Converter.StringToBytes(json),
                asyncCB, asyncContext
                );
        }

        public void SetValue(string key, JObject value)
        {
            var request = new JSONDIST_OBJ_INTERFACE.Pack_CallSetValueRequest()
            {
                key = key,
                value = value
            };

            string json = JsonConvert.SerializeObject(request);

            CurrObjSys.CallFunctionEx(mConn, mServerID, ID, JSONDIST_OBJ_INTERFACE.CALL_SetValue,
                Misc.Converter.StringToBytes(json)
                );
        }

        public override void Dispose()
        {
            CurrObjSys.ObjRemove(
                this, mConn);
        }

        public override void ConnectNotify(IFConn from)
        {
            base.ConnectNotify(from);
            if (from.IsConnected)
            {
                CurrObjSys.SenseConfigEx(
                    mConn, mServerID, ID,
                    0xffffffff,
                    SENSE_CONFIG.ADD);
            }
        }

        public override void PushInfo(IFConn from, uint srcid, ushort infoid, byte[] infodata)
        {
            switch (infoid)
            {
                case JSONDIST_OBJ_INTERFACE.PUSH_ValueChanged:
                    {
                        string json = Misc.Converter.BytesToString(infodata);
                        var p = Newtonsoft.Json.JsonConvert.DeserializeObject<JsonDistValueValueChangedEventArgs>(json);

                        ValueChanged?.Invoke(this, new JsonDistValueValueChangedEventArgs() { key = p.key });
                    } break;
            }
        }

        public override void PushCallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] retdata, object asyncDelegate, object asyncContext)
        {
            switch (funcid) 
            {
                case JSONDIST_OBJ_INTERFACE.CALL_GetValue:
                    {
                        string json = Misc.Converter.BytesToString(retdata);
                        var p = JsonConvert.DeserializeObject<DistCell>(json);
                        
                        ((AsyncCBHandler)asyncDelegate)(asyncContext, p);
                    } break;
            }
        }
    }
}