using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace ToolsBox.Collider
{
    public class CollisionZone : MonoBehaviour
    {
        [SerializeField] string _targetTypeName;
        Type _type;

        [Header("Event")]
        [SerializeField] UnityEvent<Component> _onCollisionEnter;
        [SerializeField] UnityEvent<Component> _onCollisionExit;

        public event Action<Component> OnCollisionEnterAction;
        public event Action<Component> OnCollisionExitAction;

        public List<Component> AllComponentsIn { get; private set; }
        public bool IsTriggered { get; private set; }


        private void Awake()
        {
            if (!string.IsNullOrEmpty(_targetTypeName))
            {
                _type = Type.GetType(_targetTypeName);
                if (_type == null) _type = Type.GetType($"{_targetTypeName}, Assembly-CSharp");
            }

            AllComponentsIn = new List<Component>();
        }

        public void OnCollisionEnter(UnityEngine.Collision collision)
        {
            if (collision.gameObject.TryGetComponent(_type, out Component component))
            {
                _onCollisionEnter?.Invoke(component);
                OnCollisionEnterAction?.Invoke(component);
                SaveComponents(component);
                IsTriggered = true;
            }
        }

        public void OnCollisionExit(UnityEngine.Collision collision)
        {
            if (collision.gameObject.TryGetComponent(_type, out Component component))
            {
                _onCollisionExit?.Invoke(component);
                OnCollisionExitAction?.Invoke(component);
                RemoveComponents(component);
                if (AllComponentsIn.Count <= 0) IsTriggered = false;
            }
        }

        void SaveComponents(Component component)
        {
            if (!AllComponentsIn.Find(x => x.GetEntityId() == component.GetEntityId()))
            {
                AllComponentsIn.Add(component);
            }
        }

        void RemoveComponents(Component component)
        {
            var index = AllComponentsIn.FindIndex(x => x.GetEntityId() == component.GetEntityId());

            if (index >= 0)
            {
                AllComponentsIn.RemoveAt(index);
            }
        }
    }
}

