using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Triggers;
using VOID.Generic.Turn;

namespace VOID.Generic.Objects.Abstract
{
    [System.Serializable]
    public class AbstractObjectState : ObjectComponent<AbstractObject>
    {
        #region Initialize

        protected override void EventInitialize()
        {
            // Death & Revive events
            parent.basicEvents.onDeathAfter.AddListener(OnDeath);
            parent.basicEvents.onRevive.AddListener(OnRevive);
            
            // Turn events
            parent.basicEvents.onTurnQueueEnter.AddListener(OnTurnEnter);
            parent.basicEvents.onTurnQueueLeave.AddListener(OnTurnLeave);
            parent.basicEvents.onTurnQueueSwap.AddListener(OnTurnSwap);
            
            // Trigger events
            parent.basicEvents.onTriggerEnter.AddListener(OnTriggerEnter);
            parent.basicEvents.onTriggerExit.AddListener(OnTriggerExit);
        }

        #endregion

        [ShowInInspector, ReadOnly] public TurnManager turnManager { get; private set; }
        private List<IDynamicTrigger> _triggerAreas = new();

        public bool isDead;

        private void OnTurnEnter(TurnEvent turnEvent)
        {
            turnManager = turnEvent.turnManager;
        }

        private void OnTurnLeave(TurnEvent turnEvent)
        {
            turnManager = null;
        }

        private void OnTurnSwap(TurnEvent turnEvent)
        {
            turnManager = turnEvent.turnManager;
        }

        private void OnDeath(DeathEvent deathEvent)
        {
            isDead = true;
            _triggerAreas.RemoveAll(triggerArea => triggerArea as MonoBehaviour == null);
            _triggerAreas.ForEach(triggerArea => triggerArea.OnObjectExit(parent));
            if (turnManager) turnManager.ObjectExit(parent);
        }

        private void OnRevive(ReviveEvent reviveEvent)
        {
            isDead = false;
            _triggerAreas.RemoveAll(triggerArea => triggerArea as MonoBehaviour == null);
            _triggerAreas.ForEach(triggerArea => triggerArea.OnObjectEnter(parent));
        }

        private void OnTriggerEnter(TriggerEvent triggerEvent)
        {
            _triggerAreas.Add(triggerEvent.triggerArea);
        }

        private void OnTriggerExit(TriggerEvent triggerEvent)
        {
            _triggerAreas.Remove(triggerEvent.triggerArea);
        }
    }
}
