using System.Collections;
using UnityEngine;

public class GrappleGun : Tool
{
    [Header("Grapple Gun Parameters")]
    public float range;
    public float hookStickTime;
    public GameObject hook;

    bool isMoving = false;
    bool stuckInTarget = false;
    private Vector3 hookBaseLocation;
    private Transform hookParent;

    private void Start()
    {
        hookBaseLocation = hook.transform.localPosition;
        hookParent = hook.transform.parent;
    }

    IEnumerator GoToTarget(Vector3 target)
    {
        GameManager.Instance.PlayerController.SetCharacterControl(false);
        isMoving = true;
        Vector3 startPosition = hook.transform.position;
        float elapsedTime = 0f;

        while (elapsedTime < hookStickTime)
        {
            float t = elapsedTime / hookStickTime;
            hook.transform.position = Vector3.Lerp(startPosition, target, t);
            elapsedTime += Time.deltaTime;
            yield return null;
        }

        // Ensure final position is exact
        hook.transform.position = target;
        hook.transform.parent = null;
        isMoving = false;
        stuckInTarget = true;

        StartCoroutine(MovePlayerToTarget(target));
    }

    IEnumerator MovePlayerToTarget(Vector3 target)
    {
        Transform player = GameManager.Instance.PlayerController.transform;
        Vector3 startPosition = player.position;
        float elapsedTime = 0f;

        while (elapsedTime < hookStickTime)
        {
            float t = elapsedTime / hookStickTime;
            player.position = Vector3.Lerp(startPosition, target, t);
            elapsedTime += Time.deltaTime;
            yield return null;
        }

        // Ensure final position is exact
        player.position = target;
        stuckInTarget = false;

        hook.transform.parent = hookParent;
        hook.transform.localPosition = hookBaseLocation;
        isMoving = false;
        stuckInTarget = false;

        GameManager.Instance.PlayerController.SetCharacterControl(true);
    }

    IEnumerator ShootAndMiss()
    {
        GameManager.Instance.PlayerController.SetCharacterControl(false);

        isMoving = true;

        // move to edge of range and don't stick anywhere
        Vector3 startPosition = hook.transform.position;
        Vector3 target = transform.position + (transform.forward * range);
        float elapsedTime = 0f;

        while (elapsedTime < hookStickTime)
        {
            float t = elapsedTime / hookStickTime;
            hook.transform.position = Vector3.Lerp(startPosition, target, t);
            elapsedTime += Time.deltaTime;
            yield return null;
        }

        hook.transform.localPosition = hookBaseLocation;
        isMoving = false;
        stuckInTarget = false;

        GameManager.Instance.PlayerController.SetCharacterControl(true);
    }

    public override void Use()
    {
        if (stuckInTarget || isMoving)
        {
            StopAllCoroutines();
            hook.transform.parent = hookParent;
            hook.transform.localPosition = hookBaseLocation;
            isMoving = false;
            stuckInTarget = false;

            GameManager.Instance.PlayerController.SetCharacterControl(true);
        }
        else
        {
            RaycastHit hit;
            if (Physics.Raycast(transform.position, transform.forward, out hit, range))
            {
                StartCoroutine(GoToTarget(hit.point));
            }
            else
            {
                StartCoroutine(ShootAndMiss());
            }
        }  
    }

    public override void UseAlt()
    {
        throw new System.NotImplementedException();
    }
}
