using RpcComponents;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.NetCode;

namespace Client
{
    [WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation | WorldSystemFilterFlags.ThinClientSimulation)]
    partial struct ClientRequestGameEntrySystem : ISystem
    {
        private EntityQuery _pendingNetworkIdQuery;
    
        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            //Get all entities connected to the server (having networkID), but not in game yet (no NetworkStreamInGame) 
            var builder = new EntityQueryBuilder(Allocator.Temp).WithAll<NetworkId>().WithNone<NetworkStreamInGame>();
            _pendingNetworkIdQuery = state.GetEntityQuery(builder);
        
            //only run system when entities with these components exist
            state.RequireForUpdate(_pendingNetworkIdQuery);
            state.RequireForUpdate<ClientTeamRequest>();
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            //Get Requested team and all network ids that want to join
            var ecb           = new EntityCommandBuffer(Allocator.Temp);
            var requestedTeam = SystemAPI.GetSingleton<ClientTeamRequest>().Value;
            var requestedColor = SystemAPI.GetSingleton<ClientTeamRequest>().Color;
            var pendingNetworkIds = _pendingNetworkIdQuery.ToEntityArray(Allocator.Temp);

            foreach (var pendingNetworkId in pendingNetworkIds)
            {
                //mark network ID as joined in game - it will receive Snapshots
                ecb.AddComponent<NetworkStreamInGame>(pendingNetworkId);
                var requestTeamEntity = ecb.CreateEntity();
                
                //Give entity Rpc command request and team request so that the server can handle it
                ecb.AddComponent(requestTeamEntity, new TdTeamRequest
                {
                    Value = requestedTeam,
                    Color = requestedColor
                });
                
                ecb.AddComponent(requestTeamEntity, new SendRpcCommandRequest()
                {
                    TargetConnection = pendingNetworkId
                });
                
                //Broadcast Rpc
                ecb.Playback(state.EntityManager);
            }
        }

        [BurstCompile]
        public void OnDestroy(ref SystemState state)
        {
        
        }
    }
}
