using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;

namespace XGame.Editor.Asset.Tools
{
    public static class FindReferences
    {

        private class Logger
        {
            StringBuilder sb = new StringBuilder();

            public void Debug(string info)
            {
                sb.AppendLine(info.Replace(StrColor, "").Replace("</color>", ""));
                UnityEngine.Debug.Log(info);
            }

            public void Debug(string info, Object context)
            {
                sb.AppendLine(info.Replace(StrColor, "").Replace("</color>", ""));
                UnityEngine.Debug.Log(info, context);
            }

            public void Error(string error)
            {
                UnityEngine.Debug.LogError(error);
            }

            /// <summary>
            /// 把日志内容显示在记事本中
            /// </summary>
            public void ShowInNotepad()
            {
#if UNITY_EDITOR_WIN
                try
                {
                    var path = Path.GetTempPath() + Path.GetRandomFileName();
                    File.WriteAllText(path, sb.ToString());
                    var proc = System.Diagnostics.Process.Start("notepad.exe", path);
                }
                catch (Exception e)
                {
                    UnityEngine.Debug.LogException(e);
                }
#endif
            }

            public void Clear()
            {
                sb.Clear();
            }
        }

        private const string StrColor = "<color=darkblue>";

        #region 查找引用

        [MenuItem("Assets/查找引用", false, 130)]
        private static void Find()
        {

            var lstPath = new List<string>();
            foreach (var obj in Selection.objects)
            {
                var assetPath = AssetDatabase.GetAssetPath(obj);
                if (Directory.Exists(assetPath))
                {
                    var files = Directory.GetFiles(assetPath, "*", SearchOption.AllDirectories);
                    foreach (var file in files)
                    {
                        lstPath.Add(FileUtil.ToRelativePath(file).Replace("\\", "/"));
                    }
                }
                else
                {
                    lstPath.Add(assetPath);
                }
            }
            lstPath = lstPath.Distinct().ToList();// .Where(p => FileUtil.IsFileIgnore(p) == false)
            var count = lstPath.Count;
            if (count == 0) return;
            var logger = new Logger();
            try
            {

                var extensions = new List<string>() { ".prefab", ".unity", ".mat", ".asset", ".fontsettings", ".anim" };
                var files = Directory.GetFiles(Application.dataPath, "*.*", SearchOption.AllDirectories)
                    .Where(s =>
                    {
                        var temp = s.Replace("\\", "/");
                        if (FileUtil.IsFileIgnore(temp) || temp.Contains(PathDefine.ConfigsRelative))
                        {
                            return false;
                        }
                        return extensions.Contains(Path.GetExtension(temp).ToLower());
                    }).ToArray();
                var fileCount = files.Length;

                foreach (var assetPath in lstPath)
                {
                    var guid = AssetDatabase.AssetPathToGUID(assetPath);
                    if (string.IsNullOrEmpty(guid)) continue;
                    var addressableName = AddressableHelper.GUIDToName(guid);
                    var fileIndex = 0;
                    logger.Debug("====================================");
                    logger.Debug($"{StrColor}匹配开始 Path:{assetPath} GUID:{guid}</color>", AssetDatabase.LoadAssetAtPath<Object>(assetPath));
                    bool isCancel = false;
                    foreach (var file in files)
                    {
                        var fileRelativePath = FileUtil.ToRelativePath(file.Replace("\\", "/"));
                        isCancel = EditorUtility.DisplayCancelableProgressBar($"查找引用: {assetPath}", fileRelativePath, (float)(fileIndex++) / files.Length);
                        var text = File.ReadAllText(file);
                        if (Regex.IsMatch(text, guid) || (!string.IsNullOrEmpty(addressableName) && Regex.IsMatch(text, addressableName)))
                        { //查找GUID或者addressableName的引用
                            logger.Debug($"{StrColor}{fileRelativePath}</color>", AssetDatabase.LoadAssetAtPath<Object>(fileRelativePath));
                        }
                        if (isCancel)
                        {
                            logger.Debug("用户取消查找!");
                            break;
                        }
                    }
                    logger.ShowInNotepad();
                    logger.Clear();
                    EditorUtility.ClearProgressBar();
                    if (isCancel)
                    {
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                UnityEngine.Debug.LogException(ex);
            }

        }

        [MenuItem("Assets/查找引用", true)]
        private static bool VFind()
        {
            var path = AssetDatabase.GetAssetPath(Selection.activeObject);
            return (!string.IsNullOrEmpty(path));
        }


        #endregion

        #region 查找依赖

        [MenuItem("Assets/查找依赖", false, 131)]
        public static void FindDependencies()
        {
            AssetsDependenciesWindow.CreateWindow();
        }

        [MenuItem("Assets/查找依赖", true)]
        private static bool FindIncludeReferencesCheck()
        {
            var path = AssetDatabase.GetAssetPath(Selection.activeObject);
            return (!string.IsNullOrEmpty(path));
        }


        #endregion
    }

}