using System;
using System.Net;
using ActorCore;
using MrWu.Debug;
using Server.Core;
using Server.DB.Redis;

namespace Server
{
    public class ActorNetManager : SingleInstance<ActorNetManager>
    {
        public ActorNetManager()
        {
            GameDispatcher.Instance.AddListener(GameMsgId.DayChange,OnDayChange);
        }

        /// <summary>
        /// 保存7天
        /// </summary>
        private TimeSpan ExpireTime = new TimeSpan(7,0,0,0);
        
        public string GetInnerNetKey(ActorId actorId)
        {
            return $"ActorInnerNet:{actorId.ModuleId}-{actorId.NodeNum}";
        }

        public string GetOuterNetKey(ActorId actorId)
        {
            return $"ActorOuterNet:{actorId.ModuleId}-{actorId.NodeNum}";
        }

        private ActorId innertNetActorId;

        private ActorId outerNetActorId;
        
        private void OnDayChange(object param)
        {
            if (innertNetActorId != default)
            {
                string key = GetInnerNetKey(innertNetActorId);
                redisManager.db.KeyExpireAsync(key, ExpireTime);
            }

            if (outerNetActorId != default)
            {
                string key = GetOuterNetKey(outerNetActorId);
                redisManager.db.KeyExpireAsync(key, ExpireTime);
            }
        }

        public void RegisterInnerNet(ActorId actorId,IPEndPoint ipEndPoint)
        {
            innertNetActorId = actorId;
            string key = GetInnerNetKey(actorId);
            string ipEndPointStr = ipEndPoint.ToString();
            redisManager.db.StringSetAsync(key, ipEndPointStr,ExpireTime);
        }

        public void RegisterOuterNet(ActorId actorId,IPEndPoint ipEndPoint)
        {
            outerNetActorId = actorId;
            string key = GetOuterNetKey(actorId);
            string ipEndPointerStr = ipEndPoint.ToString();
            redisManager.db.StringSetAsync(key, ipEndPointerStr, ExpireTime);
        }

        public IPEndPoint GetInnerIpEndPoint(ActorId actorId)
        {
            string key = GetInnerNetKey(actorId);
            string ipEndPointStr = redisManager.db.StringGet(key);
            
            //Debug.Info($"ipEndPointStr:{ipEndPointStr} {key}");
            
            if (!string.IsNullOrEmpty(ipEndPointStr))
            {
                string[] parts = ipEndPointStr.Trim().Split(':');
                if (parts.Length == 2 && int.TryParse(parts[1],out int port) && IPAddress.TryParse(parts[0],out IPAddress address))
                {
                    return new IPEndPoint(address,port);
                }
            }

            return null;
        }

        public IPEndPoint GetOuterIpEndPoint(ActorId actorId)
        {
            string key = GetOuterNetKey(actorId);
            string ipEndPointStr = redisManager.db.StringGet(key);
            
            // Debug.Info($"ipEndPointStr:{ipEndPointStr} {key}");
            
            if (!string.IsNullOrEmpty(ipEndPointStr))
            {
                string[] parts = ipEndPointStr.Trim().Split(':');
                if (parts.Length == 2 && int.TryParse(parts[1], out int port) && IPAddress.TryParse(parts[0], out IPAddress address))
                {
                    return new IPEndPoint(address, port);
                }
            }

            return null;
        }
    }
}