using System.Collections.Generic;
using System.Threading.Tasks;
using AppGame.Sync;
using JNGame.Runtime.Sync;
using JNGame.Runtime.System;
using JNGame.Sync.Frame;
using JNGame.Sync.State;
using JNGame.Sync.System.Data;
using JNGame.Sync.System.View;

namespace AppGame.Systems
{
    public class JNGGame : SystemBase
    {
        
        private JNSyncDefaultService client;
        public JNSyncDefaultService Client => client;
        
        private JNSStateServerService server;
        public JNSStateServerService Server => server;

        public bool IsStartClient => client is not null && client.IsStartGame;
        public bool IsStartServer => server is not null && server.IsStartGame;
        
        public override async Task OnInit()
        {
            
        }

        public override void OnClose()
        {
            base.OnClose();
            client?.Dispose();
            server?.Dispose();
        }

        /// <summary>
        /// 运行同步类
        /// </summary>
        public T StartClient<T>() where T : JNSyncDefaultService,new()
        {
            client = new T();
            client.Initialize();
            client.TStartExecute();
            return client as T;
        }
        public T StartServer<T>() where T : JNSStateServerService,new()
        {
            server = new T();
            server.Initialize();
            server.TStartExecute();
            return server as T;
        }

        /// <summary>
        /// 获取第一个客户端的输入类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T GetInput<T>() where T : JNInputBase, new()
        {
            return Client.GetSystem<JNInputSystem>().UIInput<T>();
        }
        public T GetClient<T>() where T : JNSyncDefaultService
        {
            if (!IsStartClient) return null;
            return client as T;
        }
        
        /// <summary>
        /// 接收输入数据
        /// </summary>
        /// <param name="frame"></param>
        public void AddInput(JNFrameInfo frame)
        {
            (client as JNGFrameSystem)?.AddFrame(frame);
            (server as JNGStateServerSystem)?.AddInput(frame);
        }

        public void AddTileInput(JNStateTileInputs frame)
        {
            if (server is JNGTileServerSystem system1)
            {
                if (system1.TID == frame.TId || frame.TId == 0)
                {
                    system1.AddInput(frame);
                }
            }
            if (server is JNGTileSlaveServerSystem system2)
            {
                if (system2.TID == frame.TId || frame.TId == 0)
                {
                    system2.AddInput(frame);
                }
            }
        }

        /// <summary>
        /// 清除指定区域的状态
        /// </summary>
        public void ClearTileState(int index)
        {
            client?.GetSystems<ISTileDataSystem>().ForEach(child =>
            {
                child.ClearTileData(index);
            });
            server?.GetSystems<ISTileDataSystem>().ForEach(child =>
            {
                child.ClearTileData(index);
            });
        }
        
        /// <summary>
        /// 接收状态数据
        /// </summary>
        public void SyncState(JNStateItemData frame,bool isSyncClient,bool isSyncServer)
        {
            var message = new Dictionary<ulong, byte[]>();
            foreach (var data in frame.Messages)
            {
                message.Add(data.Key,data.Value.Data.ToByteArray());
            }

            if (isSyncClient)
            {
                client?.GetSystems<ISStateDataSystem>().ForEach(child =>
                {
                    if (child.NetID != frame.NetID) return;
                    child.OnInsertUBytes(message);
                });
            }
            if (isSyncServer)
            {
                server?.GetSystems<ISStateDataSystem>().ForEach(child =>
                {
                    if (child.NetID != frame.NetID) return;
                    child.OnInsertUBytes(message);
                });
            }
        }
        
    }
}