using XGame.Framework.Asyncs;
using System;
using UnityEngine;

namespace XGame.Framework.Asset
{
    internal class AssetLoadFromBundleAsync : Async, IAssetAsync
    {
        //public AssetBundle Bundle { get; set; }
        private AssetBundleRequest request;
        ///// <summary>
        ///// 此处Path无用
        ///// </summary>
        //public string Path { get; internal set; }
        public string AddressableName { get; internal set; }
        /// <summary>
        /// asset所在Bundle的Path
        /// </summary>
        internal string BundleName { get; set; }
        internal bool IsSprite { get; set; }
        /// <summary>
        /// async的Start标记
        /// </summary>
        private bool isStart;
        /// <summary>
        /// asyncGroup完成标记
        /// </summary>
        private bool groupCompleted;
        /// <summary>
        /// asset所依赖bundle的AsyncGroup
        /// </summary>
        private AsyncGroup bundleAsyncGroup;
        internal AsyncGroup BundleAsyncGroup
        {
            get => bundleAsyncGroup;
            set
            {
                //groupCompleted = false;
                bundleAsyncGroup = value;
                bundleAsyncGroup?.On(OnGroupCompleted);
            }
        }

        public Func<string, AssetBundle> GetBundleFromCache { set; get; }
        public int AssetHash { get; set; }

        public override float Progress
        {
            get
            {
                float progress = BundleAsyncGroup?.Progress ?? 0 + request?.progress ?? 0;
                return progress / 2;
            }
            protected set => base.Progress = value;
        }

        public object GetResult()
        {
            object result = null;
            if (request != null)
                result = request.asset;
            Clear();
            return result;
        }

        public void Start()
        {
            isStart = true;
            if (bundleAsyncGroup == null || groupCompleted)
            {
                StartLoadAsset();
            }
            //if (Bundle != null)
            //{
            //    string assetName = System.IO.Path.GetFileNameWithoutExtension(Path);
            //    request = Bundle.LoadAssetAsync(assetName);
            //    request.completed += OnAssetCompleted;
            //}
        }

        void StartLoadAsset()
        {
            var bundle = GetBundleFromCache?.Invoke(BundleName);
            if (bundle != null)
            {
                //string assetName = Path.ToLower();// System.IO.Path.GetFileNameWithoutExtension(Path);
                request = IsSprite ? bundle.LoadAssetAsync(AddressableName, typeof(Sprite)) : bundle.LoadAssetAsync(AddressableName);
                request.completed += OnAssetCompleted;
            }
            else
            {
                AssetsLog.Error($"AssetBundle load completed. But it's invalid. Bundle:{BundleName}  Asset:{AddressableName}");
                AssetHash = 0;
                Completed();
            }
        }
        void OnGroupCompleted(IAsync async)
        {
            groupCompleted = true;
            if (isStart)
            {
                StartLoadAsset();
            }
        }
        void OnAssetCompleted(AsyncOperation async)
        {
            if (!async.isDone || request.asset == null)
                AssetsLog.Warn("{0} is not a valid asset.", AddressableName);
            AssetHash = request.asset?.GetInstanceID() ?? 0;
            Completed();
        }
        void Clear()
        {
            isStart = false;
            groupCompleted = false;
            request = null;
            bundleAsyncGroup = null;
        }
    }
}