using System.Collections;
using UnityEngine;

public class SlimeWalk : MonoBehaviour
{
    [SerializeField] float moveSpeed = 3f;
    [SerializeField] float jumpHeight = 1f;
    [SerializeField] float jumpDuration = 0.4f;
    [SerializeField] Animator animator;

    static readonly int UpHash = Animator.StringToHash("Up");
    static readonly int DownHash = Animator.StringToHash("Down");
    static readonly int LeftHash = Animator.StringToHash("Left");
    static readonly int RightHash = Animator.StringToHash("Right");
    static readonly int IdleHash = Animator.StringToHash("Idle");
    static readonly int JumpHash = Animator.StringToHash("Jump");

    enum Dir { Idle, Up, Down, Left, Right }
    Dir lastDir = Dir.Idle;
    float jumpOffset;
    bool isJumping;

    void Awake()
    {
        if (animator == null) animator = GetComponent<Animator>();
    }

    void Update()
    {
        float x = 0f;
        float y = 0f;
        if (Input.GetKey(KeyCode.A)) x -= 1f;
        if (Input.GetKey(KeyCode.D)) x += 1f;
        if (Input.GetKey(KeyCode.W)) y += 1f;
        if (Input.GetKey(KeyCode.S)) y -= 1f;

        Vector3 move = new Vector3(x, y, 0f);
        if (move.sqrMagnitude > 1f) move.Normalize();
        transform.position += move * moveSpeed * Time.deltaTime;

        UpdateAnimation(x, y);

        if (Input.GetKeyDown(KeyCode.Space) && !isJumping)
        {
            if (animator != null) animator.SetTrigger(JumpHash);
            StartCoroutine(Jump());
        }
    }

    void UpdateAnimation(float x, float y)
    {
        if (animator == null) return;
        Dir newDir;
        if (x == 0f && y == 0f) newDir = Dir.Idle;
        else if (Mathf.Abs(x) >= Mathf.Abs(y)) newDir = x > 0f ? Dir.Right : Dir.Left;
        else newDir = y > 0f ? Dir.Up : Dir.Down;

        if (newDir == lastDir) return;
        lastDir = newDir;
        switch (newDir)
        {
            case Dir.Up: animator.SetTrigger(UpHash); break;
            case Dir.Down: animator.SetTrigger(DownHash); break;
            case Dir.Left: animator.SetTrigger(LeftHash); break;
            case Dir.Right: animator.SetTrigger(RightHash); break;
            default: animator.SetTrigger(IdleHash); break;
        }
    }

    IEnumerator Jump()
    {
        isJumping = true;
        float t = 0f;
        while (t < jumpDuration)
        {
            t += Time.deltaTime;
            float n = Mathf.Clamp01(t / jumpDuration);
            float newOffset = 4f * jumpHeight * n * (1f - n);
            transform.position += new Vector3(0f, newOffset - jumpOffset, 0f);
            jumpOffset = newOffset;
            yield return null;
        }
        transform.position -= new Vector3(0f, jumpOffset, 0f);
        jumpOffset = 0f;
        isJumping = false;
    }
}
