using UnityEngine;

public class MenuKey : MonoBehaviour
{
    public AudioClip keyTurnOpen;

    public AudioClip keyTurnClose;

    public MenuCallbackHolder callbackHolder;

    private AudioSource audioSource;

    private Animator animator;

    private int currentRow = 0;

    private int targetRow = 0;

    private bool isTranslating = false;

    private bool triggered = false;

    private float translationElapsed = 0f;

    private float translationStartY = 0f;

    private float translationTargetY = 0f;

    private static float animationDuration = 0.45f;

    private static float[] rowPositions = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
 
    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        audioSource = GetComponent<AudioSource>();
        animator = GetComponent<Animator>();

        // Precompute the row positions based on the number of rows and the desired spacing.
        for (int i = 0; i < rowPositions.Length; i++)
        {
            rowPositions[i] = 1.462f - (i * 0.69f);
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (!isTranslating && currentRow != targetRow)
        {
            animator.SetTrigger("buttonChanged");

            translationElapsed = 0f;
            translationStartY = rowPositions[currentRow];
            translationTargetY = rowPositions[targetRow];
            isTranslating = true;
        }

        if (isTranslating)
        {
            translationElapsed += Time.deltaTime;

            float t = Mathf.Clamp01(translationElapsed / animationDuration);
            float easedT = EaseOutQuad(t);
            float y = Mathf.Lerp(translationStartY, translationTargetY, easedT);

            Vector3 position = transform.position;
            position.y = y;
            transform.position = position;

            if (t >= 1f)
            {
                currentRow = targetRow;
                isTranslating = false;

                position.y = translationTargetY;
                transform.position = position;

                animator.ResetTrigger("buttonChanged");
                animator.SetTrigger("inserted");
            }
        }
    }

    public void PlayKeyTurnOpen(int _)
    {
        audioSource.PlayOneShot(keyTurnOpen);
    }

    public void PlayKeyTurnClose(int _)
    {
        audioSource.PlayOneShot(keyTurnClose);
    }

    public void TranslateTo(int row)
    {
        targetRow = row;
    }

    public void OpenKey(bool trigger)
    {
        this.triggered = trigger;
        animator.ResetTrigger("buttonReleased");
        animator.SetTrigger("buttonClicked");
        if (!trigger)
            animator.SetBool("inButton", true);
    }

    public void CloseKey()
    {
        animator.SetBool("inButton", false);
    }

    public void ReleaseKey()
    {
        animator.ResetTrigger("buttonClicked");
        animator.SetTrigger("buttonReleased");
    }

    public void InvokeCallback()
    {
        if (!isTranslating)
        {
            callbackHolder.InvokeCallback(currentRow);
        }
    }

    public void TriggerCallback(int _)
    {
        if (!isTranslating && triggered)
        {
            triggered = false;
            callbackHolder.InvokeCallback(currentRow);
            ReleaseKey();
        }
    }

    private float EaseOutQuad(float t)
    {
        // Quadratic easing out - deceleration until the end
        return  1 - (1 - t) * (1 - t);
    }
}
