using UnityEngine;

[RequireComponent(typeof(Animator), typeof(SpriteRenderer))]
public class PlayerAnimation : MonoBehaviour
{
    [SerializeField] private Rigidbody2D body;
    [SerializeField] private PlayerDash dash;
    [SerializeField] private LayerMask groundLayers;
    [SerializeField] private bool artworkFacesRight = true;

    private Animator animator;
    private SpriteRenderer spriteRenderer;
    private static readonly int SpeedId = Animator.StringToHash("Speed");
    private static readonly int StateId = Animator.StringToHash("State");
    private readonly ContactPoint2D[] contacts = new ContactPoint2D[16];
    private ContactFilter2D groundFilter;

    private void Awake()
    {
        animator = GetComponent<Animator>();
        spriteRenderer = GetComponent<SpriteRenderer>();

        if (body == null || dash == null || groundLayers.value == 0)
        {
            Debug.LogError("PlayerAnimation: Body, Dash, Ground Layers를 연결하세요.", this);
            enabled = false;
            return;
        }

        groundFilter.SetLayerMask(groundLayers);
        groundFilter.useTriggers = false;
    }

    private void Update()
    {
        float horizontalSpeed = body.linearVelocity.x;
        animator.SetFloat(SpeedId, Mathf.Abs(horizontalSpeed));

        bool grounded = false;
        int count = body.GetContacts(groundFilter, contacts);
        for (int i = 0; i < count; i++)
        {
            // A wall or ceiling does not count as support under the player.
            if (contacts[i].normal.y > 0.5f && body.linearVelocity.y <= 0.01f)
            {
                grounded = true;
                break;
            }
        }

        // Idle 0, Move 1, Jump 2, Fall 3, Dash 4.
        int state;

        if (dash.IsDashing)
        {
            state = 4; // Dash: 대시 중
        }
        else if (grounded == false)
        {
            // 공중에서는 세로 속도로 상승과 낙하를 구분합니다.
            if (body.linearVelocity.y > 0.01f)
            {
                state = 2; // Jump: 위로 올라가는 중
            }
            else
            {
                state = 3; // Fall: 정점에 도달했거나 내려오는 중
            }
        }
        else
        {
            // 바닥에서는 가로 속도로 이동과 정지를 구분합니다.
            if (Mathf.Abs(horizontalSpeed) > 0.01f)
            {
                state = 1; // Move: 좌우로 이동 중
            }
            else
            {
                state = 0; // Idle: 서 있는 중
            }
        }

        animator.SetInteger(StateId, state);

        if (Mathf.Abs(horizontalSpeed) > 0.01f)
        {
            bool movingLeft = horizontalSpeed < 0f;

            if (artworkFacesRight)
            {
                spriteRenderer.flipX = movingLeft;
            }
            else
            {
                spriteRenderer.flipX = !movingLeft;
            }
        }
    }
}
