using System;
using System.Collections.Generic;
using Server;
using MrWu.Debug;
using Server.Data;
using MrWu.Basic;
using System.Threading;
using GameData;
using Game.Player;
using System.Collections.Concurrent;

namespace Game.Robot
{
    /// <summary>
    /// 机器人控制器
    /// </summary>
    public class RobotController
    {
        /// <summary>
        /// 机器人控制器
        /// </summary>
        public static RobotController instance { get; internal set; }

        /// <summary>
        /// 机器人数量
        /// </summary>
        public int RobotCnt { get; private set; }

        /// <summary>
        /// 闲置的机器人数量
        /// </summary>
        public int idleRobotCnt { get; private set; }

        /// <summary>
        /// 初始机器人的最小游戏币
        /// </summary>
        public readonly int minMoney;

        /// <summary>
        /// 初始机器人的最大游戏币
        /// </summary>
        public readonly int maxMoney;

        public static readonly object _lock = new object();

        /// <summary>
        /// 随机值
        /// </summary>
        public readonly Random Random = new Random(unchecked((int)DateTime.UtcNow.Ticks));

        private GameManager gamemgr;

        internal RobotController(GameManager gamemgr, int minMoney, int maxMoney)
        {
            this.gamemgr = gamemgr;
            this.minMoney = minMoney;
            this.maxMoney = maxMoney;

            robotPars = new RobotPar[ServerConfigManager.Instance.TingCnt];
            int len = robotPars.Length;
            for (int i = 0; i < len; i++)
            {
                robotPars[i] = new RobotPar(i);
            }
        }

        /// <summary>
        /// 机器人登录
        /// </summary>
        /// <param name="tingid"></param>
        private void RobotLogin(int tingid)
        {
            if (tingid < 0 || tingid >= gamemgr.tingCnt)
                return;

            int roomid = -1;
            foreach (var room in gamemgr.rooms)
            {
                foreach (var tid in room.config.Tings)
                {
                    if (tid == tingid)
                    {
                        roomid = room.id;
                        break;
                    }
                }

                if (roomid >= 0)
                    break;
            }

            if (roomid < 0)
            {
                Debug.Error("怎么可能未获取到对应的房间!");
                return;
            }

            PlayerDataAsyc pl = CreateRobot();
            if (pl == null)
                return;

            int result = PlayerCollection.Instance.AddPlayer(pl);
            if (result != 1)
            {
                return;
            }

            Shadow.Shadow shadow = gamemgr.shadowPool.GetRandomShadow();
            pl.gameid = gamemgr.config.GameId;
            pl.state = (int)PlayerState.INGame;
            pl.nickname = shadow == null ? ("auysn" + Random.Next(10000)) : shadow.name;
            pl.avatar = shadow?.photo;
            pl.exp = Random.Next(5000, 50000);
            AddRobot(pl, roomid, tingid); //去排队
        }

        /// <summary>
        /// 创建一个机器人
        /// </summary>
        /// <returns></returns>
        private PlayerDataAsyc CreateRobot()
        {
            PlayerDataAsyc pl = new PlayerDataAsyc();
            pl.userid = robotuserid;
            pl.money = BaseFun.random.Next(minMoney, maxMoney);
            pl.ip = $"106.{BaseFun.random.Next(225, 231)}.{BaseFun.random.Next(1, 255)}.{BaseFun.random.Next(1, 255)}";

            RobotCnt++;
            // Debug.Info("机器人的金钱:" + pl.money + "," + pl.userid + "," + pl.nickname + ",min:" + minMoney + ",max:" + maxMoney);

            return pl;
        }

        /// <summary>
        /// 
        /// </summary>
        protected int _robotuserid = -10000;

        /// <summary>
        /// 
        /// </summary>
        protected int robotuserid
        {
            get { return Interlocked.Decrement(ref _robotuserid); }
        }

        /// <summary>
        /// 添加到闲置机器人的数量
        /// </summary>
        /// <param name="cnt"></param>
        /// <returns></returns>
        public int AddIdleRobotCnt(int cnt)
        {
            idleRobotCnt += cnt;
            return idleRobotCnt;
        }

        #region 机器人分片管理 按厅分

        /// <summary>
        /// 机器人分区
        /// </summary>
        private readonly RobotPar[] robotPars;

        /// <summary>
        /// 获取分区中机器人的数量
        /// </summary>
        /// <param name="id">分区id</param>
        /// <returns></returns>
        public int GetParCount(int id)
        {
            return robotPars[id].Count;
        }

        /// <summary>
        /// 获取分区中的机器人数量
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public int GetParSumCount(int id)
        {
            return robotPars[id].SumCount;
        }

        /// <summary>
        /// 获取闲置的机器人数量
        /// </summary>
        /// <returns></returns>
        public int GetCount()
        {
            int count = 0;
            foreach (var item in robotPars)
            {
                count += item.Count;
            }

            return count;
        }

        /// <summary>
        /// 获取总的机器人数量
        /// </summary>
        /// <returns></returns>
        public int GetSumCount()
        {
            int count = 0;
            foreach (var item in robotPars)
            {
                count += item.SumCount;
            }

            return count;
        }

        /// <summary>
        /// 获取一个机器人
        /// </summary>
        /// <param name="id">分区id</param>
        /// <returns></returns>
        public PlayerDataAsyc GetRobot(int id)
        {
            return robotPars[id].GetRobot();
        }

        /// <summary>
        /// 放回一个机器人
        /// </summary>
        /// <param name="pl"></param>
        /// <param name="id">分区id</param>
        public void PushRobot(PlayerDataAsyc pl, int id)
        {
            robotPars[id].PushRobot(pl);
        }

        /// <summary>
        /// 放回一些机器人
        /// </summary>
        /// <param name="pls"></param>
        /// <param name="id"></param>
        public void PushRobot(IEnumerable<PlayerDataAsyc> pls, int id)
        {
            robotPars[id].PushRobot(pls);
        }

        /// <summary>
        /// 主动添加一个机器人
        /// </summary>
        /// <param name="pl"></param>
        /// <param name="roomid"></param>
        /// <param name="id"></param>
        public void AddRobot(PlayerDataAsyc pl, int roomid, int id)
        {
            robotPars[id].AddRobot(pl, roomid);
        }

        #endregion

        /// <summary>
        /// 一个机器人分区
        /// </summary>
        private class RobotPar
        {
            /// <summary>
            /// 常驻机器人数量
            /// </summary>
            private const int PerCount = 30;

            private int id;

            /// <summary>
            /// 没用上的机器人，改为线程安全的集合
            /// </summary>
            public readonly ConcurrentQueue<PlayerDataAsyc> robots = new ConcurrentQueue<PlayerDataAsyc>();

            public RobotPar(int id)
            {
                this.id = id;
            }

            /// <summary>
            /// 当前的机器人数量
            /// </summary>
            public int Count
            {
                get { return robots.Count; }
            }

            /// <summary>
            /// 总的机器人数量
            /// </summary>
            public int SumCount { get; private set; }

            /// <summary>
            /// 获取机器人
            /// </summary>
            public PlayerDataAsyc GetRobot()
            {
                //Debug.Log("获取机器人:{0}", len);
                PlayerDataAsyc pl = null;
                if (Count > 0)
                {
                    robots.TryDequeue(out pl);
                }

                Debug.Info("机器人数量:" + Count + "," + PerCount + "pl :" + (pl == null) +
                           (pl == null ? "" : "id:" + pl.userid));
                if (Count < PerCount)
                {
                    //机器人不足去补充
                    instance.RobotLogin(id);
                    SumCount++;
                }

                if (pl != null && pl.MatchObj != null)
                {
                    Debug.Fatal($"拿到了比赛的机器人:userid:{pl.userid}");
                    pl = null;
                }

                return pl;
            }

            /// <summary>
            /// 放入机器人
            /// </summary>
            /// <param name="pl"></param>
            public void PushRobot(PlayerDataAsyc pl)
            {
                //Debug.Error("放回机器人列表:" + pl.ToString());
                if (pl == null)
                {
                    Debug.Error("放回的机器人是空!!!");
                    return;
                }

                if (pl.state > 1 || pl.deskid >= 0 || pl.MatchObj != null)
                {
                    Debug.Info("放回的机器人有数据 userid:" + pl.userid + " state:" + pl.state + " deskid:" + pl.deskid +
                               "true:" + (pl.MatchObj == null));
                    return;
                }

                pl.RobotInit();
                robots.Enqueue(pl);
            }

            /// <summary>
            /// 放入机器人
            /// </summary>
            /// <param name="pls"></param>
            public void PushRobot(IEnumerable<PlayerDataAsyc> pls)
            {
                foreach (var item in pls)
                {
                    item.RobotInit();
                    robots.Enqueue(item);
                }
            }

            /// <summary>
            /// 添加机器人
            /// </summary>
            /// <param name="pl"></param>
            /// <param name="roomid">房间id</param>
            public void AddRobot(PlayerDataAsyc pl, int roomid)
            {
                pl.roomid = roomid;
                pl.tingid = id;
                lock (_lock)
                {
                    robots.Enqueue(pl);
                }

                Debug.Log("添加到机器人列表厅:{0},机器人id:{1},机器人数量:{2}", id, pl.userid, robots.Count);
            }
        }
    }
}