using XGame.Editor.Asset;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using XGame.Framework.i18n;

namespace XGame.Editor.Build.AssetBundles
{
    public class BundleContextBuilder
    {
        private BundleContext _context;
        public BundleContext Product => _context;
        public bool Build()
        {
            if (!CreatContext())
            {
                return false;
            }
            CollectProductAssets();
            CollectTextures();
            CollectBundleGroupNames();
            return true;
        }
        private bool CreatContext()
        {
            //可寻址资源清单
            var assetInfoManifest = AddressableHelper.LoadAssetManifest();

            if (assetInfoManifest == null)
            {
                Debug.LogError("Can't find AddressableAssetInfoManifest.");
                return false;
            }
            var assetInfoMap = assetInfoManifest.GetAssetInfoMapWithGUID();
            _context = new BundleContext(assetInfoMap);
            return true;
        }
        private void CollectProductAssets()
        {
            var productAssetsRoots = Asset.FileUtil.GetProductAssetsRoots();
            var assetGuids = AssetDatabase.FindAssets("", productAssetsRoots);
            foreach (var guid in assetGuids)
            {
                var assetPath = AssetDatabase.GUIDToAssetPath(guid);
                if (Directory.Exists(assetPath))
                {
                    //_context.directoriesMap.Add(assetPath, guid);
                    continue;
                }
                else if (Asset.FileUtil.IsFileIgnore(assetPath))
                {
                    continue;
                }
                _context.waittingAssetPaths.Add(assetPath);
            }
            _context.assetsRoots = productAssetsRoots;
        }
        private void CollectTextures()
        {
            var guids = AssetDatabase.FindAssets("t:Texture", new string[] { PathDefine.ResAddressableRelative, PathDefine.I18nAssetsRelative, PathDefine.ResStaticRelative });
            foreach (var guid in guids)
            {
                var assetPath = AssetDatabase.GUIDToAssetPath(guid);
                if (string.IsNullOrEmpty(assetPath))
                {
                    continue;
                }
                _context.allTexturePaths.Add(assetPath);
            }
        }
        /// <summary>
        /// 收集Assetbundle分组的GroupName
        /// <key: assetPath, value: groupName>
        /// </summary>
        /// <param name="guidToAddressableName"></param>
        /// <returns></returns>
        private void CollectBundleGroupNames()
        {
            var packerManifest = ABPackerInfoManifest.Load();
            if (packerManifest == null || packerManifest.GroupInfos == null || packerManifest.GroupInfos.Count < 1)
            {
                return;
            }
            _context.bundleNameMode = packerManifest.bundleNameMode;
            _context.isMergeShader = packerManifest.isMergeShader;
            var groupNameMap = _context.groupNameMap;
            var directories = new HashSet<string>();
            foreach (var groupInfo in packerManifest.GroupInfos)
            {
                var groupName = groupInfo.groupName;
                if (string.IsNullOrEmpty(groupName) || Asset.FileUtil.HasChinese(groupName))
                {
                    Debug.LogWarning($"[XBuild]AssetbundleGroup 名字为空或者包含中文字符. ID:{groupInfo.GroupId}");
                    continue;
                }
                if (LanguageUtils.IsLanguage(groupName))
                {
                    Debug.LogWarning($"[XBuild]AssetbundleGroup 名字不能为多语言枚举. GroupName:{groupName}");
                    continue;
                }
                groupName = groupName.ToLower();
                foreach (var guid in groupInfo.guidList)
                {
                    if (string.IsNullOrEmpty(guid))
                    {
                        continue;
                    }
                    var assetPath = AssetDatabase.GUIDToAssetPath(guid);
                    if (!assetPath.StartsWith(PathDefine.ResAddressableRelative))
                    {
                        Debug.LogWarning($"[XBuild]AssetbundleGroup 路径错误. GroupName:{groupName} assetPath:{assetPath}");
                        continue;
                    }
                    if (Directory.Exists(assetPath))
                    {
                        directories.Add(assetPath);
                        ////是文件夹
                        //var filePaths = FileUtil.FindFiles(assetPath);
                        //foreach (var filePath in filePaths)
                        //{
                        //    AddGroupItem(filePath, groupName, groupNameMap);
                        //}
                        continue;
                    }
                    AddGroupItem(assetPath, groupName, groupNameMap);
                }
                if (directories.Count > 0)
                {
                    AddGroupItem(directories.ToArray(), groupName, groupNameMap);
                    directories.Clear();
                }
            }
            Debug.Log($"CollectBundleGroupNames Count:{groupNameMap.Count}");
        }
        private void AddGroupItem(string[] directories, string groupName, Dictionary<string, string> groupNameMap)
        {
            var guids = AssetDatabase.FindAssets("", directories);
            foreach (var guid in guids)
            {
                var assetPath = AssetDatabase.GUIDToAssetPath(guid);
                //if (Directory.Exists(assetPath) || FileUtil.IsFileIgnore(assetPath))
                //{
                //    continue;
                //}
                AddGroupItem(assetPath, groupName, groupNameMap);
            }
        }
        private void AddGroupItem(string assetPath, string groupName, Dictionary<string, string> groupNameMap)
        {
            if (!_context.waittingAssetPaths.Contains(assetPath))
            {
                return;
            }
            //if (!_context.TryGetAddressableNameByPath(assetPath, out var addressableName))
            //{
            //    return;
            //}
            if (groupNameMap.ContainsKey(assetPath))
            {
                // 先到先得
                return;
            }
            //Debug.Log($"[XBuild]AddGroupItem addressableName:{addressableName} groupName:{groupName}");
            groupNameMap.Add(assetPath, groupName);
        }
    }
}
