using XGame.Framework.i18n;
using XGame.Framework.Quality;
using XGame.Framework.Asset.Addressable;
using System;

namespace XGame.Framework.Asset
{
    internal class AssetLoader : IAssetLoader, IDisposable, IAddressableHandle
    {
        private LoaderType _loadType;
        private IAssetLoader[] _loaders;
        private IAddressableManifest _addressableManifest;
        
        public AssetLoader(LoaderType loadType, IAssetLoader[] loaders, IAddressableManifest addressableManifest)
        {
            _loadType = loadType;
            _loaders = loaders;
            _addressableManifest = addressableManifest;

        }

        public IAssetAsync LoadAsync<TResult>(string addressableName)
        {
            //addressableName = assetInfoManifest.AssetPathToAddressableName(addressableName);
            return GetLoader(addressableName).LoadAsync<TResult>(addressableName);
        }

        public object LoadSync<TResult>(string addressableName)
        {
            //addressableName = assetInfoManifest.AssetPathToAddressableName(addressableName);
            return GetLoader(addressableName).LoadSync<TResult>(addressableName);
        }
        void IDisposable.Dispose()
        {
            foreach (var loader in _loaders)
            {
                (loader as IDisposable)?.Dispose();
            }
            _loaders = null;
            (_addressableManifest as IDisposable)?.Dispose();
            _addressableManifest = null;
        }

        private IAssetLoader GetLoader(string addressableName)
        {
            if (_addressableManifest.IsInResourcesByName(addressableName))
            {
                return _loaders[(int)LoaderType.Resources];

            }
            else if (!_addressableManifest.ContainsName(addressableName))
            {
                var text = " ";
                if (!string.IsNullOrEmpty(addressableName) && addressableName.Contains(text))
                {
                    text = "addressableName 包含空格. ";
                }
                AssetsLog.Error($"找不到资源信息.{text}Name:{addressableName}");
            }
            return _loaders[(int)_loadType];
        }

        public void Unload(string addressableName, object source)
        {
            //addressableName = assetInfoManifest.AssetPathToAddressableName(addressableName);
            GetLoader(addressableName).Unload(addressableName, source);
        }
        public void UnloadUnusedAssets()
        {
            foreach (var loader in _loaders)
            {
                loader?.UnloadUnusedAssets();
            }
        }

        public IAssetAsync LoadSceneBundleAsync(string sceneName)
        {
            return _loaders[(int)_loadType].LoadSceneBundleAsync(sceneName);
        }
        public void UnLoadSceneBundle(string sceneName)
        {
            _loaders[(int)_loadType].UnLoadSceneBundle(sceneName);
        }

        /// <summary>
        /// 根据ConvertOptions转换对应多语言或者LOD版本资源
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        string IAddressableHandle.ConvertAddressableName(ConvertOptions options)
        {
            options.addressableName = options.addressableName?.ToLower();

            if ((options.langType != LanguageType.NONE ||
                 options.quality.IsLodQuality()) &&
                TryConvertAddressableName(ref options, out var name))
            {
                return name;
            }
            return options.addressableName;
        }
        string IAddressableHandle.GetAlphaTextureName(string spriteName)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 尝试转换指定资源的对应多语言或者LOD版本资源
        /// </summary>
        /// <param name="options"></param>
        /// <param name="addressableName"></param>
        /// <returns></returns>
        private bool TryConvertAddressableName(ref ConvertOptions options, out string addressableName)
        {
            addressableName = options.addressableName;
            var result = false;
            if (_addressableManifest.TryGetLodAddressableName(addressableName, options.quality, out var lodName))
            {
                //先取Lod资源
                addressableName = lodName;
                result = true;
            }
            if (_addressableManifest.TryGetI18nAddressableName(addressableName, options.langType, out var i18nName))
            {
                //再取多语言资源
                addressableName = i18nName;
                result = true;
            }
            if (result)
            {
                return true;
            }
            addressableName = string.Empty;
            return false;
        }
    }
}

