using System.Collections.Generic;
using UnityEngine;

namespace ImpactCFX.VFXBatch
{
    [AddComponentMenu("Impact CFX/VFX Batch/Impact VFX Batch Processor")]
    public class ImpactVFXBatchEffectProcessor : ImpactSimpleEffectProcessor<ImpactVFXBatchEffectAuthoring, VFXBatchEffect, VFXBatchEffectResult>
    {
        private List<ImpactVFXBatchMaster> vfxMasters = new List<ImpactVFXBatchMaster>();

        protected override VFXBatchEffect getEffect(ImpactVFXBatchEffectAuthoring effectAuthoring)
        {
            VFXBatchEffect vfxBatchEffect = effectAuthoring.GetVFXBatchEffect();
            ImpactVFXBatchMaster masterVisualEffectPrefab = effectAuthoring.VisualEffectPrefab;

            if (!vfxMasters.Exists(p => p.GetEffectID() == vfxBatchEffect.EffectID))
            {
                ImpactVFXBatchMaster masterVisualEffectInstance = Instantiate(masterVisualEffectPrefab);
                masterVisualEffectInstance.SetEffectID(vfxBatchEffect.EffectID);
                masterVisualEffectInstance.SetEffectType(vfxBatchEffect.VisualEffectType);

                DontDestroyOnLoad(masterVisualEffectInstance.gameObject);
                vfxMasters.Add(masterVisualEffectInstance);

                if (!queueCapacity.Override)
                    queueCapacity.Value = Mathf.Max(queueCapacity.Value, masterVisualEffectInstance.Capacity);
            }

            return vfxBatchEffect;
        }
        protected override ImpactEffectProcessorJob<VFXBatchEffect, VFXBatchEffectResult> getEffectProcessorJobBase()
        {
            return new ImpactEffectProcessorJob<VFXBatchEffect, VFXBatchEffectResult>();
        }

        public override void FixedUpdateProcessor()
        {
            foreach (var item in vfxMasters)
            {
                item.ApplyVisualEffectParameters();
            }
        }

        public override void ClearAllRegistered()
        {
            base.ClearAllRegistered();

            foreach (ImpactVFXBatchMaster master in vfxMasters)
            {
                if (master != null && !master.Equals(null))
                    Destroy(master.gameObject);
            }

            vfxMasters.Clear();
        }

        public override void PlayEffect(VFXBatchEffectResult effectResult, CollisionResultData collisionResultData)
        {
            base.PlayEffect(effectResult, collisionResultData);

            if (findVFXBatchMaster(effectResult.EffectID, out ImpactVFXBatchMaster master))
            {
                master.SetInput(collisionResultData);
            }
        }

        private bool findVFXBatchMaster(int effectID, out ImpactVFXBatchMaster master)
        {
            foreach (ImpactVFXBatchMaster p in vfxMasters)
            {
                if (p.GetEffectID() == effectID)
                {
                    master = p;
                    return true;
                }
            }

            master = default;
            return false;
        }

        public override void ResetProcessor()
        {
            foreach (ImpactVFXBatchMaster p in vfxMasters)
            {
                p.ResetEffect();
            }
        }

        public override bool HasEffects()
        {
            return effects.Length > 0;
        }
    }
}