using System;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;

namespace Assets.Source.Patterns.ObjectPool
{
    public class ObjectPool
    {
        private Transform _rootTransform;
        private Func<IPoolObject> _warmFunc;

        public event Action<IPoolObject> OnWarm;

        private List<IPoolObject> _spawnedClones = new List<IPoolObject>();
        private List<IPoolObject> _pooledClones = new List<IPoolObject>();

        public ObjectPool(Transform rootTransform, Func<IPoolObject> warmFunc)
        {
            _rootTransform = rootTransform;
            _warmFunc = warmFunc;
        }

        public void Warm()
        {
            var clone = _warmFunc();
            //if (!_clonesLookup.ContainsKey(prefab))
            //    _clonesLookup.Add(prefab, new List<IPoolObject>());
            //_clonesLookup[prefab].Add(clone);
            //_prefabLookup.Add(clone, prefab);
            _pooledClones.Add(clone);
            OnWarm?.Invoke(clone);
            clone.gameObject.SetActive(false);
        }

        public IPoolObject Spawn()
        {
            if (_pooledClones.Count == 0)
                Warm();

            var cloneToSpawn = _pooledClones[0];
            _pooledClones.RemoveAt(0);
            _spawnedClones.Add(cloneToSpawn);

            cloneToSpawn.gameObject.SetActive(true);
            cloneToSpawn.OnSpawnFromPool();

            return cloneToSpawn;
        }

        public bool Release(IPoolObject clone)
        {
            if (_pooledClones.Contains(clone))
            {
                Debug.LogWarning($"Clone already in pool: {clone.gameObject.name}");
                return false;
            }
            _spawnedClones.Remove(clone);
            _pooledClones.Add(clone);

            clone.OnReturnToPool();
            clone.gameObject.SetActive(false);

            DOTween.Kill(clone);
            DOTween.Kill(clone.gameObject.transform);

            if (_rootTransform != null)
                clone.gameObject.transform.SetParent(_rootTransform);

            return true;
        }

        public static void AddReleaseHandler(IPoolObject obj, Action<IPoolObject> action)
        {

        }
    }
}
