using System.Collections.Generic;
using Fort23.Core;
using Fort23.UTool;
using UnityEngine;
using Utility;

namespace Core.AssetLoadTool.Asset
{
    public class BundleLoadBasic : LoadTaskBasic
    {
        public List<LoadTaskBasic> ownTask = new List<LoadTaskBasic>();
        protected string url;
        private float progress;
        protected object userData;
        private Map<string, LoadInfoAsset> _bundleAsset = new Map<string, LoadInfoAsset>();

        public AssetBundle currBundle
        {
            get { return _currBundle; }
        }

        protected AssetBundle _currBundle;
        protected System.Action<BundleLoadBasic, object> callBack;
        protected List<BundleLoadBasic> m_dependenceTasks = new List<BundleLoadBasic>();

        protected bool isAwaitDependencies;

        protected bool _isUnloadType;
        public string bundleName;

        public void InitBundle(string bundleName, bool isUnloadType, System.Action<BundleLoadBasic, object> callBack)
        {
            // Debug.Log("加载bunlde"+bundleName);
            _isUnloadType = isUnloadType;
            loadState = LoadState.Init;
            AddCallBack(callBack);
            this.bundleName = bundleName;
            LoadDependencies(bundleName);
        }

        public void LoadDependencies(string bundleName)
        {
            string[] dependencies = AssetBundleLoadManager.Instance.GetBundleDependencies(bundleName);
            if (dependencies != null && dependencies.Length > 0)
            {
                m_dependenceTasks = new List<BundleLoadBasic>();
                for (int i = 0; i < dependencies.Length; i++)
                {
                    string depBundleName = dependencies[i];
                    BundleLoadBasic task = AssetBundleLoadManager.Instance.AddBundleTask(depBundleName, null, this);

                    m_dependenceTasks.Add(task);
                }

                isAwaitDependencies = true;
                 loadState = LoadState.Await;
                AssetBundleLoadManager.Instance.dependenciesBuffer.Add(this);
            }
            else
            {
                loadState = LoadState.Load;
                StartLoad();
            }

           
        }
        

        public bool AwaitDependenceLoadEnd()
        {
            for (int i = 0; i < m_dependenceTasks.Count; i++)
            {
                if (!m_dependenceTasks[i].IsLoadEnd())
                {
                    return false;
                }
            }

            AwaitDependenciesFinish();
            return true;
        }

        protected void AwaitDependenciesFinish()
        {
            isAwaitDependencies = false;
            if (loadState == LoadState.Await)
            {
                // loadState = LoadState.End;
                // callBack?.Invoke(this, userData);
                loadState = LoadState.Load;
                StartLoad();
            }
        }

        protected void LoadFinish(AssetBundle assetBundle)
        {
            _currBundle = assetBundle;
            if (_currBundle == null)
            {
                LogTool.Error("budnle空的" + url + "__" + bundleName);
                return;
            }

            // if (isAwaitDependencies)
            // {
            //     loadState = LoadState.Await;
            // }
            // else
            {
                loadState = LoadState.End;
                callBack?.Invoke(this, userData);
            }
        }

        public void AddCallBack(System.Action<BundleLoadBasic, object> callBack)
        {
            if (loadState == LoadState.End)
            {
                if (callBack != null)
                {
                    callBack(this, userData);
                }

                return;
            }

            this.callBack += callBack;
        }

        public void AddOwnTask(LoadTaskBasic taskBasic)
        {
            if (taskBasic == null)
            {
                return;
            }

            if (ownTask.Contains(taskBasic))
            {
                return;
            }

            ownTask.Add(taskBasic);
        }

        public void RemoveAsset(string assetName)
        {
            if (_bundleAsset.TryGetValue(assetName, out LoadInfoAsset loadInfoAsset))
            {
                loadInfoAsset.count--;
            }
        }

        public T LoadAsset<T>(string assetName) where T : Object
        {
            if (_bundleAsset.TryGetValue(assetName, out LoadInfoAsset loadInfoAsset))
            {
                loadInfoAsset.count++;
                if (loadInfoAsset.asset == null)
                {
                    _bundleAsset.Remove(assetName);
                }
                else
                {
                    return (T)loadInfoAsset.asset;
                }
            }


            if (_currBundle == null)
            {
                LogTool.Error("budnle已经空" + url + "__" + bundleName);
                return default;
            }

            loadInfoAsset = new LoadInfoAsset();
            loadInfoAsset.asset = _currBundle.LoadAsset<T>(assetName);
            loadInfoAsset.count = 1;
            _bundleAsset.Add(assetName, loadInfoAsset);
            return (T)loadInfoAsset.asset;
        }

        public void RemoveOwnTask(LoadTaskBasic taskBasic)
        {
            ownTask.Remove(taskBasic);
            UnloadBundle();
        }

        public void UnloadBundle()
        {
            if (ownTask.Count <= 0)
            {
                Dispose();
            }
        }

        private void Dispose()
        {
            if (loadState == LoadState.Load)
            {
                return;
            }

            for (_bundleAsset.Begin(); _bundleAsset.Next();)
            {
                if (_bundleAsset.Value.asset is GameObject)
                {
                    Object.DestroyImmediate(_bundleAsset.Value.asset, true);
                }
                else
                {
                    Resources.UnloadAsset(_bundleAsset.Value.asset);
                }
            }

            _bundleAsset.Clear();
            for (int i = 0; i < m_dependenceTasks.Count; i++)
            {
                m_dependenceTasks[i].RemoveOwnTask(this);
            }

            m_dependenceTasks.Clear();
            if (_currBundle != null)
            {
                // Debug.Log("卸载bunlde"+bundleName);
                _currBundle.Unload(_isUnloadType);
                _currBundle = null;
            }

            AssetBundleLoadManager.Instance.RemoveBundleTask(this);
            loadState = LoadState.Disposed;
        }
    }
}