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

namespace XGame.Editor.Build.AssetBundles
{
    public class ABPackerInfoManifestWindow
    {
        private ABPackerInfoManifest manifest;
        private readonly bool isInspector;
        private GUIContent _shaderContent;
        private ABPackerReorderableList<ABPackerInfoItem, ABPackerInfo> _abPackerList;
        private ABPackerReorderableList<ABGroupInfoItem, ABGroupInfo> _abGroupList;



        public ABPackerInfoManifestWindow(ABPackerInfoManifest manifest, bool isInspector)
        {
            this.manifest = manifest;
            this.isInspector = isInspector;
            _shaderContent = new GUIContent("是否合并Shader", "将*.shadervariants文件和其所依赖的shader一起打在一个包内");
            var apckerToolTip = "打包分类 \r\nTopDirectoryOnly：默认方式，当前目录的资源(不包含子目录)打一个包 \r\nAllDirectories：当前目录及子目录的资源打一个包 \r\nSingleAsset：单个资源打包";
            _abPackerList = new ABPackerReorderableList<ABPackerInfoItem, ABPackerInfo>(manifest.PackerInfos, "Assetbundle打包配置", apckerToolTip)
            {
                IsFoldout = true
            };
            var groupToolTip = "设置分组的资源，Assetbundle会生成在指定分组文件夹下: StreamAssets/{Platform}/AssetBundles/{GroupName}/ ";
            _abGroupList = new ABPackerReorderableList<ABGroupInfoItem, ABGroupInfo>(manifest.GroupInfos, "Assetbundle分组配置", groupToolTip)
            { 
                IsFoldout = true
            };

        }

        

        public void OnGUI()
        {
            EditorGUILayout.BeginVertical();
            manifest.bundleNameMode = (AssetBundleNameMode)EditorGUILayout.EnumPopup("Bundle命名模式", manifest.bundleNameMode);
            manifest.isMergeShader = EditorGUILayout.Toggle(_shaderContent, manifest.isMergeShader);
            _abPackerList.OnGUI();
            _abGroupList.OnGUI();
            DrawButtons();
            DrawMsg();
            EditorGUILayout.EndVertical();
        }


        private void DrawButtons()
        {
            var apply = GUILayout.Button("Apply");
            if (apply)
            {
                //刷新
                OnApplyBtn();
            }
        }

        private void DrawMsg()
        {
            GUILayout.Space(20);
            EditorGUILayout.HelpBox("友情提示：如有修改请及时上传同步 Manifest 文件，否则后果自负。", MessageType.Warning);
            //GUI.color = Color.red;
            //GUILayout.TextArea("友情提示：如有修改请及时上传同步 Manifest 文件，否则后果自负。", GUI.skin.textArea);
            //GUI.color = Color.white;

            GUILayout.Space(5);
            EditorGUI.BeginDisabledGroup(true);
            EditorGUILayout.ObjectField("Manifest", manifest, typeof(Object), false);
            EditorGUI.EndDisabledGroup();
        }

        private void OnApplyBtn()
        {
            ApplyPackerInfos();
            ApplyGroupInfos();
            manifest.Save();
            Debug.Log("ABPackerInfoManifest apply completed.");
        }
        private void ApplyPackerInfos()
        {
            var guids = new HashSet<string>();
            var packerInfos = new List<ABPackerInfo>();
            foreach (var item in manifest.PackerInfos)
            {
                var guid = item.GUID;
                if (string.IsNullOrEmpty(guid))
                {
                    Debug.LogWarning($"AssetbundlePacker 资源为空. {item}");
                }
                else if (guids.Contains(guid))
                {
                    Debug.LogError($"AssetbundlePacker 资源重复. Path: {AssetDatabase.GUIDToAssetPath(guid)}");
                }
                else
                {
                    guids.Add(guid);
                    packerInfos.Add(item);
                }
            }
            manifest.PackerInfos.Clear();
            manifest.PackerInfos.AddRange(packerInfos);
        }
        private void ApplyGroupInfos()
        {
            var datas = _abGroupList.GetItemDatas();
            var guids = new HashSet<string>();
            var groupMap = new Dictionary<string, ABGroupInfo>();
            foreach (var data in datas)
            {
                var groupName = data.groupName.Trim();
                if (string.IsNullOrEmpty(groupName) || Asset.FileUtil.HasChinese(groupName))
                {
                    Debug.LogError($"AssetbundleGroup 名字为空或者包含中文字符! GroupName:{groupName}");
                    continue;
                }
                if (LanguageUtils.IsLanguage(groupName))
                {
                    Debug.LogError($"AssetbundleGroup 名字不能为多语言枚举. GroupName:{groupName}");
                    continue;
                }
                if (groupMap.ContainsKey(groupName))
                {
                    Debug.LogError($"AssetbundleGroup 名字重复. GroupName:{groupName}");
                    continue;
                }
                for(var i = data.guidList.Count - 1; i >= 0; i--)
                {
                    var guid = data.guidList[i];
                    if (string.IsNullOrEmpty(guid))
                    {
                        data.guidList.RemoveAt(i);
                    }
                    else if (guids.Contains(guid))
                    {
                        data.guidList.RemoveAt(i);
                        Debug.LogError($"AssetbundleGroup 资源重复. Path:{AssetDatabase.GUIDToAssetPath(guid)}");
                    }
                    else
                    {
                        guids.Add(guid);
                    }
                }
                if (data.guidList.Count < 1)
                {
                    Debug.LogError($"AssetbundleGroup 资源列表为空! GroupName:{groupName}");
                    continue;
                }
                data.groupName = groupName;
                groupMap.Add(groupName, data);
            }
            manifest.GroupInfos.Clear();
            foreach(var item in groupMap)
            {
                manifest.GroupInfos.Add(item.Value);
            }
        }

        public void Close()
        {
            (_abPackerList as System.IDisposable)?.Dispose();
            _abPackerList = null;
            (_abGroupList as System.IDisposable)?.Dispose();
            _abGroupList = null;
            manifest = null;
        }
    }

}
