using System;
using Grid;
using UnityEngine;
using UnityEngine.Serialization;

public class GrenadeProjectile : MonoBehaviour {
    private const float moveSpeed = 15f;
    private const float reachedTargetDistance = 2f;
    private const float damageRadius = 4f;
    private const float damage = 200f;

    [SerializeField] private Transform grenadeExplodeVfxPrefab;
    [SerializeField] private TrailRenderer trailRenderer;

    [FormerlySerializedAs("ArcYAnimationCurve")] [SerializeField]
    private AnimationCurve arcYAnimationCurve;

    private Action onGrenadeBehaviourComplete;
    private Vector3 positionXZ;

    private Vector3 targetPosition;
    private float totalDistance;

    private void Update() {
        Vector3 moveDir = (targetPosition - transform.position).normalized;
        positionXZ += moveSpeed * Time.deltaTime * moveDir;

        float distance = Vector3.Distance(positionXZ, targetPosition);
        float distanceNormalized = 1 - distance / totalDistance;

        float maxHeight = totalDistance / 4f;
        float positionY = arcYAnimationCurve.Evaluate(distanceNormalized) * maxHeight;
        transform.position = new(positionXZ.x, positionY, positionXZ.z);

        if (!(Vector3.Distance(positionXZ, targetPosition) < reachedTargetDistance * maxHeight)) return;

        Collider[] hitColliderArray = Physics.OverlapSphere(targetPosition, damageRadius);
        foreach (Collider hitCollider in hitColliderArray) {
            if (hitCollider.TryGetComponent(out Unit targetUnit)) targetUnit.Damage(30);
            if (hitCollider.TryGetComponent(out IDestructable destructable)) destructable.Damage(damage);
        }

        OnAnyGrenadeExploded?.Invoke(this, EventArgs.Empty);
        trailRenderer.transform.parent = null;
        Instantiate(grenadeExplodeVfxPrefab, targetPosition + Vector3.up * 1f, Quaternion.identity);
        Destroy(gameObject);
        onGrenadeBehaviourComplete();
    }

    public static event EventHandler OnAnyGrenadeExploded;

    public void Setup(GridPosition targetGridPosition, Action newGrenadeBehaviourComplete) {
        onGrenadeBehaviourComplete = newGrenadeBehaviourComplete;
        targetPosition = LevelGrid.Instance.GetWorldPosition(targetGridPosition);
        positionXZ = transform.position;
        positionXZ.y = 0;
        totalDistance = Vector3.Distance(positionXZ, targetPosition);
    }
}