using System.Collections.Generic;
using System.Linq;
using UnityEditor;

namespace XGame.Editor.Build.AssetBundles
{
    public class AssetBundleCollector
    {
        private BundleContext _context;
        private ShaderBundleCollector _shaderCollector;
        private AtlasBundleCollector _atlasCollector;
        private PackerBundleCollector _packerCollector;
        private DepBundleCollector _depCollector;
        private SceneBundleCollector _sceneCollector;

        public AssetBundleCollector(BundleContext context, ShaderBundleCollector shaderCollector, AtlasBundleCollector atlasCollector, PackerBundleCollector packerCollector, DepBundleCollector depCollector, SceneBundleCollector sceneCollector)
        {
            _context = context;
            _shaderCollector = shaderCollector;
            _atlasCollector = atlasCollector;
            _packerCollector = packerCollector;
            _depCollector = depCollector;
            _sceneCollector = sceneCollector;
        }

        /// <summary>
        /// 收集AssetBundle信息
        /// </summary>
        /// <param name="guidToAddressableName"></param>
        /// <returns></returns>
        public void CollectBundleBuilds(bool recursive)
        {
            //string root = PathDefine.ResAddressablePath;
            //Debug.Log($"CollectBundleBuilds Path: {root}");
            //List<AssetBundleBuild> assetBundleBuilds = new List<AssetBundleBuild>();
            //List<string> bundleNames = new List<string>();
            #region packer
            //var assetBundleBuilds = new Dictionary<long, AssetBundleBuild>();
            //var filePaths = new List<string>();

            // 先把BuildSetting中的Scene的path加到filePaths中，在之后的收集中过滤掉
            int sceneCount = EditorBuildSettings.scenes.Length;
            for (int i = 0; i < sceneCount; i++)
                _context.bundleAssetPaths.Add(EditorBuildSettings.scenes[i].path);
            _shaderCollector.Collect();
            if (_atlasCollector.Collect() && _packerCollector.Collect())
            {
                _atlasCollector.ToBundleBuilds();
                var waittingAssetMap = new Dictionary<string, string>();
                foreach (var waittingFile in _context.waittingAssetPaths)
                {
                    if (_context.bundleAssetPaths.Contains(waittingFile))
                    {
                        continue;
                    }
                    var directoryPath = waittingFile.Substring(0, waittingFile.LastIndexOf('/'));
                    waittingAssetMap.Add(waittingFile, directoryPath);
                }
                // 按文件夹名字分组
                var groups = waittingAssetMap.GroupBy((a) => a.Value);
                var assetPaths = new HashSet<string>();
                foreach(var group in groups)
                {
                    var dirPath = group.Key;
                    foreach (var item in group)
                    {
                        assetPaths.Add(item.Key);
                    }
                    _context.AddAddressableBundle(_context.ToArrayBySort(assetPaths), AssetDatabase.AssetPathToGUID(dirPath));
                    assetPaths.Clear();
                }
                if (_context.waittingAssetPaths.Count > 0)
                {
                    BuildLog.Error($"waittingAssetPaths 没有全部处理. 剩余数量:{_context.waittingAssetPaths.Count}");
                    foreach (var waittingFile in _context.waittingAssetPaths)
                    {
                        BuildLog.Error($"waittingAssetPath:{waittingFile}");
                    }
                }
                //var assetRoots = FileUtil.GetProductAssetsRoots();
                //foreach (var root in assetRoots)
                //{
                //    FileUtil.FindFiles(root, (files) =>
                //    {
                //        if (_context.bundleAssetPaths != null && _context.bundleAssetPaths.Count > 0)
                //        {
                //            //过滤已设置bundle的资源，此处待优化
                //            files = files.Where((file) => !_context.bundleAssetPaths.Contains(file)).ToArray();
                //        }
                //        if (files.Length > 0)
                //            _context.bundleBuildMap.TryAdd(_context.CreateBundleBuild(files));
                //    });
                //}
                if (recursive)
                    _depCollector.Collect();
            }
            #endregion
        }
        #region Scene Bundle
        public bool CollectSceneBundles()
        {
            return _sceneCollector.Collect();
        }
        //public Dictionary<long, AssetBundleBuild> SceneBundleBuildMap => _sceneCollector.bundleBuildMap;

        //public bool MergeSceneBundles()
        //{
        //    return _context.bundleBuildMap.TryAddRange(_sceneCollector.bundleBuildMap);
        //}
        #endregion
    }
}
