using System;
using UnityEngine;
using XGame.Framework.Asset;

namespace XGame.Framework.Map
{
    public class MapAssetModule : IMapAssetModule, IDisposable
    {
        private IAssetModule _assetModule;
        private MapContext _context;
        private MapAssetPool _pool;
        private MapAssetPool Pool => _pool ?? (_pool = new MapAssetPool());
        public MapAssetModule(MapContext mapContext)
        {
            _assetModule = new AssetModule();
            _context = mapContext;
        }
        IAssetLoadAsync<TResult> IMapAssetModule.LoadAsync<TResult>(string addressableName)
        {
            return _assetModule.LoadAsync<TResult>(addressableName);
        }
        IEntityViewLoadAsync<TEntityView> IMapAssetModule.LoadEntity<TEntityView>(string addressableName, Transform parent)
        {
            var loadAsync = _assetModule.LoadAsync<EntityBehaviour>(addressableName);
            var viewAsync = new EntityViewLoadAsync<TEntityView>(loadAsync, parent, this);
            return viewAsync;
        }
        public TEntityView CreateEntity<TEntityView>(EntityBehaviour behaviour) where TEntityView : class, IEntityView, new()
        {
            var entityView = Pool.Acquire<TEntityView>();
            if (entityView is IMapContextSetter contextSetter)
            {
                contextSetter.Context = _context;
            }
            if (entityView is IEntityProxy proxy)
            {
                proxy.Behaviour = behaviour;
            }
            return entityView;
        }
        void IMapAssetModule.Recycle(UnityEngine.Object obj)
        {
            _assetModule.Recycle(obj);
        }
        void IMapAssetModule.Recycle(IEntityView entityView, bool isDestroy)
        {
            if (entityView?.Active ?? false)
            { // ÏÈÒþ²Ø
                entityView.Disable();
            }
            if (entityView is IEntityProxy proxy)
            {
                var behaviour = proxy.Behaviour;
                _assetModule.Recycle(behaviour.gameObject, isDestroy);
            }
            if (isDestroy)
            {
                (entityView as IDisposable)?.Dispose();
            }
            else
            {
                Pool.Recycle(entityView);
            }
        }
        void IMapAssetModule.StopAllAsyncs()
        {
            _assetModule.StopAllAsyncs();
        }

        void IDisposable.Dispose()
        {
            _pool?.Clear();
            _pool = null;
            (_assetModule as IDisposable)?.Dispose();
            _assetModule = null;
        }
    }
}
