using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using Sirenix.OdinInspector;

/// <summary>
/// 马背上人的控制类
/// </summary>
public class Person : MonoBehaviour
{
    public enum PersonState{
        Normal,//骑在马背
        Shoot,//从发射到着地平台
        Walk,//在平台行走
        FallingOff,//下落，从脱离平台到判定有结果前
        Recover,//判定成功到恢复到Normal的过程态
        Dead//判定失败后均为此态
    }

    /// <summary>
    /// 人此时的状态
    /// </summary>
    [Header("信息显示")]
    [Title("人此时的状态")]
    [EnumPaging()]
    public PersonState state;

    /// <summary>
    /// 人在人马分离障碍的平台上时的行走速度
    /// </summary>
    [FoldoutGroup("主要参数",true)]
    [Title("人在人马分离障碍的平台上时的行走速率")]
    public float walkSpeed = 1f;


    /// <summary>
    /// 人在人马分离障碍前，被抛出的速度
    /// </summary>
    [FoldoutGroup("附加参数",false)]
    [Title("人在人马分离障碍前，被抛出的速度")]
    public Vector2 throwingSpeed;
    
    [FoldoutGroup("附加参数",false)]
    [Title("人在离开平台时起跳的速度")]
    public Vector2 jumpSpeed;

    [FoldoutGroup("附加参数")][Title("人死后的飞出速度")]
    public Vector2 deadFlyVeloctiy;

    [FoldoutGroup("附加参数")][Title("人死后的飞出的旋转的角速度")]
    public float deadFlyRotateSpeed;

    /// <summary>
    /// 默认状态下的追踪点
    /// </summary>
    private Transform defaultTrackingPoint;

    private Rigidbody2D m_rigidbody2D;

    private Animator m_animator;


    void Start(){
    //Init
    //Init
    //Find
        defaultTrackingPoint = GameObject.Find("人的默认位置（不可改名）").transform;
        m_rigidbody2D = GetComponent<Rigidbody2D>();
        m_animator = GetComponentInChildren<Animator>();
    //Find
    }
    void Update(){
        //默认状态下的Update
        if(state == PersonState.Normal){
            //同步人和马的位置和旋转
            transform.position = defaultTrackingPoint.position;
            transform.rotation = defaultTrackingPoint.rotation;
        }
        //行走状态下的Update
        else if(state == PersonState.Walk){
            //让人向右移动
            transform.position += (Vector3.right * walkSpeed * Time.deltaTime);
        }
    }

    /// <summary>
    /// 人发射的瞬间触发一次，由人马分离障碍物触发
    /// </summary>
    public void Shoot(){
        Debug.Log("人发射");
        state = PersonState.Shoot;
        //给与刚体一个右上角的速度，使其刚好能抛到平台上
        m_rigidbody2D.velocity = throwingSpeed;
        //1秒内修正人的旋转
        transform.DORotate(new Vector3(0,0,0),1).OnComplete(
            //旋转修正结束后，锁定刚体Z轴旋转
            () => m_rigidbody2D.constraints = RigidbodyConstraints2D.FreezeRotation
        );
        //动画
        m_animator.SetTrigger("跳上");
    }

    /// <summary>
    /// 人接触到平台的瞬间触发，由人马分离障碍物触发
    /// </summary>
    public void Walk(){
        Debug.Log("人行走");
        state = PersonState.Walk;
        //动画
        m_animator.SetTrigger("跑步");
    }

    /// <summary>
    /// 人离开平台的瞬间触发，由人马分离障碍物触发
    /// </summary>
    public void FallingOff(){
        Debug.Log("人降落");
        state = PersonState.FallingOff;
        //给刚体一个右上的速度，模拟一下起跳
        m_rigidbody2D.velocity = jumpSpeed;
        //动画
        m_animator.SetTrigger("跳下");
    }

    public void Recover(){
        Debug.Log("人成功降落到马背");
        state = PersonState.Recover;
        //1秒内修正人的位置和旋转，与defaultTrackingPoint同步
        //后发现，由于追踪的动画终点是定好了的，但是马在这一秒还是会运动，会导致问题，所以这里把时间改短
        transform.DOMove(defaultTrackingPoint.position,0.2f);
        transform.DORotate(defaultTrackingPoint.rotation.eulerAngles,0.2f).OnComplete(
            () => state = PersonState.Normal
        );
        //动画
        m_animator.SetTrigger("恢复");
    }

    /// <summary>
    /// 由GameController触发，用于控制人死后的动作
    /// </summary>
    public void Death(GameController.Death deathInfo){
        state = PersonState.Dead;
        //让人和马一样，旋转着飞出去，同时关闭自身的碰撞体
        GetComponent<CapsuleCollider2D>().enabled = false;
        Rigidbody2D rigidbody2D = GetComponent<Rigidbody2D>();
        rigidbody2D.velocity = deadFlyVeloctiy;
        rigidbody2D.angularVelocity = deadFlyRotateSpeed;
    }

    private void OnCollisionEnter2D(Collision2D other) {
        //如果创到地面，且是在降落状态，则判定为游戏失败
        if(other.gameObject.tag == "Ground" && state == PersonState.FallingOff){
            GameController.Death death = new GameController.Death();
            death.deadReason = GameController.Death.DeadReason.PersonFall;
            GameController.Instance.GameOver(death);
            Debug.Log("人掉落到地面");
        }
    }









}
