using UnityEngine;
using UnityEngine.InputSystem;

interface IInteractable
{
    public void Interact();
}

public class Interactor : MonoBehaviour
{

    public float range = 0.5f;
    public Transform source;
    public InputActionReference interact;
    public Dialogue dialogue;
    [SerializeField] private Animator animator;
    [SerializeField] private GameObject interactHint;
    [SerializeField] private GameObject dialogueBox;


    void Awake()
    {
        interact.action.started += Interact;
    }


    private void Interact(InputAction.CallbackContext ctx)
    {
        if(!dialogue.textActive)
        {
            RaycastHit hit;

            Ray up = new Ray(source.position, new Vector3(0,0,1));
            Ray down = new Ray(source.position, new Vector3(0,0,-1));
            Ray left = new Ray(source.position, new Vector3(-1,0,0));
            Ray right = new Ray(source.position, new Vector3(1,0,0));

            // boolean so that interactions are not detected twice
            bool foundInteract = false;
            
            if(Physics.Raycast(up, out hit, range) && !foundInteract && animator.GetBool("facingBack"))
            {
                if(hit.collider.gameObject.TryGetComponent(out IInteractable obj))
                {
                    obj.Interact();
                    foundInteract = true;
                }
            }
            if(Physics.Raycast(down, out hit, range) && !foundInteract && !animator.GetBool("facingBack"))
            {
                if(hit.collider.gameObject.TryGetComponent(out IInteractable obj))
                {
                    obj.Interact();
                    foundInteract = true;
                }
            }
            if(Physics.Raycast(left, out hit, range) && !foundInteract && animator.GetBool("facingSide"))
            {
                if(hit.collider.gameObject.TryGetComponent(out IInteractable obj))
                {
                    obj.Interact();
                    foundInteract = true;
                }
            }
            if(Physics.Raycast(right, out hit, range) && !foundInteract && animator.GetBool("facingSide"))
            {
                if(hit.collider.gameObject.TryGetComponent(out IInteractable obj))
                {
                    obj.Interact();
                }
            }
        }
    }

    void Update()
    {
        RaycastHit hit;

        // continuously cast rays in cardinal directions
        Ray up = new Ray(source.position, new Vector3(0,0,1));
        Ray down = new Ray(source.position, new Vector3(0,0,-1));
        Ray left = new Ray(source.position, new Vector3(-1,0,0));
        Ray right = new Ray(source.position, new Vector3(1,0,0));

        // boolean so that interactions are not detected twice
        bool foundInteract = false;
    
        // display interact hint
        if(Physics.Raycast(up, out hit, range) && !foundInteract && animator.GetBool("facingBack") && !dialogueBox.activeSelf)
        {
            if(hit.collider.gameObject.TryGetComponent(out IInteractable obj))
            {
                interactHint.SetActive(true);
                foundInteract = true;
            }
        }
        else if(Physics.Raycast(down, out hit, range) && !foundInteract && !animator.GetBool("facingBack") && !dialogueBox.activeSelf)
        {
            if(hit.collider.gameObject.TryGetComponent(out IInteractable obj))
            {
                interactHint.SetActive(true);
                foundInteract = true;
            }
        }
        else if(Physics.Raycast(left, out hit, range) && !foundInteract && animator.GetBool("facingSide") && !dialogueBox.activeSelf)
        {
            if(hit.collider.gameObject.TryGetComponent(out IInteractable obj))
            {
                interactHint.SetActive(true);
                foundInteract = true;
            }
        }
        else if(Physics.Raycast(right, out hit, range) && !foundInteract && animator.GetBool("facingSide") && !dialogueBox.activeSelf)
        {
            if(hit.collider.gameObject.TryGetComponent(out IInteractable obj))
            {
                interactHint.SetActive(true);
            }
        }
        else
        {
            interactHint.SetActive(false);
        }
    }
}
