using System;
using System.Collections.Generic;
using System.Linq;
using Assets.Source.Core.Impacting;

namespace Assets.Source.Core.Effecting
{
    public class EffectContainer
    {
        public IImpactable Owner { get; }

        private readonly List<Effect> _effects = new List<Effect>();

        public event Action<Effect> OnAddEffect;
        public event Action<Effect> OnSubtractEffect;

        public EffectContainer(IImpactable owner)
        {
            Owner = owner;
        }

        public void Add<T>(T e) where T : Effect
        {
            _effects.Add(e);
            e.OnExpire += () => OnEffectExpired(e);
            e.Owner = Owner;
            OnAddEffect?.Invoke(e);
        }

        public void Subtract<T>(int stacks = 1) where T : Effect
        {
            var e = _effects.FirstOrDefault(effect => effect is T);
            if (e == null)
                return;
            e.Subtract(stacks);
            OnSubtractEffect?.Invoke(e);
        }

        public T Get<T>() where T : Effect
        {
            return _effects.FirstOrDefault(effect => effect is T) as T;
        }

        public bool Has<T>() where T : Effect
        {
            return _effects.Any(effect => effect is T);
        }

        public int CountOf<T>() where T : Effect
        {
            return _effects.Count(e => e is T);
        }

        public void Clear()
        {
            _effects.Clear();
        }

        private void OnEffectExpired(Effect e)
        {
            _effects.Remove(e);
        }
    }
}
