using System.Collections.Generic;
using _Project.Develop.Runtime.Entities;
using _Project.Develop.Runtime.Utilities;
using _Project.Develop.Runtime.Utils.ReactiveManagement;
using _Project.Develop.Runtime.Utils.ReactiveManagement.Event;
using UnityEngine;

namespace _Project.Develop.Runtime.Logic.Gameplay.Features.Damage
{
    public class DealDamageOnContactSystem: IInitializableSystem, IUpdatableSystem
    {
        private Entity _entity;
        private Buffer<Entity> _contacts;
        private ReactiveVariable<float> _damage;
    
        private List<Entity> _processedEntities;
    
        public void OnInit(Entity entity)
        {
            _entity = entity;
            _contacts = entity.ContactEntitiesBuffer;
            _damage = entity.BodyContactDamage;
    
            _processedEntities = new List<Entity>(_contacts.Items.Length);
        }
    
        public void OnUpdate(float deltaTime)
        {
            for (int i = 0; i < _contacts.Count; i++)
            {
                Entity contactEntity = _contacts.Items[i];
    
                if(_processedEntities.Contains(contactEntity) == false)
                {
                    _processedEntities.Add(contactEntity);
                    
                    if (contactEntity.TryGetTakeDamageRequest(out ReactiveEvent<float> takeDamageRequest))
                        takeDamageRequest.Invoke(_damage.Value);
                }
            }
    
            for (int i = _processedEntities.Count - 1; i >= 0; i--)
                if (ContainInContacts(_processedEntities[i]) == false)
                    _processedEntities.RemoveAt(i);
        }
    
        private bool ContainInContacts(Entity entity)
        {
            for (int i = 0; i < _contacts.Count; i++)
                if (_contacts.Items[i] == entity)
                    return true;
    
            return false;
        }
    }
}