using System.Collections.Generic;
using Thousandto.Cfg.Data;
using Thousandto.Code.Center;
using Thousandto.Code.Global;
using Thousandto.Core.Asset;
using UnityEngine;

namespace Thousandto.Code.Logic
{
    //主角宠物
    public class LocalPet : Pet
    {
        #region//私有变量
        private AIState _aiState = AIState.Count;
        private Vector2 _moveTarget2D = Vector2.zero;
        private DeclareSkill _skillCfg = null;
        private float _sqrUseDis = 0f;
        private float _useDis = 0f;
        //技能CD
        private float _skillCDTimer = 0f;
        //当前选择的目标Id
        private ulong _curSelectedTargetId = 0;

        //助战宠物id列表
        private List<ulong> _assistPetList = new List<ulong>();
        //载入助战宠物等待帧数
        private int _assistLoadWairFrame = 0;
        #endregion

        #region//继承基类
        protected override bool OnInitializeAfter(EntityInitInfo baseInfo)
        {
            _assistLoadWairFrame = 10;
            GameCenter.RegFixEventHandle(LogicEventDefine.EID_EVENT_REFRESH_ASSIST_PET, OnAssistPetChanged);
            return base.OnInitializeAfter(baseInfo);
        }
        protected override void OnUninitializeBefore()
        {
            UnLoadAssistPet();
            base.OnUninitializeBefore();
            GameCenter.UnRegFixEventHandle(LogicEventDefine.EID_EVENT_REFRESH_ASSIST_PET, OnAssistPetChanged);
        }
        protected override void OnUpdate(float elapsedTime)
        {
            if (_skillCDTimer > 0f)
            {
                _skillCDTimer -= elapsedTime;
            }
            UpdateState();
            if(_assistLoadWairFrame > 0)
            {
                --_assistLoadWairFrame;
                if(_assistLoadWairFrame <= 0)
                {
                    LoadAssistPet();
                }
            }
            base.OnUpdate(elapsedTime);
        }
        public override bool IsLocalPet()
        {
            return true;
        }
        #endregion

        #region//私有函数
        private bool CheckSkill()
        {
            if (_skillCfg != null && _sqrUseDis > 0f)
            {
                return true;
            }
            _skillCfg = DeclareSkill.Get(PropMoudle.Cfg.Baseskill);
            if (_skillCfg == null)
            {
                return false;
            }
            var visCfg = GameCenter.SkillVisualManager.Find(_skillCfg.VisualDef);
            if (visCfg == null)
            {
                _skillCfg = null;
                return false;
            }
            _useDis = CombatUtil.GetSkillFindPathDis(visCfg);
            _sqrUseDis = _useDis * _useDis;
            return true;
        }
        private bool CanMove()
        {
            if (skillManager.IsSkillUseing())
                return false;
            return true;
        }
        private void ChangeState(AIState state)
        {
            if (_aiState == state)
                return;
            OnStateLeave(_aiState);
            _aiState = state;
            OnStateEnter(_aiState);
        }
        private void UpdateState()
        {
            switch (_aiState)
            {
                case AIState.Idle:
                    {
                        var lp = GameCenter.GameSceneSystem.GetLocalPlayer();
                        if (lp != null)
                        {
                            if (!lp.IsDead() && lp.FightState && lp.GetCurSelectedTarget() != null && CheckSkill())
                            {
                                //主角正在战斗状态
                                ChangeState(AIState.Fight);
                            }
                            else if (Vector2.SqrMagnitude(Position2d - lp.Position2d) < 1f && CanMove())
                            {
                                //距离太近,走远一点
                                var dir = -lp.GetFacingDirection2d();
                                _moveTarget2D = lp.Position2d + dir.normalized * 2;
                                ChangeState(AIState.Follow);
                                break;
                            }
                            else if (Vector2.SqrMagnitude(Position2d - lp.Position2d) > 9f && CanMove())
                            {
                                //距离太远,走近一点
                                var dir = -lp.GetFacingDirection2d();
                                _moveTarget2D = lp.Position2d + dir.normalized * 2;
                                ChangeState(AIState.Follow);
                            }
                        }
                    }
                    break;
                case AIState.Follow:
                    {
                        var lp = GameCenter.GameSceneSystem.GetLocalPlayer();
                        if (lp != null)
                        {
                            if (Vector2.SqrMagnitude(Position2d - lp.Position2d) > 400f)
                            {
                                Stop_Action(false);
                                var dir = -lp.GetFacingDirection2d();
                                var targetPos = lp.Position2d + dir.normalized * 2;
                                if (Scene.navigator.IsBlocked(targetPos))
                                {
                                    RayCastToGroundXOZ(lp.Position2d);
                                }
                                else
                                {
                                    RayCastToGroundXOZ(targetPos);
                                }
                                //与玩家的距离超过了20米,直接瞬移
                                NetHandler.SendMessage_PetJumpBlock(Position2d.x, Position2d.y);
                            }
                            else if (!lp.IsDead() && lp.FightState && lp.GetCurSelectedTarget() != null && CheckSkill())
                            {
                                //主角正在战斗状态
                                ChangeState(AIState.Fight);
                            }
                            else if (CanMove())
                            {
                                if (!IsMoving())
                                {
                                    if (Vector2.SqrMagnitude(Position2d - lp.Position2d) > 9f)
                                    {
                                        //距离太远,走近一点
                                        var dir = -lp.GetFacingDirection2d();
                                        _moveTarget2D = lp.Position2d + dir.normalized * 2;
                                        Action_MoveTo(new Vector3(_moveTarget2D.x, 0f, _moveTarget2D.y), 0.5f);
                                    }
                                    else
                                    {
                                        ChangeState(AIState.Idle);
                                    }
                                }
                                else
                                {
                                    //如果快到目标点了计算是否继续移动,主要为了防止宠物行走卡顿
                                    var moveState = Fsm.CurrentState as PathMove;
                                    if (moveState != null)
                                    {
                                        if (Vector2.SqrMagnitude(Position2d - moveState.CurPathTarget) <= 1f && Vector2.SqrMagnitude(Position2d - lp.Position2d) > 9f)
                                        {
                                            //距离太远,走近一点
                                            var dir = -lp.GetFacingDirection2d();
                                            _moveTarget2D = lp.Position2d + dir.normalized * 2;
                                            Action_MoveTo(new Vector3(_moveTarget2D.x, 0f, _moveTarget2D.y), 0.5f);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;
                case AIState.Fight:
                    {
                        var lp = GameCenter.GameSceneSystem.GetLocalPlayer();
                        if (lp != null)
                        {
                            if (!lp.FightState || lp.IsDead())
                            {
                                ChangeState(AIState.Idle);
                            }
                            else if (!skillManager.IsSkillUseing())
                            {
                                //查找主目标
                                var target = lp.GetCurSelectedTarget();
                                if (target != null && CombatUtil.CanAttackTarget(lp, target, false))
                                {
                                    SetCurSelectedTargetId(target.ID);
                                    //判断是否在技能范围内
                                    if (Vector2.SqrMagnitude(Position2d - target.Position2d) > _sqrUseDis)
                                    {
                                        //不在范围
                                        if (!IsMoving() && CanMove())
                                        {
                                            Action_MoveTo(target.Position, _useDis * 0.9f);
                                        }
                                    }
                                    else
                                    {
                                        if (!IsMoving())
                                        {
                                            if (_skillCDTimer <= 0f)
                                            {
                                                //使用技能
                                                skillManager.LocalPetUseSkill(_skillCfg);
                                                _skillCDTimer = _skillCfg.Cd / 1000f;
                                            }
                                        }
                                        else if (!target.IsMoving())
                                        {
                                            //如果目标没有移动了,停止移动
                                            Stop_Action(true);
                                        }
                                    }
                                }
                                else if (Vector2.SqrMagnitude(Position2d - lp.Position2d) > 9f && CanMove() && !IsMoving())
                                {
                                    //跟随一下
                                    var dir = -lp.GetFacingDirection2d();
                                    _moveTarget2D = lp.Position2d + dir.normalized * 2;
                                    Action_MoveTo(new Vector3(_moveTarget2D.x, 0f, _moveTarget2D.y), 0.5f);
                                }
                            }
                        }
                    }
                    break;
                case AIState.Count:
                    {
                        ChangeState(AIState.Idle);
                    }
                    break;
            }
        }
        private void OnStateEnter(AIState state)
        {
            switch (state)
            {
                case AIState.Idle:
                    {

                    }
                    break;
                case AIState.Follow:
                    {
                        Action_MoveTo(new Vector3(_moveTarget2D.x, 0f, _moveTarget2D.y), 0.5f);
                    }
                    break;
                case AIState.Fight:
                    {

                    }
                    break;
            }
        }
        private void OnStateLeave(AIState state)
        {
            switch (state)
            {
                case AIState.Idle:
                    {

                    }
                    break;
                case AIState.Follow:
                    {
                    }
                    break;
                case AIState.Fight:
                    {

                    }
                    break;
                case AIState.Count:
                    {

                    }
                    break;
            }
        }
        #endregion

        #region//目标选择
        //获取当前目标
        public Character GetCurSelectedTarget()
        {
            if (_curSelectedTargetId == 0 || Scene == null)
            {
                return null;
            }
            Character target = Scene.Find<Character>(_curSelectedTargetId);
            return target;
        }

        //设置当前目标,
        //当id==0是表示取消选择目标,id!=0但是没有找到目标的情况下不做任何操作
        public bool SetCurSelectedTargetId(ulong id, bool isAuto = true)
        {
            if (id == 0)
            {
                _curSelectedTargetId = 0;
                return true;
            }
            else
            {
                Character newTarget = Scene.Find<Character>(id);
                //重复选择
                if (id == _curSelectedTargetId || Scene == null)
                {
                    return true;
                }
                if (newTarget != null && !newTarget.IsDead() && newTarget.CanBeSelect)
                {
                    _curSelectedTargetId = id;
                    return true;
                }
            }
            return false;
        }

        public void UpdateTarget()
        {
            //如果当前有选择的目标ID但是查找不到目标对象,丢失目标
            if (_curSelectedTargetId > 0)
            {
                Character target = GetCurSelectedTarget();
                if (target == null || target.IsDead() || !target.CanBeSelect)
                {
                    SetCurSelectedTargetId(0);
                }
            }
        }
        #endregion

        #region//助战宠物
        //助战宠物列表改变
        private void OnAssistPetChanged(object obj, object sender)
        {
            LoadAssistPet();
        }
        //排序
        private int AssistRank(DeclarePet left, DeclarePet right)
        {
            return left.FllowRank.CompareTo(right.FllowRank);
        }
        //载入助战宠物
        public void LoadAssistPet()
        {
            UnLoadAssistPet();
            var idList = GameCenter.LuaSystem.Adaptor.GetAssistPetList();
            if (idList == null)
                return;
            var cfgList = new List<DeclarePet>();
            for(int i = 0; i < idList.Length; ++i)
            {
                cfgList.Add(DeclarePet.Get((int)idList[i]));
            }
            cfgList.Sort(AssistRank);
            Entity fllowEntity = this;
            for(int i = 0; i < cfgList.Count; ++i)
            {
                var petInfo = new AssistPetInitInfo(cfgList[i], fllowEntity);
                GameCenter.GameSceneSystem.RefreshAssistPet(petInfo);
                var newPet = GameCenter.GameSceneSystem.FindEntity<Entity>(petInfo.ID);
                if(newPet != null)
                {
                    fllowEntity = newPet;
                    _assistPetList.Add(petInfo.ID);
                }
            }
        }
        //协助助战宠物
        public void UnLoadAssistPet()
        {
            for(int i = 0; i < _assistPetList.Count; ++i)
            {
                GameCenter.GameSceneSystem.RemoveRemoteEntity(_assistPetList[i]);
            }
            _assistPetList.Clear();
        }
        #endregion

        #region//私有类
        private enum AIState
        {
            Idle,
            Follow,
            Fight,
            Count,
        }
        #endregion
    }
}