using System.Collections.Concurrent;
using System.Collections.Generic;
using MrWu.Debug;
using NetWorkMessage;
using Server.Core;

namespace ActorCore
{
    /// <summary>
    /// 当前进程的消息队列，也可以给进程内其他Actor发送消息
    /// </summary>
    public class ActorMessageQueue : Singleton<ActorMessageQueue>
    {
        /// <summary>
        /// 接收到的Actor消息暂存在这里，等待Actor进行处理
        /// </summary>
        private readonly ConcurrentDictionary<int, ConcurrentQueue<MessageInfo>> m_actorMessageQueue =
            new ConcurrentDictionary<int, ConcurrentQueue<MessageInfo>>();
        
        /// <summary>
        /// 取出待处理消息
        /// </summary>
        /// <param name="actorTypeId"></param>
        /// <param name="count"></param>
        /// <param name="list"></param>
        public void Fetch(int actorTypeId, int count, List<MessageInfo> list)
        {
            if (!this.m_actorMessageQueue.TryGetValue(actorTypeId,out var queue))
            {
                Debug.Error($"没有这个ActorType：{actorTypeId}");
                return;
            }
            
            for (int i = 0; i < count; i++)
            {
                if (!queue.TryDequeue(out MessageInfo message))
                {
                    break;
                }
                list.Add(message);
            }
            
            //Debug.Log($"拿走后还剩多少：{queue.Count}");
        }

        public void AddQueue(int actorTypeId)
        {
            var queue = new ConcurrentQueue<MessageInfo>();
            this.m_actorMessageQueue[actorTypeId] = queue;
        }

        public void RemoveQueue(int actorTypeId)
        {
            this.m_actorMessageQueue.TryRemove(actorTypeId, out _);
        }

        /// <summary>
        /// 给内部Actor发包
        /// </summary>
        /// <param name="fromActorId"></param>
        /// <param name="actorId"></param>
        /// <param name="messageObject"></param>
        /// <returns></returns>
        public bool Send(ActorId fromActorId,ActorId actorId,MessageObject messageObject)
        {
            if (!m_actorMessageQueue.TryGetValue(actorId.ActorTypeId,out var queue))
            {
                Debug.Error($"发送失败，没有这个Actor! {actorId}");
                return false;
            }
            
            //Debug.Info($"添加到内部消息:{fromActorId} {actorId}");
            queue.Enqueue(new MessageInfo(){FormActorId = fromActorId,MessageObject = messageObject});
            return true;
        }
    }
}