using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;

[RequireComponent(typeof(Collider))]
public class WallInteractButton : MonoBehaviour
{
    [Header("Interaction")]
    [Tooltip("Key the player must press to interact (keyboard fallback).")]
    [SerializeField] private Key interactKey = Key.E;

    [Tooltip("If true, the button can only be triggered once.")]
    [SerializeField] private bool oneShot = false;

    [Header("Physical Press")]
    [Tooltip("Transform that moves to simulate a physical press (optional).")]
    [SerializeField] private Transform buttonMesh;

    [Tooltip("How far the button moves when pressed.")]
    [SerializeField] private float pressDepth = 0.05f;

    [Tooltip("Speed of the press/release animation.")]
    [SerializeField] private float pressSpeed = 10f;

    [Header("Events")]
    public UnityEvent OnInteract;

    private bool m_playerInRange;
    private bool m_used;

    private Vector3 m_buttonRestPos;
    private Vector3 m_buttonPressedPos;
    private bool m_isVisuallyPressed;

    private void Reset()
    {
        Collider col = GetComponent<Collider>();
        col.isTrigger = true;
    }

    private void Start()
    {
        if (buttonMesh != null)
        {
            m_buttonRestPos = buttonMesh.localPosition;
            m_buttonPressedPos = m_buttonRestPos - buttonMesh.localRotation * Vector3.forward * pressDepth;
        }
    }

    private void Update()
    {
        if (m_playerInRange && Keyboard.current != null && Keyboard.current[interactKey].wasPressedThisFrame)
        {
            TryInteract();
        }

        AnimateButton();
    }

    private void TryInteract()
    {
        if (oneShot && m_used)
            return;

        m_used = true;
        m_isVisuallyPressed = true;
        OnInteract?.Invoke();

        if (!oneShot)
            Invoke(nameof(ReleaseVisual), 0.15f);
    }

    private void ReleaseVisual()
    {
        m_isVisuallyPressed = false;
    }

    private void AnimateButton()
    {
        if (buttonMesh == null)
            return;

        Vector3 target = m_isVisuallyPressed ? m_buttonPressedPos : m_buttonRestPos;
        buttonMesh.localPosition = Vector3.Lerp(buttonMesh.localPosition, target, Time.deltaTime * pressSpeed);
    }

    private void OnTriggerEnter(Collider other)
    {
        if (IsPlayer(other))
            m_playerInRange = true;
    }

    private void OnTriggerExit(Collider other)
    {
        if (IsPlayer(other))
            m_playerInRange = false;
    }

    private bool IsPlayer(Collider other)
    {
        if (other.CompareTag("Player"))
            return true;

        if (other.GetComponentInParent<PlayerMovement>() != null)
            return true;

        return false;
    }

#if UNITY_EDITOR
    private void OnDrawGizmos()
    {
        Collider col = GetComponent<Collider>();
        if (col == null)
            return;

        Gizmos.matrix = transform.localToWorldMatrix;
        Gizmos.color = m_playerInRange
            ? new Color(0f, 1f, 0f, 0.25f)
            : new Color(1f, 0.9f, 0f, 0.15f);

        if (col is SphereCollider sphere)
        {
            Gizmos.DrawSphere(sphere.center, sphere.radius);
            Gizmos.color = m_playerInRange ? Color.green : Color.yellow;
            Gizmos.DrawWireSphere(sphere.center, sphere.radius);
        }
        else if (col is BoxCollider box)
        {
            Gizmos.DrawCube(box.center, box.size);
            Gizmos.color = m_playerInRange ? Color.green : Color.yellow;
            Gizmos.DrawWireCube(box.center, box.size);
        }
    }
#endif
}
