using System.Collections.Generic;
using System.IO;
using System.Linq;
using SGModule.Common.Helper;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEditor.PackageManager.Requests;
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
#if USE_ADDRESSABLES
using UnityEditor.AddressableAssets;
#endif

namespace SGModule.Editor {
    [InitializeOnLoad]
    public static class AddressablesManager {
        private const string AddressablesPackageName = "com.unity.addressables";
        private const string AddressablesSymbol = "USE_ADDRESSABLES";
        private static AddRequest _addRequest;

        // 安装标记，避免重复弹窗
        private static bool _isInstallingAddressables;

        static AddressablesManager() {
            EditorApplication.projectChanged += OnProjectChanged; // 监听项目变更

            CheckAndSetupAddressables();
        }

        private static string DefaultConfigsPath => "Assets/Configs"; // 默认的 Addressables 配置路径

        private static void CheckAndSetupAddressables() {
            if (IsAddressablesInstalled()) {
                Log.Info("ConfigLoader", "Addressables 已安装，正在初始化...");

                AddScriptingDefineSymbol(AddressablesSymbol);

#if USE_ADDRESSABLES
                EnsureAddressablesConfigured();
#endif
            }
            else {
                RemoveScriptingDefineSymbol(AddressablesSymbol);
                if (!_isInstallingAddressables) {
                    PromptToInstallAddressables();
                }
            }
        }

        private static bool IsAddressablesInstalled() {
            return PackageInfo.GetAllRegisteredPackages().Any(package => package.name == AddressablesPackageName);
        }

        private static void PromptToInstallAddressables() {
            var install = EditorUtility.DisplayDialog(
                "Addressables 未安装",
                "当前插件依赖 Addressables 功能，请安装以确保正常使用。\n\n是否立即安装 Addressables？",
                "安装",
                "取消");

            if (install) {
                InstallAddressables();
            }
            else {
                Log.Warning("ConfigLoader", "用户取消安装 Addressables，部分功能可能无法正常使用！");
            }
        }

        private static void InstallAddressables() {
            if (_isInstallingAddressables) {
                return; // 防止重复安装
            }

            Log.Info("ConfigLoader", "开始安装 Addressables...");

            _isInstallingAddressables = true; // 标记正在安装，避免重复弹窗
            _addRequest = Client.Add(AddressablesPackageName);

            EditorApplication.update += MonitorAddRequest;
        }

        private static void MonitorAddRequest() {
            if (_addRequest == null || !_addRequest.IsCompleted) {
                return;
            }

            EditorApplication.update -= MonitorAddRequest;

            if (_addRequest.Status == StatusCode.Success) {
                Log.Info("ConfigLoader", "Addressables 安装成功！");

                EditorUtility.DisplayDialog("安装完成", "Addressables 安装成功，请稍候等待 Unity 刷新。", "确定");

                CheckAndSetupAddressables();
            }
            else if (_addRequest.Status >= StatusCode.Failure) {
                Log.Error("ConfigLoader", $"安装 Addressables 失败：{_addRequest.Error.message}");

                EditorUtility.DisplayDialog("安装失败", $"安装 Addressables 失败：{_addRequest.Error.message}", "确定");
            }

            _isInstallingAddressables = false; // 重置标记
        }

        private static void AddScriptingDefineSymbol(string symbol) {
            var symbols = new List<string>(PlayerSettings
                .GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup).Split(';'));
            if (symbols.Contains(symbol)) {
                return;
            }


            symbols.Add(symbol);
            PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup,
                string.Join(";", symbols));
            Log.Info("ConfigLoader", $"已添加脚本定义符号: {symbol}");
        }

        private static void RemoveScriptingDefineSymbol(string symbol) {
            var symbols = new List<string>(PlayerSettings
                .GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup).Split(';'));
            if (symbols.Contains(symbol)) {
                symbols.Remove(symbol);
                PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup,
                    string.Join(";", symbols));

                Log.Info("ConfigLoader", $"已移除脚本定义符号: {symbol}");
            }
        }

        private static void OnProjectChanged() {
            Log.Info("ConfigLoader", "检测到项目变更，重新检查 Addressables 状态...");

            CheckAndSetupAddressables();
        }

#if USE_ADDRESSABLES
        private static void EnsureAddressablesConfigured() {
            var settings = AddressableAssetSettingsDefaultObject.Settings;

            if (settings == null) {
                Log.Info("ConfigLoader", "正在初始化 Addressables 设置...");

                settings = AddressableAssetSettingsDefaultObject.GetSettings(true); // 自动创建配置
            }

            // 确保默认的 Configs 文件夹存在并被添加到 Addressables
            var needRefresh = false;
            if (!Directory.Exists(DefaultConfigsPath)) {
                Directory.CreateDirectory(DefaultConfigsPath);
                Log.Info("ConfigLoader", $"已创建文件夹: {DefaultConfigsPath}");

                needRefresh = true;
            }

            if (!IsFolderInAddressables(DefaultConfigsPath)) {
                var guid = AssetDatabase.AssetPathToGUID(DefaultConfigsPath);
                var group = settings.DefaultGroup;
                settings.CreateOrMoveEntry(guid, group)?.SetLabel("config", true, true);
                needRefresh = true;
            }

            if (needRefresh) {
                AssetDatabase.Refresh();
            }
        }

        private static bool IsFolderInAddressables(string folderPath) {
            var settings = AddressableAssetSettingsDefaultObject.Settings;
            foreach (var group in settings.groups)
            {
                if (group)
                {
                    foreach (var entry in group.entries)
                    {
                        if (AssetDatabase.GUIDToAssetPath(entry.guid) == folderPath)
                        {
                            return true;
                        }
                    }
                }
            }


            return false;
        }
#endif
    }
}
