using System;
using System.Net;
using System.Threading.Tasks;
using MrWu.Debug;
using NetWorkMessage;
using Server.Core;
using Server.Net;

namespace ActorCore
{
    /// <summary>
    /// 内部网络Actor，负责给其他进程发送消息
    /// </summary>
    public class NetInnerActor : Actor
    {
        public override SchedulerType SchedulerType => SchedulerType.Thread;

        public override MailBoxType MailBoxType => MailBoxType.UnOrderedMessage;

        /// <summary>
        /// 跨进程发送
        /// </summary>
        public readonly IProcessOuterSender ProcessOuterSender;
        
        public NetInnerActor(byte moduleId, byte nodeNum,IPEndPoint ipEndPoint,Func<ActorId, IPEndPoint> getActorIdAddress) : base(moduleId, nodeNum, ActorTypeId.NetInner)
        {
            ProcessOuterSender processOuterSender = new ProcessOuterSender(this);
            processOuterSender.Start(ipEndPoint);
            processOuterSender.GetActorIdAddress = getActorIdAddress;
            this.ProcessOuterSender = processOuterSender;
        }
        
        public override void RegisterHandle()
        {
            RegisterMessageHandle(typeof(NetInnerMessage),NetInnerMessageHandle);
            RegisterRPCHandle(typeof(NetInnerRequest),NetInnerRequestHandle); 
        }

        protected override void Update()
        {
            this.ProcessOuterSender.Update();
        }

        private async Task NetInnerMessageHandle(ActorId fromActorId,IMessage message)
        {
            if (message is NetInnerMessage netInnerMessage)
            {
                Debug.Log($"NetInnerMessageHandle :{fromActorId}");
                ProcessOuterSender.Send(fromActorId, netInnerMessage.ActorId, netInnerMessage.MessageObject);
                await Task.CompletedTask;
            }
        }

        private async Task NetInnerRequestHandle(ActorId fromActorId,IRequest request,IResponse response)
        {
            if (request is NetInnerRequest netInnerRequest && response is NetInnerResponse netInnerResponse)
            {
                IResponse res = await ProcessOuterSender.Call(fromActorId, netInnerRequest.ActorId, netInnerRequest.MessageObject);
                netInnerResponse.MessageObject = res;
                //Debug.Info($"远程调用回到:{res.GetType()}");
            }
        }
    }
}