using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Pool;


public class VfxHandlerBase {
  private List<ObjectPool<ParticleSystem>> ParticleSystemPool = new List<ObjectPool<ParticleSystem>>();
  private GameObject PoolParentContainer;

  public VfxHandlerBase(GameObject vfx, int defaultCap = 10, int maxCap = 50) {
    if (!vfx) { Debug.LogError($"You did not pass vfx...."); }
    PoolParentContainer = new GameObject($"{vfx.name} Pool");
    var particleSystems = vfx.GetComponentsInChildren<ParticleSystem>();
    particleSystems.ToListPooled().ForEach(x => GenerateVfxPool(x, defaultCap, maxCap));
  }

  public void PlayAll(Vector3? position = null, Quaternion? rotation = null) {
    if (position == null) position = Vector3.zero;
    if (rotation == null) rotation = Quaternion.Euler(0, 0, 0);

    Get((Vector3)position, (Quaternion)rotation);

    //var particleSystems = obj.GetComponentsInChildren<ParticleSystem>();
    //particleSystems.ToListPooled().ForEach((x) => x.Play());
  }

  public List<ParticleSystem> Get(Vector3 position, Quaternion rotation) {
    var particleSystems = ParticleSystemPool.ToList().Select(x => x.Get()).ToList();
    particleSystems.ForEach(x => {
      x.transform.SetPositionAndRotation(position, rotation);
      x.Play();
    });
    return particleSystems;
  }

  private void GenerateVfxPool(ParticleSystem vfx, int defaultCap = 10, int maxCap = 50) {
    if (!vfx) { Debug.LogError($"You did not pass vfx...."); }
    ObjectPool<ParticleSystem> pool = null;
    pool = new ObjectPool<ParticleSystem>(
        createFunc: () => {
          var inst = Object.Instantiate(vfx, PoolParentContainer.transform);
          inst.gameObject.SetActive(false);
          var main = inst.main;
          main.loop = false;
          main.stopAction = ParticleSystemStopAction.Callback;
          inst.gameObject.AddComponent<ReturnToPool>().Initialize(pool);
          return inst;
        },
        actionOnGet: ps => ps.gameObject.SetActive(true),
        actionOnRelease: ps => {
          ps.Clear();
          ps.gameObject.SetActive(false);
        },
        //actionOnDestroy: ps => Object.Destroy(ps.gameObject),
        collectionCheck: true,
        defaultCapacity: defaultCap,
        maxSize: maxCap
    );

    ParticleSystemPool.Add(pool);
  }


  public class ReturnToPool : MonoBehaviour {
    private ObjectPool<ParticleSystem> pool;

    public void Initialize(ObjectPool<ParticleSystem> pool) {
      this.pool = pool;
    }

    private void OnParticleSystemStopped() {
      pool.Release(GetComponent<ParticleSystem>());
    }
  }
}
