using Fleck;
using MessagePack;
using TouchSocket.Core;
using System.Collections.Concurrent;
using StackExchange.Redis;
using CrazyStudio.Core.Common.Game;
using CrazyStudio.Core.Common.Redis.Dto;

namespace CrazyStudio.Core.Common.Status.Eitities
{
    [MessagePackObject]
    public class RoomInfo : IDisposable
    {
        /// <summary>
        /// 用户房间ID
        /// </summary>
        [Key(0)]
        public string RoomId { get; set; } = string.Empty;

        /// <summary>
        /// 用户ID，每个用户唯一
        /// </summary>
        [Key(1)]
        public string RoomName { get; set; } = string.Empty;

        /// <summary>
        /// 做主机的用户名称
        /// </summary>
        [Key(2)]
        public string HostUserName { get; set; } = string.Empty;

        /// <summary>
        /// 房间创建时间,单位：毫秒
        /// </summary>
        [Key(3)]
        public HashSet<string> UserNameList = new HashSet<string>();

        /// <summary>
        /// 房间创建时间,单位：毫秒
        /// </summary>
        [Key(4)]
        public long CreateTime = DateTime.UtcNow.Ticks / 10000;

        /// <summary>
        /// 房间创建时间,单位：毫秒
        /// </summary>
        [Key(5)]
        public long StartGameTime = DateTime.UtcNow.Ticks / 10000;

        [IgnoreMember]
        public System.Timers.Timer? RoomEndTimer { get; set; } = null;

        [IgnoreMember]
        public GameLogicServer? RoomServer { get; set; } = null;


        [IgnoreMember]
        private Action? StopServerEvent = null;

        [IgnoreMember]
        public ConcurrentDictionary<string, ConcurrentQueue<byte[]>> MessageQueue { get; set; } = new ConcurrentDictionary<string, ConcurrentQueue<byte[]>>();


        public RoomInfo()
        {

        }
        //[IgnoreMember]
        //public ConcurrentQueue<byte[]> MessageQueue { get; set; } = new ConcurrentQueue<byte[]>();

        /// <summary>
        /// 启动房间逻辑服务器，同步数据
        /// </summary>
        /// <param name="syncGameStateToClientsEvents">逻辑服务器房间同步发送网络包事件</param>
        /// <param name="stopServerEvent">关闭事件</param>
        /// <param name="runMs">服务器运行多久后关闭</param>
        public void StartServer(Action syncGameStateToClientsEvents, int runMs, Action? stopServerEvent = null, bool isForceResetTime = false)
        {
            if (!IsRunningServer)
            {
                if (RoomServer == null)
                {
                    RoomServer = new GameLogicServer();
                }
                this.StopServerEvent = stopServerEvent;
                RoomServer.SetSyncGameStateToClientsEvents(syncGameStateToClientsEvents);
                RoomServer.Start();
                if (isForceResetTime)
                {
                    if (RoomEndTimer != null)
                    {
                        RoomEndTimer.Stop();
                        RoomEndTimer.Dispose();
                        RoomEndTimer = null;
                    }
                }
                if (RoomEndTimer == null)
                {
                    RoomEndTimer = new System.Timers.Timer();
                    RoomEndTimer.Interval = runMs;
                    RoomEndTimer.Elapsed -= RoomEndTimer_Elapsed;
                    RoomEndTimer.Elapsed += RoomEndTimer_Elapsed;
                    RoomEndTimer.Start();
                }
            }
        }

        public void PushMessage(string userName, byte[] message)
        {
            if (MessageQueue.TryGetValue(userName, out var queue))
            {
                queue.Enqueue(message);
            }
            else
            {
                var newQueue = new ConcurrentQueue<byte[]>();
                newQueue.Enqueue(message);
                MessageQueue[userName] = newQueue;
            }
        }


        public List<byte[]> PopRoomMessageAll()
        {
            var messages = new List<byte[]>();
            foreach (var queue in MessageQueue.Values)
            {
                while (queue.TryDequeue(out var message))
                {
                    if (message != null)
                    {
                        messages.Add(message);
                    }
                }
            }
            return messages;
        }

        public List<byte[]> PopRoomMessageThisTime()
        {
            var messages = new List<byte[]>();
            foreach (var queue in MessageQueue.Values)
            {
                if (queue.TryDequeue(out var message))
                {
                    if (message != null)
                    {
                        messages.Add(message);
                    }
                }
            }
            return messages;
        }

        private void RoomEndTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
            StopServer();
            StopServerEvent?.Invoke();
        }

        [IgnoreMember]
        public bool IsRunningServer { get => RoomServer?.IsRunning ?? false; }

        /// <summary>
        /// 停止房间逻辑服务器
        /// </summary>
        public void StopServer()
        {
            RoomServer?.Stop();
            RoomEndTimer?.Stop();
        }

        /// <summary>
        /// 释放房间逻辑服务器
        /// </summary>
        public void DisposeServer()
        {
            StopServer();
            RoomServer?.Dispose();
            RoomServer = null;
            RoomEndTimer?.Dispose();
            RoomEndTimer = null;
        }

        /// <summary>
        /// 释放房间资源
        /// </summary>
        public void Dispose()
        {
            DisposeServer();
        }
    }
}
