using FObjBase;
using FObjSysTest.IService;
using FObjSysTest.OBJ_INTERFACE;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FObjSysTest.Client
{
    public class ObjAServiceClient : FObj, IObjAService
    {
        public DateTime Now { get; private set; }

        public double[] Numbers { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        IFConn conn;
        UInt32 serverId;
        Stopwatch stopwatch = new Stopwatch();
        public ObjAServiceClient(UInt32 serverId)
        {
            this.serverId = serverId;
            
        }

        public void GetNumbers(double offset, AsyncCBHandler asyncDelegate, object asyncState)
        {
            var request = new Pack_CallGetNumbersRequest()
            {
                offset = offset
            };
            string json = JsonConvert.SerializeObject(request);

            CurrObjSys.CallFunctionEx(conn, serverId, ID,
                OBJA_OBJ_INTERFACE.CALL_GETNUMBERS, Misc.Converter.StringToBytes(json), asyncDelegate, asyncState);
        }


        public void Apply()
        {
            var p = new OBJA_OBJ_INTERFACE.Pack_Params() {
                numbers = Numbers
            };
            string json = JsonConvert.SerializeObject(p);
            CurrObjSys.SetValueEx(
                conn, serverId,ID,
                OBJA_OBJ_INTERFACE.SET_PARAMS, Misc.Converter.StringToBytes(json));
        }
        #region FObj
        public override void ConnectNotify(IFConn from)
        {
            conn = from;
            if (conn.IsConnected)
            {
                CurrObjSys.GetValueEx(conn, serverId, ID, OBJA_OBJ_INTERFACE.GET_PARAMS);
                CurrObjSys.GetValueEx(conn, serverId, ID, OBJA_OBJ_INTERFACE.GET_STATUS);
                CurrObjSys.SenseConfigEx(conn, serverId, ID, 0xffffffff, SENSE_CONFIG.ADD);
                stopwatch.Start();
            }
        }

        public override void PushCallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] retdata, object AsyncDelegate, object AsyncState)
        {
            switch (funcid)
            {
                case OBJA_OBJ_INTERFACE.CALL_GETNUMBERS:
                    {
                        string json = Misc.Converter.BytesToString(retdata);
                        var p = JsonConvert.DeserializeObject<Pack_CallGetNumbersReponse>(json);
                        ((AsyncCBHandler)AsyncDelegate)(AsyncState, p);
                    } break;
            }
        }
        public override void PushInfo(IFConn from, uint srcid, ushort infoid, byte[] infodata)
        {
            PushGetValue(from, srcid, infoid, infodata);
        }

        public override void PushGetValue(IFConn from, uint srcid, ushort memid, byte[] infodata)
        {
            switch (memid)
            {
                case OBJA_OBJ_INTERFACE.GET_PARAMS:
                    {
                        stopwatch.Stop();
                        Console.WriteLine($"PushGetValue OBJA_OBJ_INTERFACE.GET_PARAMS stopwatch = {stopwatch.ElapsedMilliseconds}ms");
                        string json = Misc.Converter.BytesToString(infodata);
                        var p = JsonConvert.DeserializeObject<OBJA_OBJ_INTERFACE.Pack_Params>(json);
                        Numbers = p.numbers;
                    }
                    break;
                case OBJA_OBJ_INTERFACE.GET_STATUS:
                    {
                        string json = Misc.Converter.BytesToString(infodata);

                        var p = JsonConvert.DeserializeObject<OBJA_OBJ_INTERFACE.Pack_Status>(json);
                        Now = p.now;
                    } break;
            }
        }
        #endregion
    }
}