using UnityEngine.Events;

namespace ChillConnect
{
    using System;
    using UnityEngine;
    using System.Collections.Generic;

    public delegate void onLoaded(AssetBundle param);

    public class ChillConnectInfo
    {
        public string assetBundleName;

        public List<string> parentABNameList = new();

        public long assetBundleSize;


        public AssetBundle assetBundle { get; internal set; }

        public ChillConnectState assetBundleState;

        public onLoaded ONLoaded;

        public long waitUnloadCurrentTime;

        public Action<Action<bool>> unloadAction;

        public Action<bool> unloadCompletedAction;

        public int waitUnloadTime;


        public static List<string> StatisticsCacheAssetList = new List<string>();


        private static bool isStatisticsCacheAssetList = false;


        public int ReferencedCount { get; set; }


        public float LastReferencedTimestamp { get; set; }

        public ChillConnectInfo(string assetBundleName, UnityAction<AssetBundle> onCompletedLoaded)
        {
            this.assetBundleName = assetBundleName;
            assetBundleState = ChillConnectState.STATE_LOADING;
            Referenced(assetBundleName);
            LastReferencedTimestamp = Time.realtimeSinceStartup;
            if (onCompletedLoaded != null)
            {
                ONLoaded += a => onCompletedLoaded(a);
            }
        }

        #region 引用关系

        public int GetReferenced()
        {
            return ReferencedCount;
        }


        public void Referenced(string parentAbName)
        {
            parentAbName = parentAbName.ToLower();
            if (!parentABNameList.Contains(parentAbName))
            {
                ReferencedCount++;
                parentABNameList.Add(parentAbName);
#if UNITY_EDITOR

#endif
            }
        }

        public void UnReferenced(string parentAbName)
        {
            if (parentABNameList.Contains(parentAbName))
            {
                ReferencedCount--;
                parentABNameList.Remove(parentAbName);
#if UNITY_EDITOR

#endif
            }
        }

        public void CleanReferenced()
        {
            ReferencedCount = 0;
        }

        #endregion

        public void callRes(string parentAbName, UnityAction<AssetBundle> action)
        {
            switch (assetBundleState)
            {
                case ChillConnectState.STATE_NONE:
                    break;
                case ChillConnectState.STATE_LOADING:
                    ONLoaded += a => { action(a); };
                    break;
                case ChillConnectState.STATE_LOADED:
                    Referenced(parentAbName);
                    action(this.assetBundle);
                    break;
            }
        }

        public void onLoaded(string parentAbName, AssetBundle assetBundle)
        {
            Referenced(parentAbName);
            this.assetBundle = assetBundle;
            this.assetBundleState = ChillConnectState.STATE_LOADED;
            ONLoaded(assetBundle);
            ONLoaded = null;
            OnAddtStatisticsCacheAssetList(assetBundle.name);
        }

        public void Unload(bool isThorough)
        {
            CleanReferenced();
            if (assetBundle != null)
                assetBundle.Unload(isThorough);
            assetBundle = null;
        }


        private void OnAddtStatisticsCacheAssetList(string assetBundleName)
        {
            if (!isStatisticsCacheAssetList) return;
            if (!StatisticsCacheAssetList.Contains(assetBundleName))
            {
                StatisticsCacheAssetList.Add(assetBundleName);
            }
        }


        public static void OnStartStatisticsCacheAssetList()
        {
            isStatisticsCacheAssetList = true;
            StatisticsCacheAssetList.Clear();
        }


        public static string[] OnStopStatisticsCacheAssetList()
        {
            isStatisticsCacheAssetList = false;
            string[] tempList = StatisticsCacheAssetList.GetRange(0, StatisticsCacheAssetList.Count).ToArray();
            StatisticsCacheAssetList.Clear();
            return tempList;
        }


        public void UpdateWaitUnloadCurrentTime()
        {
            waitUnloadCurrentTime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
        }


        public long GetWaitUpdateTimeTD()
        {
            var tempTime = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds();
            return tempTime - waitUnloadCurrentTime;
        }

        public void SetUnloadAction(Action<Action<bool>> action, Action<bool> onCompletedAction)
        {
            this.unloadAction = action;
            this.unloadCompletedAction = onCompletedAction;
        }

        public void InvokeUnloadAction()
        {
            unloadAction?.Invoke(unloadCompletedAction);
        }

        public void SetWaitUnloadTime(int time)
        {
            waitUnloadTime = time;
        }

        public int GetWaitUnloadTime()
        {
            return waitUnloadTime;
        }

        public void SetAssetBundleSize(long size)
        {
            if (size > 0)
            {
                assetBundleSize = size;
            }
        }

        public long GetSize()
        {
            return assetBundleSize;
        }
    }
}