using UnityEngine;
using UnityEngine.InputSystem;
public class Grappling : MonoBehaviour
{
    [Header("References")]
    [SerializeField] private PlayerMovement pm;
    public Transform cam;
    public Transform gunTip;
    public LayerMask whatIsGrappleable;
    public LineRenderer lr;
    public GameObject hook;
    SoundManager sm;

    [Header("Grappling")]
    public float maxGrappleDistance;
    public float grappleDelayTime;
    public float overshootYAxis;

    private Vector3 grapplePoint;

    [Header("Cooldown")]
    public float grapplingCd;
    private float grapplingCdTimer;

    [Header("Input")]
    public InputActionReference grapplingKey;

    private bool grappling;

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {
        pm = GetComponent<PlayerMovement>();
        
    }

    // Update is called once per frame
    void Update()
    {
        if(grapplingKey.action.WasPressedThisFrame())
        {
            StartGrapple();
        }

        if(grapplingCdTimer > 0)
        {
            grapplingCdTimer -= Time.deltaTime;
        }
    }

    private void LateUpdate()
    {
        //if(grappling)
        //{
        //    lr.SetPosition(0, gunTip.position);
        //}
    }

    private void StartGrapple()
    {
        if(grapplingCdTimer > 0)
        {
            return;
        }
        grappling = true;

        pm.freeze = true;
        SoundManager.PlaySound(SoundType.HOOK_LAUNCH,0.5f);
        hook.SetActive(false);
        
        

        RaycastHit hit;
        if(Physics.Raycast(cam.position,cam.forward,out hit, maxGrappleDistance,whatIsGrappleable))
        {
            grapplePoint = hit.point;
            Invoke(nameof(ExecuteGrapple), grappleDelayTime);
        }
        else
        {
            grapplePoint = cam.position + cam.forward * maxGrappleDistance;
            Invoke(nameof(StopGrapple), grappleDelayTime);
        }

        //lr.enabled = true;
        //lr.SetPosition(1, grapplePoint);
    }

    private void ExecuteGrapple()
    {
        pm.freeze = false;
        SoundManager.PlaySound(SoundType.HOOK_HIT,0.5f);

        Vector3 lowestPoint = new Vector3(transform.position.x, transform.position.y - 1f, transform.position.z);
        float grapplePointRelativeYPos = grapplePoint.y - lowestPoint.y;
        float highestPointOnArc = grapplePointRelativeYPos + overshootYAxis;
        if(grapplePointRelativeYPos < 0)
        {
            highestPointOnArc = overshootYAxis;
        }
        

        pm.JumpToPosition(grapplePoint,highestPointOnArc);

        Invoke(nameof(StopGrapple), 1f);

    }
    
    public void StopGrapple()
    {
        pm.freeze = false;

        grappling = false;

        grapplingCdTimer = grapplingCd;

        //lr.enabled = false;
        hook.SetActive(true);
    }

    public bool IsGrappling()
    {
        return grappling;
    }

    public Vector3 GetGrapplePoint()
    {
        return grapplePoint;
    }

}
