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

namespace FObjSysTest.Server.OBJProxxy
{
    public class ObjA_OBJProxy : FObj
    {
        #region 延时推送 MARKNO
        const int MARKNO_PUSH_PARAMS = 1;
        const int MARKNO_PUSH_STATUS = 2;
        #endregion

        IObjAService objAService;
        public ObjA_OBJProxy(int objsys_idx, UInt32 objid, IObjAService objAService) : base(objsys_idx)
        {
            ID = objid;
            this.objAService = objAService;

            this.objAService.PropertyChanged += ObjAService_PropertyChanged;
        }

        private void ObjAService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Now")
            {
                FObjBase.PollModule.Current.Poll_JustOnce(
                    new PollModule.PollHandler(delegate ()
                    {
                        byte[] buf;
                        GetValue(null, 0, OBJA_OBJ_INTERFACE.GET_STATUS, out buf);
                        CurrObjSys.PushObjInfoEx(
                            this, OBJA_OBJ_INTERFACE.PUSH_STATUS,
                            buf);
                    }), this, MARKNO_PUSH_STATUS);
            }
            else if (e.PropertyName == "Numbers")
            {
                FObjBase.PollModule.Current.Poll_JustOnce(
                    new PollModule.PollHandler(delegate ()
                    {
                        byte[] buf;
                        GetValue(null, 0, OBJA_OBJ_INTERFACE.GET_PARAMS, out buf);
                        CurrObjSys.PushObjInfoEx(
                            this, OBJA_OBJ_INTERFACE.PUSH_PARAMS,
                            buf);
                    }), this, MARKNO_PUSH_PARAMS);
            }
        }

        #region FObj
        public override void ConnectNotify(IFConn from)
        {
            Console.WriteLine($"from.IsConnected={from.IsConnected}");
        }
        public override void GetValue(IFConn from, uint srcid, ushort memid, out byte[] infodata)
        {
            infodata = null;
            switch (memid)
            {
                case OBJA_OBJ_INTERFACE.GET_STATUS:
                    {
                        var p = new OBJA_OBJ_INTERFACE.Pack_Status()
                        {
                            now = objAService.Now
                        };
                        string json = JsonConvert.SerializeObject(p);

                        infodata = Misc.Converter.StringToBytes(json);
                    }break;
                case OBJA_OBJ_INTERFACE.GET_PARAMS:
                    {
                        var p = new OBJA_OBJ_INTERFACE.Pack_Params()
                        {
                            numbers = objAService.Numbers
                        };
                        string json = JsonConvert.SerializeObject(p);

                        infodata = Misc.Converter.StringToBytes(json);
                    }
                    break;
            }
        }
        public override void SetValue(IFConn from, uint srcid, ushort memid, byte[] infodata)
        {
            switch (memid)
            {
                case OBJA_OBJ_INTERFACE.SET_PARAMS:
                    {
                        string json = Misc.Converter.BytesToString(infodata);
                        var p = JsonConvert.DeserializeObject<OBJA_OBJ_INTERFACE.Pack_Params>(json);
                        objAService.Numbers = p.numbers;
                    }
                    break;
            }
        }
        public override void CallFunction(IFConn from, uint srcid, uint magic, ushort funcid, byte[] infodata)
        {
            switch (funcid)
            {
                case OBJA_OBJ_INTERFACE.CALL_GETNUMBERS:
                    {
                        string json = Misc.Converter.BytesToString(infodata);
                        var request = JsonConvert.DeserializeObject<Pack_CallGetNumbersRequest>(json);
                        objAService.GetNumbers(request.offset,
                            (asyncState, retdata) =>
                            {
                                var connContext = asyncState as ConnContext;
                                string json_reponse = JsonConvert.SerializeObject(retdata);
                                CurrObjSys.PushCallFunctionEx(
                                    connContext.from,
                                    connContext.srcid,
                                    ID,
                                    connContext.magic,
                                    OBJA_OBJ_INTERFACE.CALL_GETNUMBERS,
                                    Misc.Converter.StringToBytes(json_reponse));

                            }, new ConnContext(from, srcid, magic));
                    }
                    break;
            }
        }
        #endregion
    }
}
