using System;
using System.Collections.Generic;
using UnityEngine;


public abstract partial class RoleEntity : CapsuleColliderEntity
{
    public const float roleDefaultSpeed = 3f;
    
    [SerializeField]
    protected long m_PlayerId;
    public long playerId=> m_PlayerId;
    
    protected int m_RoleId;
    public int roleId => m_RoleId;

    [SerializeField]
    protected float m_Speed = roleDefaultSpeed;
    public float speed
    {
        get { return m_Speed; }
        set { m_Speed = value; }
    }

    protected Vector3 m_MoveVec;
    public Vector3 moveVec => m_MoveVec;

    /// <summary>
    /// 可视范围
    /// </summary>
    private float m_VisiableRange = 3f;
    public float visiableRange => m_VisiableRange;

    /// <summary>
    /// 可视角度
    /// </summary>
    private float m_VisiableAngle = 180;
    public float visiableAngle => m_VisiableAngle;
    
    /// <summary>
    /// 角色朝向
    /// </summary>
    public Vector2 roleOrientation
    {
        get
        {
            Vector3 dir = transform.TransformDirection(Vector3.forward);
            return new Vector2(dir.x,dir.z).normalized;
        }
    }


    /// <summary>
    /// 动作状态机
    /// </summary>
    protected ActionFSMSystem m_ActionFSMSystem;

    /// <summary>
    /// 当前动作
    /// </summary>
    public ActionFSMState curAction => m_ActionFSMSystem?.CurrentState as ActionFSMState;

    
    protected List<BattleBuff> m_Buffs = new List<BattleBuff>();
    /// <summary>
    /// 该玩家的buff列表
    /// </summary>
    public List<BattleBuff> buffs { get { return m_Buffs; } }
    
    /// <summary>
    /// hp
    /// </summary>
    protected int m_Hp = maxHp;
    public int hp => m_Hp;

    public const int maxHp = 1;
    
    /// <summary>
    /// 是否死亡
    /// </summary>
    public bool dead => hp <= 0;
    
    public virtual int memberId { get; }
    
    /// <summary>
    /// 无敌
    /// </summary>
    public bool unbeatable { get; set; }
    
    /// <summary>
    /// 是否使用插件来移动
    /// </summary>
    protected bool m_UsePluginMove = false;
    public bool usePluginMove => m_UsePluginMove;
    
    /// <summary>
    /// 是否已移动过
    /// </summary>
    public bool hasMoved { get; set; }
    
    /// <summary>
    /// 实际移动
    /// </summary>
    private Vector3 m_RealMoveVec;
    public Vector3 realMoveVec => m_RealMoveVec;
    
    /// <summary>
    /// 前一帧的位置
    /// </summary>
    private Vector3 m_PrePos;
    
    public void Init(int roleId)
    {
        m_RoleId = roleId;
    }

    protected override void Awake()
    {
        base.Awake();
        InitView();
    }
    
    protected virtual void Start()
    {
    }

    /// <summary>
    /// 添加buff
    /// </summary>
    /// <param name="buff"></param>
    public void AddBuff(BattleBuff buff)
    {
        m_Buffs.Add(buff);
    }

    
    protected void SetMoveVec(Vector3 moveVec)
    {
        m_MoveVec = moveVec;
    }

    public virtual void StopMove()
    {
        GameDebug.LogError($"{name} stop move");
        m_MoveVec = Vector3.zero;
        
        //m_Rigidbody.velocity = Vector3.zero;
        var vel = m_Rigidbody.velocity;
        vel.x = vel.z = 0;
        m_Rigidbody.velocity = vel;
    }
    
    /// <summary>
    /// 朝向某位置
    /// </summary>
    /// <param name="targetPos"></param>
    /// <returns></returns>
    public Quaternion FocusTo(Vector3 targetPos)
    {
        var dir = targetPos - transform.position;
        dir.y = 0;

        if (dir.magnitude < 0.001f)
            return Quaternion.identity;
        
        return Quaternion.LookRotation(dir, Vector3.up);
        //transform.rotation = Quaternion.LookRotation(dir, Vector3.up);
        //return transform.rotation.eulerAngles;
    }
    
    public static bool CheckPosVisiable(Vector2 pos, Vector2 lookFromPos, Vector2 lookAtDir, float range,
       float innerRange, float radian)
    {
        Vector2 targetDir = pos - lookFromPos;

        if (targetDir.magnitude > range || targetDir.magnitude < innerRange)
            return false;

        targetDir = targetDir.normalized;

        float dot = Vector2.Dot(targetDir, lookAtDir);

        if (dot < 0)
            return false;
        
        float temp = (targetDir.magnitude * lookAtDir.magnitude);
        if (temp != 0)
        {
            float aCos = dot / temp;
        
            aCos = aCos < -1 ? -1 : aCos;
            aCos = aCos > 1 ? 1 : aCos;

            float r = Mathf.Acos(aCos);// FixedMath.Acos(aCos);
            
//            GameDebug.LogError($"dot:{dot}  aCos:{aCos}  r:{r}");
            if (r <= radian)
                return true;
        }
        
        return false;
    }

    public void InputActionSign(int sign)
    {
        if (m_ActionFSMSystem != null)
        {
            m_ActionFSMSystem.InputSign(sign);
        }
        else
        {
            GameDebug.LogError($"m_ActionFSMSystem is null");
        }
    }
    
    
    /// <summary>
    /// 复活
    /// </summary>
    public virtual  void Revive(Vector3 pos)
    {
        if(capsuleCollider)
            this.capsuleCollider.enabled = true;

        this.m_Hp = maxHp;
        
    }
    
    

    /*public void SetPosition(Vector3 pos)
    {
        if (m_UsePluginMove)
        {
            if (this.m_rc)
                m_rc.SetPosition( pos);
        }
        
        transform.position = pos;
    }*/

        
    /// <summary>
    /// 收到致命一击
    /// </summary>
    /// <param name="attacker"></param>
    public void ReceiveDeadlyDamage(RoleEntity attacker)
    {
        ReceiveDamage(attacker, this.hp);
    }
    public void ReceiveDamage(RoleEntity attacker,int damage)
    {
        if (unbeatable)
        {
            GameDebug.Log($"免疫", "ReceiveDamage", "PlayerEntity", 1834, this.playerId, this.name);
            return;
        }

        //GameDebug.LogError("ReceiveDamage");
        // 添加显示buff
        BattleBuffDamage buffLifeTime = new BattleBuffDamage(this.battleController,this, 1, attacker,this,damage);
        this.AddBuff(buffLifeTime);
        
        this.ReceiveDamage(buffLifeTime);
    }

    public void ReceiveDamage(int damage)
    {
        ReceiveDamage(null, damage);
    }
    
    void ReceiveDamage(BattleBuffDamage lifeTimeDamage)
    {
        // 行为跳转
        this.InputActionSign(PlayerState.byHit);

        // 计算血量
        m_Hp -= lifeTimeDamage.damage;

        // 范围限定
        if (m_Hp < 0)
        {
            m_Hp = 0;
        }
        else if (m_Hp > maxHp)
        {
            m_Hp = maxHp;
        }

        //GameDebug.Log("damage: " + damage + ", hp: " + m_Hp);
    }
    
    protected virtual void Update()
    {
        //更新动作
        if (m_ActionFSMSystem != null)
        {  
            //GameDebug.LogError($"m_ActionFSMSystem  Update"); 
            m_ActionFSMSystem.Update();
            
        }
        else
        {
            GameDebug.LogError($"m_ActionFSMSystem is null");
        }
        
        //更新Buff
        for (int i = 0; i < m_Buffs.Count;)
        {
            if (m_Buffs[i].expired)
            {
                m_Buffs[i].OnExpired();
                m_Buffs.RemoveAt(i);
            }
            else
            {
                m_Buffs[i++].Update();
            }
        }

        if (Time.frameCount % 2 == 0)
        {
           
            Vector3 moveVec = transform.position - m_PrePos;

            if (moveVec.sqrMagnitude > 0.0001f) //0.000000000001f)
            {
                this.m_RealMoveVec = moveVec;
                //this.m_MoveVec = moveVec * 10; // moveVec.normalized * this.m_Speed / 2;
            }
            else
            { 
                this.m_RealMoveVec = Vector3.zero;
                //this.m_MoveVec = Vector3.zero;
            }  
               
            m_PrePos = transform.position;
        }

    }

    private void LateUpdate()
    {
        this.ViewUpdate();
    }
}