using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace XGame.Editor.Build.AssetBundles
{
    public class PackerBundleCollector
    {
        private BundleContext _context;
        private AtlasBundleCollector _atlasCollector;
        public PackerBundleCollector(BundleContext context, AtlasBundleCollector atlasCollector)
        {
            _context = context;
            _atlasCollector = atlasCollector;
        }
        /// <summary>
        /// 根据设置的分包规则收集AssetBundle信息
        /// </summary>
        /// <param name="guidToAddressableName"></param>
        /// <param name="assetBundleBuilds">bundle信息集合</param>
        /// <param name="filePaths">收集到的bundle所包含的资源路径集合，只收集ResAddressable目录</param>
        /// <returns></returns>
        public bool Collect()
        {
            //var tempFilePaths = new List<string>();
            var packerManifest = ABPackerInfoManifest.Load();
            if (packerManifest == null)
            {
                return true;
            }
            var packerInfos = packerManifest.PackerInfos;
            packerInfos.Sort();

            for (int i = 0; i < packerInfos.Count; i++)
            {
                var info = packerInfos[i];
                var assetPath = info.AssetPath;
                if (!_context.IsValidPath(assetPath))
                {
                    BuildLog.Warn($"ABPackerInfo invalid.{info}");
                    continue;
                }
                //Debug.Log($"Packer index:{i} {info} full: {System.IO.Path.GetFullPath(assetPath)}");
                if (info.packerType == ABPackerType.SingleAsset)
                {
                    //var langFlag = AddressableHelper.GetLanguageFlagByAssetPath(assetPath);
                    if (info.IsFile)
                    {
                        AddSingleBundle(assetPath, info.GUID);
                    }
                    else
                    {
                        var guids = AssetDatabase.FindAssets("", new string[] { assetPath });
                        foreach (var guid in guids)
                        {
                            AddSingleBundle(AssetDatabase.GUIDToAssetPath(guid), guid);
                        }
                    }
                }
                else if (info.packerType == ABPackerType.AllDirectories)
                {
                    AddAllDirectoriesBundle(assetPath, info.GUID);
                }
            }
            //filePaths.AddRange(tempFilePaths);
            return true;
        }
        private void AddSingleBundle(string assetPath, string guid)
        {
            if (_context.waittingAssetPaths.Contains(assetPath) && _context.bundleAssetPaths.Contains(assetPath) == false && _atlasCollector.IsAtlasAssetPath(assetPath) == false)
            { // 配置了单体，但是是图集的也忽略
                _context.AddAddressableBundle(new string[] { assetPath }, guid);
                //var bundleName = $"single_{System.IO.Path.GetFileNameWithoutExtension(assetPath)}_{info.GUID.Substring(0, 8)}".ToLower();
                //if (langFlag != Framework.i18n.LanguageType.NONE)
                //{
                //    bundleName = $"{langFlag.ToString().ToLower()}/{bundleName}";
                //}
                //_context.bundleBuildMap.TryAdd(_context.CreateBundleBuild(new string[] { assetPath }, bundleName.ToLower()));
            }
        }
        private HashSet<string> _tempAssetPaths = new HashSet<string>();
        private void AddAllDirectoriesBundle(string directoryPath, string directoryGuid)
        {
            var guids = AssetDatabase.FindAssets("", new string[] { directoryPath });

            foreach (var fileGuid in guids)
            {
                var filePath = AssetDatabase.GUIDToAssetPath(fileGuid);
                if (_context.waittingAssetPaths.Contains(filePath) && _context.bundleAssetPaths.Contains(filePath) == false && _tempAssetPaths.Contains(filePath) == false)
                {
                    if (_atlasCollector.IsAtlasAssetPath(filePath))
                    {
                        _tempAssetPaths.UnionWith(_atlasCollector.PopAtlasAssetPaths(filePath));
                    }
                    else
                    {
                        _tempAssetPaths.Add(filePath);
                    }
                }
            }
            if (_tempAssetPaths.Count > 0)
            {
                _context.AddAddressableBundle(_context.ToArrayBySort(_tempAssetPaths), directoryGuid);
                _tempAssetPaths.Clear();
            }
            else
            {
                BuildLog.Warn($"Packer config invalid.Path:{directoryPath} GUID:{directoryGuid}");
            }
        }
    }
}
