using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.XR.Interaction.Toolkit;

public class LeverController : MonoBehaviour
{
    private Transform pivot; //The lever will use a pivot point
    private Transform grabHand;
    private bool leverGrabbed;
    private bool eventCalled;
    private bool leverDown;

    private Vector3 handDelta;
    private Vector3 lastPosition;

    //These UnityEvent objects can be set in the inspector as any public methods from scripts
    [SerializeField]
    private UnityEvent onUp;
    [SerializeField]
    private UnityEvent onDown;

    public float minAngle = 20f;
    public float maxAngle = 75f;

    public float hapticAmplitude = 1f;
    public float hapticDuration = 0.1f;

    public AudioSource upSound;
    public AudioSource downSound;

    //This script cannot work with multiplayer, see CheckHand() method
    public Transform leftHand;
    public Transform rightHand;

    void Awake()
    {
        pivot = transform.parent;
        leverGrabbed = false;
        leverDown = false;
        pivot.eulerAngles = new Vector3(pivot.eulerAngles.x, pivot.eulerAngles.y, minAngle);
        leftHand = GameObject.Find("LeftHand Controller").transform;
        rightHand = GameObject.Find("RightHand Controller").transform;
    }

    void Update()
    {
        if (leverGrabbed)
        {
            handDelta = lastPosition - grabHand.position; //The vector of hand movement between frames
            pivot.RotateAround(pivot.position, pivot.forward, 200 * handDelta.y); //Is a Time.deltaTime multiplication needed here?

            //Two following if statements set the up and down position angles and call events when angle is met
            //Only one event is called per grab because the logic is in the update method
            if(pivot.eulerAngles.z < minAngle)
            {
                pivot.eulerAngles = new Vector3(pivot.eulerAngles.x, pivot.eulerAngles.y, minAngle);
                if (leverDown)
                {
                    onUp.Invoke();
                    grabHand.gameObject.GetComponent<ActionBasedController>().SendHapticImpulse(hapticAmplitude, hapticDuration);
                    if (upSound != null) upSound.Play();
                    leverDown = false;
                }
            } 
            else if(pivot.eulerAngles.z > maxAngle)
            {
                pivot.eulerAngles = new Vector3(pivot.eulerAngles.x, pivot.eulerAngles.y, maxAngle);
                if (!leverDown)
                {
                    onDown.Invoke();
                    grabHand.gameObject.GetComponent<ActionBasedController>().SendHapticImpulse(hapticAmplitude, hapticDuration);
                    if (downSound != null) downSound.Play();
                    leverDown = true;
                }
            }

            lastPosition = grabHand.position;
        }
    }

    public void GrabLever()
    {
        CheckHand();
        leverGrabbed = !leverGrabbed;
        handDelta = Vector3.zero;
        lastPosition = grabHand.position;
        eventCalled = false;
    }

    private void CheckHand()
    {
        float leftDistance = Vector3.Distance(leftHand.position, transform.position);
        float rightDistance = Vector3.Distance(rightHand.position, transform.position);

        if (leftDistance > rightDistance) grabHand = rightHand; 
        else grabHand = leftHand;
    }

    
}