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

namespace XGame.Editor.Asset.Tools
{
    public class AssetDependenciesEditor : System.IDisposable
    {
        private string _assetPath;
        private string _showName;
        private Object _assetObj;
        private bool _inited;
        public bool IsFoldout { set; get; }
        private List<AssetReorderableList> _depAssetLists;
        private int _depAssetsCount;
        private string[] _atlasRootPaths;
        public AssetDependenciesEditor(string assetPath, string[] atlasRootPaths)
        {
            _assetPath = assetPath;
            _atlasRootPaths = atlasRootPaths;
            _showName = Path.GetFileNameWithoutExtension(assetPath);
            _assetObj = AssetDatabase.LoadMainAssetAtPath(assetPath);
        }
        public void Init()
        {
            if (_inited) return;
            _inited = true;
            _depAssetsCount = 0;
            var depAssetInfoMap = new Dictionary<FileType, List<AssetInfoData>>();
            // <贴图所在的文件夹, AtlasAssetInfoData>
            var atlasInfoMap = new Dictionary<string, AtlasAssetInfoData>();
            var dependencies = AssetDatabase.GetDependencies(_assetPath, true);
            foreach (var dep in dependencies)
            {
                if (dep == _assetPath)
                {
                    continue;
                }
                _depAssetsCount++;
                var dirName = Path.GetDirectoryName(dep);
                if (atlasInfoMap.TryGetValue(dirName, out var atlasInfoData))
                {
                    atlasInfoData.sprites.Add(dep);
                }
                else
                {
                    var infoData = CreateInfo(dep);
                    var fileType = infoData.fileType;
                    if (!depAssetInfoMap.TryGetValue(fileType, out var assetInfos))
                    {
                        assetInfos = new List<AssetInfoData>();
                        depAssetInfoMap.Add(fileType, assetInfos);
                    }
                    if (fileType == FileType.Atlas)
                    {
                        var last = assetInfos.Find((a) => a.assetPath.Equals(infoData.assetPath));
                        if (last != null)
                        {
                            infoData = last;
                        }
                        else
                        {
                            assetInfos.Add(infoData);
                        }
                        atlasInfoData = infoData as AtlasAssetInfoData;
                        if (atlasInfoData.sprites == null)
                        {
                            atlasInfoData.sprites = new HashSet<string>();
                        }
                        atlasInfoData.sprites.Add(dep);
                        atlasInfoMap.Add(dirName, atlasInfoData);
                    }
                    else
                    {
                        assetInfos.Add(infoData);
                    }
                }
                
            }
            if (depAssetInfoMap.Count == 0) return;

            _depAssetLists = new List<AssetReorderableList>();
            var fileTypes = System.Enum.GetValues(typeof(FileType));
            var isFirst = true;
            foreach (FileType fileType in fileTypes)
            {
                if (depAssetInfoMap.TryGetValue(fileType, out var assetInfos))
                {
                    var reorderableList = new AssetReorderableList(fileType, assetInfos)
                    {
                        IsFoldout = isFirst
                    };
                    _depAssetLists.Add(reorderableList);
                    isFirst = false;
                }
            }
        }

        public void OnGUI()
        {
            IsFoldout = EditorGUILayout.Foldout(IsFoldout, _showName);
            if (IsFoldout)
            {
                Init();
                EditorGUILayout.BeginHorizontal();
                //缩进14像素
                GUILayout.Space(14);

                EditorGUILayout.BeginVertical();
                //选中的资源
                //展示区域，禁止操作
                EditorGUI.BeginDisabledGroup(true);
                EditorGUILayout.ObjectField(_showName, _assetObj, typeof(Object), false);
                EditorGUI.EndDisabledGroup();
                //依赖
                EditorGUILayout.LabelField($"{_showName}的依赖资源总数: {_depAssetsCount}");
                if (_depAssetLists != null)
                {
                    foreach (var depAssetList in _depAssetLists)
                    {
                        depAssetList.OnGUI();
                    }
                }
                EditorGUILayout.EndVertical();

                EditorGUILayout.EndHorizontal();


            }
        }

        private AssetInfoData CreateInfo(string assetPath)
        {
            var extension = Path.GetExtension(assetPath).ToLower();
            FileType fileType;
            if (extension.Equals(".prefab"))
            {
                fileType = FileType.Prefab;
            }
            else if (extension.Equals(".mat"))
            {
                fileType = FileType.Material;
            }
            else if (extension.Equals(".shader"))
            {
                fileType = FileType.Shader;
            }
            else if (extension.Equals(".cs"))
            {
                fileType = FileType.Script;
            }
            else if (FileUtil.IsTextureFile(assetPath))
            {
                fileType = FileType.Texture;
                if (IsAtlasSprite(assetPath))
                {
                    var dirName = Path.GetDirectoryName(assetPath);
                    while (!string.IsNullOrEmpty(dirName))
                    {
                        var files = Directory.GetFiles(dirName, "*.spriteatlas");
                        if (files.Length > 0)
                        {
                            //Debug.Log($"_spriteAtlas is {_spriteAtlas != null}  Path:{files[0]} asset:{assetPath}");
                            return new AtlasAssetInfoData()
                            {
                                fileType = FileType.Atlas,
                                assetPath = files[0]
                            };
                        }
                        else
                        {
                            dirName = Path.GetDirectoryName(dirName);
                        }
                    }
                }
            }
            else
            {
                fileType = FileType.Other;
            }
            return new AssetInfoData()
            {
                fileType = fileType,
                assetPath = assetPath
            };
        }
        private bool IsAtlasSprite(string assetPath)
        {
            if (_atlasRootPaths == null)
                return false;
            foreach(var rootPath in _atlasRootPaths)
            {
                if (assetPath.Contains(rootPath))
                {
                    return true;
                }
            }
            return false;
        }
        public void Dispose()
        {
            if (_depAssetLists != null)
            {
                foreach (var depAssetList in _depAssetLists)
                {
                    depAssetList.Dispose();
                }
                _depAssetLists.Clear();
                _depAssetLists = null;
            }
            _assetObj = null;
            _inited = false;
        }
    }

}
