using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Build;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine;

namespace TyphoonUnitySDK
{
    public class AddressableTool
    {
        public static AddressableAssetSettings DefaultSettings =>
            AddressableAssetSettingsDefaultObject.Settings;

        /// <summary>
        /// 弹出菜单，选择Profile
        /// </summary>
        public static void PopUpProfileSelectorMenu(PublishSetting publish)
        {
            var settings = DefaultSettings;
            if (settings == null)
            {
                Debug.LogError("找不到Settings,请先初始化 Addressables");
                return;
            }

            var menu = new GenericMenu();
            var profileSettings = settings.profileSettings;
            foreach (var element in profileSettings.GetAllProfileNames())
            {
                menu.AddItem(new GUIContent(element), false, () =>
                {
                    publish.AAUseProfile = element;
                    EditorUtility.SetDirty(publish);
                    AssetDatabase.SaveAssets();
                });
            }

            menu.ShowAsContext();
        }


        /// <summary>
        /// 是否创建了默认设置
        /// </summary>
        public static bool HasDefaultSettings()
        {
            return DefaultSettings != null;
        }

        /// <summary>
        /// 设置AA相关参数
        /// </summary>
        public static void ModifyAAProfileAndVariables(PublishSetting publish)
        {
            if (!publish.AASupportEnable)
            {
                return;
            }

            if (!HasDefaultSettings())
            {
                return;
            }

            var settings = DefaultSettings;
            //激活profile
            settings.activeProfileId =
                settings.profileSettings.GetProfileId(publish.AAUseProfile);
            ModifyVariable(publish);
        }

        /// <summary>
        /// 设置参数
        /// </summary>
        public static void SetVariable(PublishSetting publish, string variableName, string value, bool save = false)
        {
            if (string.IsNullOrEmpty(publish.AAUseProfile))
            {
                Debug.LogError("未关联profile");
                return;
            }

            var success = SetVariable(publish.AAUseProfile, variableName, value);
            EditorUtility.SetDirty(DefaultSettings);
            if (save && success)
            {
                AssetDatabase.SaveAssets();
            }
        }

        /// <summary>
        /// 修改AA参数
        /// </summary>
        public static void ModifyVariable(PublishSetting publish)
        {
            var modifies = publish.AAVariableModify;
            foreach (var modify in modifies)
            {
                SetVariable(publish.AAUseProfile, modify.VariableName, modify.VariableValue);
            }

            EditorUtility.SetDirty(DefaultSettings);
        }

        /// <summary>
        /// 设置参数
        /// </summary>
        public static bool SetVariable(string profileName, string variableName, string value)
        {
            try
            {
                var settings = DefaultSettings;
                var profileId = settings.profileSettings.GetProfileId(profileName);
                settings.profileSettings.SetValue(profileId, variableName, value);
                return true;
            }
            catch (Exception e)
            {
                Debug.LogError($"设置aa参数失败，profile:{profileName} vaiableName:{variableName} value:{value}");
            }

            return false;
        }

        /// <summary>
        /// 是否包含Profile
        /// </summary>
        public static bool ContainProfile(string profile)
        {
            try
            {
                if (string.IsNullOrEmpty(profile))
                {
                    return false;
                }

                var settings = DefaultSettings;
                return settings.profileSettings.GetAllProfileNames().Contains(profile);
            }
            catch (Exception e)
            {
                return false;
            }
        }

        /// <summary>
        /// 一键构建AA
        /// </summary>
        public static void BuildAASource(PublishSetting publish)
        {
            if (!HasDefaultSettings())
            {
                throw new Exception("未初始化Addresable");
            }

            //选择激活的参数
            var settings = DefaultSettings;
            var profileId = settings.activeProfileId;
            if (publish.AASupportEnable && ContainProfile(publish.AAUseProfile))
            {
                profileId = settings.profileSettings.GetProfileId(publish.AAUseProfile);
                settings.activeProfileId = profileId;
                foreach (var element in publish.AAVariableModify)
                {
                    SetVariable(publish.AAUseProfile, element.VariableName, element.VariableValue);
                }

                EditorUtility.SetDirty(settings);
            }

            foreach (var builder in settings.DataBuilders)
            {
                AddressableAssetSettings.CleanPlayerContent(builder as IDataBuilder);
            }

            Debug.Log(
                $"<color=#{SdkDebug.BlueHex}>使用profile:{settings.profileSettings.GetProfileName(profileId)}</color>");
            Debug.Log(
                $"<color=#{SdkDebug.BlueHex}>想要在AA构建前or后做点事情？任意Editor文件夹下创建class继承于TyphoonUnitySDK.OnBuildAAProcessor</color>");
            //触发AA回调
            var sub = GetSubClassTypes(typeof(OnBuildAAProcessor));
            var match = new List<OnBuildAAProcessor>();
            foreach (var type in sub)
            {
                var instance = Activator.CreateInstance(type) as OnBuildAAProcessor;
                match.Add(instance);
            }

            foreach (var processor in match)
            {
                processor.OnBeforeBuild(publish);
            }

            AddressableAssetSettings.BuildPlayerContent(out var outResult);
            foreach (var processor in match)
            {
                processor.OnAfterBuild(publish);
            }
        }

        /// <summary>
        /// 获取参数名
        /// </summary>
        public static List<string> GetVariables()
        {
            var settings = DefaultSettings;
            if (settings != null)
            {
                return settings.profileSettings.GetVariableNames();
            }

            var result = new List<string>();
            return result;
        }


        /// <summary>
        /// 获取属性名
        /// </summary>
        public static string GetVariableValue(string variableName)
        {
            try
            {
                var settings = DefaultSettings;
                return settings.profileSettings.GetValueByName(settings.activeProfileId, variableName);
            }
            finally
            {
            }

            return string.Empty;
        }


        public static List<Type> GetSubClassTypes(Type check)
        {
            var result = new List<Type>();
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var element in assemblies)
            {
                var types = element.GetTypes();
                foreach (var type in types)
                {
                    if (type == check)
                    {
                        continue;
                    }
                    else if (type.IsSubclassOf(check))
                    {
                        result.Add(type);
                    }
                }
            }

            return result;
        }
    }
}