using CommonAI.Zone.Formula;
using CommonAI.Zone.Helper;
using CommonAI.Zone.Instance;
using CommonLang;
using System.Collections.Generic;
using XmdsCommon.Plugin;
using CommonLang.Log;

namespace XmdsCommonServer.Plugin
{
    public class XmdsHateSystem : HateSystem
    {
        //private readonly Logger log = LoggerFactory.GetLogger("XmdsHateSystem");
        public readonly XmdsVirtual Virtual;

        /// <summary>
        /// 继承者.
        /// </summary>
        private XmdsVirtual mHeirs;
        //是否寻找继承人.
        private bool mFindHeirs = false;
        //分享列表.
        private List<string> mSharedList = null;
        //hatesystem添加单位通知.
        public delegate void OnTargetAddEvent(HateInfo target);
        public event OnTargetAddEvent OnHandleTargetAddEvent;
        /// <summary>
        /// 击杀助攻列表.
        /// </summary>
        private List<string> mAtkAssistantList = null;

        protected TimeExpire<int> mSwithHeirsExpire;//切换归属者

        public XmdsHateSystem(XmdsVirtual owner)
            : base(owner.mUnit)
        {
            Virtual = owner;
            this.mSwithHeirsExpire = new TimeExpire<int>(10000);// 6秒切归属者
        }

        /// <summary>
        /// 设置是否计算归属权.
        /// </summary>
        /// <param name="flag"></param>
        public void SetFindHeirs(bool flag)
        {
            if (flag == false && mFindHeirs != flag)
            {
                RemoveHeirs();
            }

            mFindHeirs = flag;
        }

        public override void Update(int intervalMS)
        {
            base.Update(intervalMS);

            if (mHeirs != null)
            {
                if (this.mSwithHeirsExpire.Update(intervalMS))
                {
                    RemoveHeirs();
                }
            }
        }
        public override void Sort()
        {
            base.Sort();
        }
        public override int Compare(HateSystem.HateInfo x, HateSystem.HateInfo y)
        {
			//先根据仇恨值排序.
			int v = base.Compare(x, y);

            //仇恨值相同时,就近原则.
            if (v == 0)
            {
                //重载后根据距离判断,距离近的在前.
                float d1 = CMath.getDistance(Virtual.mUnit.X, Virtual.mUnit.Y, x.Unit.X, x.Unit.Y);
                float d2 = CMath.getDistance(Virtual.mUnit.X, Virtual.mUnit.Y, y.Unit.X, y.Unit.Y);
                v = (int)(d1 - d2);
            }

            return v;
        }
        //获取攻击对象.
        public override InstanceUnit GetHated(bool onlyMonster = false)
        {
            InstanceUnit ret = base.GetHated(onlyMonster);

            if (ret != null)
            {
                ret = Virtual.GetAtkTarget(ret);
            }

            return ret;
        }

        /// <summary>
        /// 强制删除buff追击目标,只能怪物调用(怪物有攻击圈)
        /// </summary>
        public override void forceRemoveAtkTraget() {
            Virtual.forceRemoveAtkTarget();
        }

        protected override void onTargetAdded(HateInfo target)
        {
            if (this.Owner.IsDead() == false)
            {
                if (OnHandleTargetAddEvent != null)
                {
                    OnHandleTargetAddEvent.Invoke(target);
                }

                base.onTargetAdded(target);
            }
        }

		public void MockingInheritHatred(XmdsVirtual attacker)
		{
			if(unitList.Count > 1)
			{
				HateInfo info = unitList[0];
				XmdsVirtual hateVirtual = (XmdsVirtual)info.Unit.Virtual;
				long hateValue = System.Math.Min((long)(info.HateValue * 1.3), info.HateValue + hateVirtual.MirrorProp.GetFinalAttack(true) * 100);
				this.SetHateInfo(attacker, hateValue);
            }
			else
			{
				this.SetHateInfo(attacker, CUtils.CastInt(attacker.MirrorProp.MaxHP));
			}
        }

        protected override void onTargetRemoved(HateInfo target)
        {
            base.onTargetRemoved(target);

            if (mHeirs != null)
            {
                if (mHeirs.mUnit.ID == target.Unit.ID)
                {
                    if (Virtual.mUnit.IsDead() == false)
                    {
                        //移除归属者.
                        RemoveHeirs();
                    }
                    else
                    {
                        //移除归属者监听.
                        RemoveHeirsListener();
                    }
                }
            }
        }
        protected override void onOwnerHitted(HateInfo attacker, AttackSource attack, int reduceHP)
        {
            //不使用底层仇恨机制.
            base.onOwnerHitted(attacker, attack, reduceHP);
        }

        /// <summary>
        /// 设置归属者,同时设置监听.
        /// </summary>
        /// <param name="zv"></param>
        private void AddHeirs(XmdsVirtual zv)
        {
            if (zv is XmdsVirtual_Player)
            {
                if ((zv.mUnit.Info.Properties as XmdsUnitProperties).BotTestTemplate == false)
                {
                    //log.Error("AddHeirs - " + System.DateTime.Now);
                    mHeirs = zv;

                    if (mHeirs != null)
                    {
                        int hpPercent = mHeirs.mUnit.get_current_hp()*10000/ mHeirs.mProp.ServerData.Prop.MaxHP;
                        Virtual.SyncHeirsInfo(mHeirs.mProp.ServerData.BaseInfo.name, hpPercent,mHeirs.mProp.ServerData.BaseInfo.ProType);
                        //加血监听.
                        mHeirs.OnHealEventHandle += MHeres_OnHealEventHandle;
                        //脱战监听.
                        mHeirs.OnCombatStateChangeHandle += MHeres_OnCombatStateChangeHandle;
                    }
                    this.mSwithHeirsExpire.Reset();
                }

            }

        }
        /// <summary>
        /// 移除归属者以及对应的监听.
        /// </summary>
        private void RemoveHeirs()
        {
            if (mHeirs != null)
            {
                //log.Error("RemoveHeirs - " + System.DateTime.Now);

                mHeirs.OnHealEventHandle -= MHeres_OnHealEventHandle;
                mHeirs.OnCombatStateChangeHandle -= MHeres_OnCombatStateChangeHandle;
                Virtual.SyncHeirsInfo(null, 0,mHeirs.mProp.ServerData.BaseInfo.ProType);
                mHeirs = null;
            }
        }

        private void RemoveHeirsListener()
        {
            if (mHeirs != null)
            {
                mHeirs.OnHealEventHandle -= MHeres_OnHealEventHandle;
                mHeirs.OnCombatStateChangeHandle -= MHeres_OnCombatStateChangeHandle;
            }
        }

        /// <summary>
        /// 脱战监听.
        /// </summary>
        /// <param name="unit"></param>
        /// <param name="status"></param>
        private void MHeres_OnCombatStateChangeHandle(XmdsVirtual unit, bool status)
        {
            if (status == false)
            {
                RemoveHeirs();
            }
        }
        /// <summary>
        /// 监听仇恨对象受治愈效果.
        /// </summary>
        /// <param name="attacker"></param>
        /// <param name="hitter"></param>
        /// <param name="value"></param>
        /// <param name="result"></param>
        private void MHeres_OnHealEventHandle(XmdsVirtual attacker, XmdsVirtual hitter, int value, ref XmdsVirtual.AtkResult result)
        {
            if (value > 0 && result.ThreatValue > 0)
            {
                int ret = CalThreatValue(value, result.ThreatValue, result.ThreatValueChangePer, result.ThreatValueChangeModify);
                addTarget(attacker, ret);
            }
        }
        /// <summary>
        /// 添加仇恨对象,设置仇恨值.
        /// </summary>
        /// <param name="target"></param>
        /// <param name="threatValue"></param>
        private void addTarget(XmdsVirtual target, int threatValue)
        {
            HateInfo ret = null;

            if (this.unitMap.TryGetValue(target.mUnit.ID, out ret))
            {
                //donothing.
            }
            else
            {
                //加入仇恨列表.
                ret = Add(target.mUnit);
            }
            //增加对应仇恨.
            ret.HateValue += threatValue;
        }

        /// <summary>
        /// 被攻击时调用.
        /// </summary>
        /// <param name="attacker"></param>
        /// <param name="hitter"></param>
        /// <param name="value"></param>
        /// <param name="result"></param>
        public void OnHitted(XmdsVirtual attacker, XmdsVirtual hitter, int value, ref XmdsVirtual.AtkResult result)
        {
            int threat = value;

            if (value > 0 && result.ThreatValue > 0)
            {
                threat = CalThreatValue(value, result.ThreatValue, result.ThreatValueChangePer, result.ThreatValueChangeModify);
            }
            //归属人设置.
            if (mFindHeirs)
            {
                if(mHeirs == null)
                {
                    //设置继承人.
                    XmdsVirtual temp = null;
                    if (attacker is XmdsVirtual_Player)
                    {
                        AddHeirs(attacker);
                    }
                    else if (attacker is XmdsVirtual_Pet)//是宠物找主人.
                    {
                        temp = (attacker as XmdsVirtual_Pet).GetMaster();
                        if (temp != null)
                        {
                            AddHeirs(temp);
                        }
                    }
                    else if (attacker is XmdsVirtual_SummonUnit)//是召唤物,找宿主.
                    {
                        temp = (attacker as XmdsVirtual_SummonUnit).GetPlayerUnit();

                        if (temp != null && temp is XmdsVirtual_Player)
                        {
                            AddHeirs(temp);
                        }
                    }
                }
                else
                {
                    bool isFinded = mHeirs.GetPlayerUUID() == attacker.GetPlayerUUID();
                    if(!isFinded)
                    {
                        if (mHeirs is XmdsVirtual_Player && attacker is XmdsVirtual_Player)
                        {
                            List<string> lt = mHeirs.TeamList as List<string>;
                            if(lt != null)
                            {
                                for (int i = 0; i < lt.Count; i++)
                                {
                                    if (attacker.GetPlayerUUID() == lt[i])
                                    {
                                        isFinded = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if(isFinded)
                    {
                        this.mSwithHeirsExpire.Reset();
                    }

                }

            }

            addTarget(attacker, threat);
        }

        public void AddTarget(XmdsVirtual zv)
        {
            addTarget(zv, 0);
        }

        /// <summary>
        /// 计算仇恨值.
        /// </summary>
        /// <param name="damage"></param>
        /// <param name="threatValue"></param>
        /// <returns></returns>
        private int CalThreatValue(int damage, int threatValue, int threatValuePer, int threatValueModify)
        {
            threatValue = threatValue + threatValuePer;

            int ret = 0;

            if (threatValue != 0)
            {
                ret = (int)(damage * (threatValue / XmdsSkillTemplate.DamageCalculator.XmdsDamageCalculator.PERER));
            }

            return ret;
        }
        /// <summary>
        /// 销毁仇恨系统.
        /// </summary>
        public void Dispose()
        {
            if (mAtkAssistantList != null)
            {
                mAtkAssistantList.Clear();
            }

            OnHandleTargetAddEvent = null;

            Clear();

            ClearSharedList();

            RemoveHeirs();

        }
        /// <summary>
        /// 取得继承人.
        /// </summary>
        /// <returns></returns>
        public InstanceUnit GetHeirs()
        {
            if (mHeirs != null)
            {
                return mHeirs.mUnit;
            }

            return null;
        }

        public void AddSharedList(string uuid)
        {
            if (mSharedList == null) { mSharedList = new List<string>(); }

            mSharedList.Add(uuid);
        }

        public List<string> GetSharedList()
        {
            return mSharedList;
        }

        public void ClearSharedList()
        {
            if (mSharedList != null)
            {
                mSharedList.Clear();
            }
        }

        public void CalAtkAssistantList(bool isShare)
        {
            if (mAtkAssistantList != null)
            {
                mAtkAssistantList.Clear();
            }
            else
            {
                mAtkAssistantList = new List<string>();
            }

            string uuid = null;
            //仇恨值大于0的单位.
            foreach (var info in unitMap)
            {
                if (info.Value.HateValue > 0)
                {
                    float dist = CMath.getDistance(Owner.X, Owner.Y, info.Value.Unit.X, info.Value.Unit.Y);

                    //单位在范围内.
                    if (dist <= XmdsConfig.Instance.SHARED_AWARD_MAX_RANGE)
                    {
                        uuid = ((info.Value.Unit.Virtual) as XmdsVirtual).GetPlayerUUID();
                        //过滤宠物、召唤单位宿主相同情况.
                        if (string.IsNullOrEmpty(uuid) == false && !mAtkAssistantList.Contains(uuid))
                        {
                            mAtkAssistantList.Add(uuid);
                        }
                    }
                }
            }

            //if(isShare)
            //{
            //    foreach (InstancePlayer info in this.Owner.Parent.AllPlayers)
            //    {
            //        float dist = CMath.getDistance(Owner.X, Owner.Y, info.X, info.Y);
            //        if (dist <= XmdsConfig.Instance.SHARED_AWARD_MAX_RANGE)
            //        {
            //            uuid = info.PlayerUUID;
            //            if (string.IsNullOrEmpty(uuid) == false && !mAtkAssistantList.Contains(uuid))
            //            {
            //                mAtkAssistantList.Add(uuid);
            //            }
            //        }
            //    }
            //}
        }

        public List<string> GetAtkAssistantList()
        {
            return mAtkAssistantList;
        }

        /// <summary>
        /// 设置指定单位仇恨值.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="threatValue"></param>
        public void SetHateInfo(uint id, long threatValue)
        {
            HateInfo ret = null;

            if (this.unitMap.TryGetValue(id, out ret))
            {
                ret.HateValue = threatValue;
            }
        }

		/// <summary>
		/// 添加仇恨对象,设置仇恨值.
		/// </summary>
		/// <param name="target"></param>
		/// <param name="threatValue"></param>
		private void SetHateInfo(XmdsVirtual target, long threatValue)
		{
			HateInfo ret = null;

			if (this.unitMap.TryGetValue(target.mUnit.ID, out ret))
			{
				//donothing.
			}
			else
			{
				//加入仇恨列表.
				ret = Add(target.mUnit);
			}
			//增加对应仇恨.
			ret.HateValue = threatValue;
		}

		public void ClearAllThreatValue()
        {
            if (unitMap != null)
            {
                foreach (var kvp in unitMap)
                {
                    kvp.Value.HateValue = 0;
                }
            }
        }
    }

}