using UnityEngine;
using UnityEngine.InputSystem;

/// <summary>
/// Simple world pickup for bat or hammer. Uses Input System action "WeaponPickup" via WeaponManager to equip when in range.
/// Plays the pickup animation on the player, hides the world pickup, and shows the in-hand weapon.
/// Assumes the player already has WeaponManager and the weapon models hidden on hand.
/// </summary>
[RequireComponent(typeof(Collider))]
public class WeaponPickup : MonoBehaviour
{
    public enum PickupType { Bat, Hammer }
    public PickupType pickupType = PickupType.Bat;

    [Header("Pickup Settings")]
    public float pickUpRange = 2.5f;
    public Transform player;

    [Header("Input System")]
    [SerializeField] private string pickupActionName = "WeaponPickup";

    private bool _playerInTrigger;
    private PlayerInput _playerInput;
    private InputAction _pickupAction; // action named "WeaponPickup" in the input asset

    // Tracks the pickup the player is currently inside (single-player assumption)
    public static WeaponPickup currentPickupInRange;

    private void Reset()
    {
        var col = GetComponent<Collider>();
        col.isTrigger = true;
        // Ensure trigger events fire by having a kinematic Rigidbody on the pickup
        var rb = GetComponent<Rigidbody>();
        if (rb == null)
        {
            rb = gameObject.AddComponent<Rigidbody>();
        }
        rb.isKinematic = true;
        rb.useGravity = false;
    }

    private void OnEnable()
    {
        // Attempt to bind immediately if player is already assigned
        TryBindInput();
    }

    private void OnTriggerEnter(Collider other)
    {
        // Robustly detect the player even if a child collider enters
        var wm = other.GetComponentInParent<WeaponManager>();
        if (wm != null)
        {
            player = wm.transform;
            _playerInTrigger = true;
            currentPickupInRange = this;
            TryBindInput();
        }
    }

    private void OnTriggerExit(Collider other)
    {
        var wm = other.GetComponentInParent<WeaponManager>();
        if (wm != null && player == wm.transform)
        {
            _playerInTrigger = false;
            if (currentPickupInRange == this)
                currentPickupInRange = null;
        }
    }

    private void Update()
    {
        if (player == null)
        {
            // Lazy find player by component to be safer
            var wm = FindObjectOfType<WeaponManager>();
            if (wm != null) player = wm.transform;
        }

        // Ensure input is bound/enabled (even though we don't read it here)
        TryBindInput();

        // IMPORTANT: Do not handle input here. WeaponManager exclusively handles the WeaponPickup action.

        // Proximity fallback: if triggers fail, still allow pickup when close
        if (player != null)
        {
            bool near = Vector3.Distance(player.position, transform.position) <= pickUpRange;
            if (near)
            {
                currentPickupInRange = this;
            }
            else if (!_playerInTrigger && currentPickupInRange == this)
            {
                currentPickupInRange = null;
            }
        }
    }

    private void TryBindInput()
    {
        if (player == null) return;

        if (_playerInput == null)
        {
            _playerInput = player.GetComponent<PlayerInput>();
        }

        if (_playerInput == null) return;

        if (_pickupAction == null)
        {
            _pickupAction = _playerInput.actions?.FindAction(pickupActionName, false);
        }

        if (_pickupAction != null && !_pickupAction.enabled)
        {
            _pickupAction.SafeEnable();
        }
    }

    private void OnDisable()
    {
        // Keep action enabled via PlayerInput; only clear local refs
        if (currentPickupInRange == this)
            currentPickupInRange = null;
        _pickupAction = null;
        _playerInput = null;
    }

    // Expose for global handler (called by WeaponManager when button pressed and in range)
    public void TryEquip()
    {
        if (player == null) return;

        // Safety: ensure still in range and not holding a weapon
        bool inRange = _playerInTrigger || Vector3.Distance(player.position, transform.position) <= pickUpRange;
        var wm = player.GetComponent<WeaponManager>();
        if (!inRange || wm == null)
        {
            return;
        }
        if (wm.IsWeaponEquipped)
        {
            // Let WeaponManager handle dropping with the same button
            return;
        }

        // Play pickup animation if available
        var anim = player.GetComponent<AnimationManager>();
        if (anim != null)
        {
            anim.PlayAnimation(AnimationNames.WeaponPickup);
        }

        switch (pickupType)
        {
            case PickupType.Bat:
                wm.EquipWeaponFromPickup(WeaponManager.WeaponType.Bat, this);
                break;
            case PickupType.Hammer:
                wm.EquipWeaponFromPickup(WeaponManager.WeaponType.Hammer, this);
                break;
        }

        // Hide the world pickup (simulate taking it). You can pool/destroy instead.
        gameObject.SetActive(false);

        // Clear static reference if this was the current pickup
        if (currentPickupInRange == this)
            currentPickupInRange = null;
    }

    // Called by WeaponManager to place this pickup back into the world when dropping
    public void PlaceAsDropped(Transform playerTransform)
    {
        gameObject.SetActive(true);
        transform.position = playerTransform.position + Vector3.up * 0.25f;
        transform.rotation = Quaternion.Euler(0f, playerTransform.eulerAngles.y, 0f);

        // Prevent instant re-trigger by disabling collider briefly
        var col = GetComponent<Collider>();
        if (col != null)
        {
            StartCoroutine(DisableColliderBrief(col));
        }
    }

    private System.Collections.IEnumerator DisableColliderBrief(Collider col)
    {
        bool prev = col.enabled;
        col.enabled = false;
        yield return new WaitForSeconds(0.2f);
        col.enabled = prev;
    }
}
