﻿#if UNITY_EDITOR
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using JLGames.RocketDriver.CSharp.Utils;
using JLGames.RocketDriver.Actions.Utils;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;

namespace JLGames.RocketDriver.Actions.Loaderx
{
    internal sealed class EditorLoader : LoaderBase, ILoader
    {
        internal EditorLoader()
        {
            m_BaseInfo = new LoaderBaseInfo();
            m_BundleLoader = new EditorBundleLoader();
            m_AssetLoader = new EditorAssetLoader(m_BaseInfo);
        }

        public void InitLoader(LoaderSettings settings)
        {
            m_OriginalSettings = settings;
            var se = settings.DefaultEditorSetting;
            if ("" != se.ProjectBasePath)
            {
                SetBaseUri("", se.ProjectBasePath);
            }
        }

        public void SetBaseUri(string baseReqUri, string baseLocUri)
        {
            if (string.IsNullOrEmpty(baseLocUri))
            {
                throw LoaderErrors.ErrorUriEmpty;
            }

            Debug.Log("BaseReqUri will be ignored in Editor Mode.");
            m_BaseInfo.SetBaseLocUri(baseLocUri);
        }

        public void SetCacheSetting(string cacheName, string cachePath)
        {
        }

        //多层异步资源加载------------------------------------------------------------

        public IEnumerator LoadAssetAsync<T>(string bundleName, string assetPath,
            LoaderDelegate.OnAssetWithBundleLoaded<T> onLoaded,
            bool autoRelease = true, bool unloadObjects = false) where T : Object
        {
            if (string.IsNullOrEmpty(bundleName) || string.IsNullOrEmpty(assetPath))
            {
                throw LoaderErrors.ErrorNameEmpty;
            }

            var asset = LoadAssetSync<T>(assetPath, null);

            if (null == asset)
            {
                Internal.ApplyAssetWithBundleCallback(onLoaded, null, null, false);
            }
            else
            {
                Internal.ApplyAssetWithBundleCallback(onLoaded, null, asset, true);
            }

            yield break;
        }
        //-----------------------------------------------

        [Obsolete("禁止使用")]
        private string[] SearchPath(string path)
        {
            var name = Path.GetFileNameWithoutExtension(path);
            var guids = AssetDatabase.FindAssets(name, new[] {m_BaseInfo.BaseLocUri});
            if (null == guids || guids.Length == 0)
            {
                return null;
            }

            var list = new List<string>();
            for (var i = guids.Length - 1; i >= 0; i--)
            {
                var p = AssetDatabase.GUIDToAssetPath(guids[i]);
                // 过滤文件夹
                if (AssetDatabase.IsValidFolder(p))
                {
                    continue;
                }

                // 过滤不一致
                if (p.IndexOf(path) == -1)
                {
                    continue;
                }

                list.Add(p);
            }

            return list.ToArray();
        }

        [Obsolete("Prohibited to use, poor performance(禁止使用,性能不佳")]
        private string SearchInPath(string[] paths, string path)
        {
            if (null == paths || path.Length == 0)
            {
                return null;
            }

            var maybeFullPath = Path.Combine(m_BaseInfo.BaseLocUri, path);
//            Debug.Log($"---------------FullName:{maybeFullPath}");
            var index = Array.IndexOf(paths, maybeFullPath);
            if (-1 != index)
            {
                return paths[index];
            }

            var fileNameOut = Path.GetFileNameWithoutExtension(path);
//            Debug.Log($"---------------FileNameOut:{fileNameOut}");
            for (var i = paths.Length - 1; i >= 0; i--)
            {
//                Debug.Log($"{paths[i]} -> {Path.GetFileNameWithoutExtension(paths[i])}");
                if (Path.GetFileNameWithoutExtension(paths[i]) == fileNameOut)
                {
                    return paths[i];
                }
            }

            var fileName = Path.GetFileName(path);
//            Debug.Log($"---------------FileName:{fileName}");
            for (var i = paths.Length - 1; i >= 0; i--)
            {
//                Debug.Log($"{paths[i]} -> {Path.GetFileName(paths[i])}");
                if (Path.GetFileName(paths[i]) == fileName)
                {
                    return paths[i];
                }
            }

            return null;
        }

        /// <summary>
        /// Unity recommends absolute mode with relative paths (including extensions)
        /// Unity建议使用相对路径的绝对模式(包含扩展名)
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private string GetAssetRelativeFullPath(string path)
        {
            var rs = UnityPathUtil.CombineUnityPath(m_BaseInfo.BaseLocUri, path);
            return rs;
        }
    }
}
#endif