using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace TFramework
{
    public class ReferencePoolManager : BaseManager
    {
        private Dictionary<Type, ReferencePool> _referencePools = new Dictionary<Type, ReferencePool>();

        public int Limit { get; set; } = 100;

        /// <summary>
        /// 获取引用数量
        /// </summary>
        /// <param name="type">引用类型</param>
        /// <returns>引用数量</returns>
        public int GetRerenceCount(Type type)
        {
            if (_referencePools.ContainsKey(type))
                return _referencePools[type].Count;
            else
                throw new UnityException($"获取引用数量失败，不存在引用池{type.FullName}！");
        }

        /// <summary>
        /// 生成引用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public T Spawn<T>() where T : class, IReference, new()
        {
            Type type = typeof(T);
            RegisterRefer(type);
            return _referencePools[type].Spawn<T>();
        }

        /// <summary>
        /// 回收引用
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public void Recycle<T>(T refer) where T : class, IReference, new()
        {
            Type type = refer.GetType();
            RegisterRefer(type);
            _referencePools[type].Recycle<T>(refer);
        }

        /// <summary>
        /// 批量回收引用
        /// </summary>
        /// <typeparam name="T">引用类型</typeparam>
        /// <param name="refes">引用集合</param>
        public void Recycles<T>(List<T> refes) where T : class, IReference, new() => Recycles<T>(refes.ToArray());

        /// <summary>
        /// 批量回收引用
        /// </summary>
        /// <typeparam name="T">引用类型</typeparam>
        /// <param name="refes">引用数组</param>
        public void Recycles<T>(T[] refes) where T : class, IReference, new()
        {
            if (refes == null) return;
            Type type = typeof(T);
            RegisterRefer(type);
            for (int i = 0; i < refes.Length; i++)
                _referencePools[type].Recycle<T>(refes[i]);
        }

        /// <summary>
        /// 清空指定引用池
        /// </summary>
        /// <param name="type">引用类型</param>
        public void Clear(Type type) => _referencePools[type].Clear();

        /// <summary>
        /// 清空所有引用池
        /// </summary>
        public void ClearAll()
        {
            foreach (var refer in _referencePools)
                refer.Value.Clear();
        }

        /// <summary>
        /// 注册引用
        /// </summary>
        /// <param name="type">引用类型</param>
        private void RegisterRefer(Type type)
        {
            if (!_referencePools.ContainsKey(type))
                _referencePools.Add(type, new ReferencePool(Limit));
        }
    }
}
