using Sirenix.Utilities;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using YooAsset.Editor;

namespace ET
{
    public static class BuildHelper
    {
        private const string programName = "TikTokGameClient";
        private const string relativeDirPrefix = "../../TiktokGameClient";


        /*[InitializeOnLoadMethod]
        public static void ReGenerateProjectFiles()
        {
            if (Unity.CodeEditor.CodeEditor.CurrentEditor.GetType().Name == "RiderScriptEditor")
            {
                FieldInfo generator = Unity.CodeEditor.CodeEditor.CurrentEditor.GetType().GetField("m_ProjectGeneration", BindingFlags.Static | BindingFlags.NonPublic);
                var syncMethod = generator.FieldType.GetMethod("Sync");
                syncMethod.Invoke(generator.GetValue(Unity.CodeEditor.CodeEditor.CurrentEditor), null);
            }
            else
            {
                Unity.CodeEditor.CodeEditor.CurrentEditor.SyncAll();
            }

            Debug.Log("ReGenerateProjectFiles finished.");
        }*/


#if ENABLE_CODES
        [MenuItem("ET/ChangeDefine/Remove ENABLE_CODES")]
        public static void RemoveEnableCodes()
        {
            EnableCodes(false);
        }
#else
        [MenuItem("ET/ChangeDefine/Add ENABLE_CODES")]
        public static void AddEnableCodes()
        {
            EnableCodes(true);
        }
#endif
        private static void EnableCodes(bool enable)
        {
            string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
            var ss = defines.Split(';').ToList();
            if (enable)
            {
                if (ss.Contains("ENABLE_CODES"))
                {
                    return;
                }
                ss.Add("ENABLE_CODES");
            }
            else
            {
                if (!ss.Contains("ENABLE_CODES"))
                {
                    return;
                }
                ss.Remove("ENABLE_CODES");
            }
            defines = string.Join(";", ss);
            PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, defines);
            AssetDatabase.SaveAssets();
        }

#if ENABLE_VIEW
        [MenuItem("ET/ChangeDefine/Remove ENABLE_VIEW")]
        public static void RemoveEnableView()
        {
            EnableView(false);
        }
#else
        [MenuItem("ET/ChangeDefine/Add ENABLE_VIEW")]
        public static void AddEnableView()
        {
            EnableView(true);
        }
#endif
        private static void EnableView(bool enable)
        {
            string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
            var ss = defines.Split(';').ToList();
            if (enable)
            {
                if (ss.Contains("ENABLE_VIEW"))
                {
                    return;
                }
                ss.Add("ENABLE_VIEW");
            }
            else
            {
                if (!ss.Contains("ENABLE_VIEW"))
                {
                    return;
                }
                ss.Remove("ENABLE_VIEW");
            }

            defines = string.Join(";", ss);
            PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, defines);
            AssetDatabase.SaveAssets();
        }

        public static void Build(PlatformType type, BuildAssetBundleOptions buildAssetBundleOptions, BuildOptions buildOptions, bool isBuildExe, bool isContainAB, bool clearFolder)
        {
            BuildTarget buildTarget = BuildTarget.StandaloneWindows;
            string exeName = programName;
            switch (type)
            {
                case PlatformType.Windows:
                    buildTarget = BuildTarget.StandaloneWindows64;
                    exeName += ".exe";
                    break;
                case PlatformType.Android:
                    buildTarget = BuildTarget.Android;
                    exeName += ".apk";
                    break;
                case PlatformType.IOS:
                    buildTarget = BuildTarget.iOS;
                    break;
                case PlatformType.MacOS:
                    buildTarget = BuildTarget.StandaloneOSX;
                    break;

                case PlatformType.Linux:
                    buildTarget = BuildTarget.StandaloneLinux64;
                    break;
            }

            /*string fold = string.Format(BuildFolder, type);
            if (clearFolder && Directory.Exists(fold))
            {
                Directory.Delete(fold, true);
            }
            Directory.CreateDirectory(fold);

            if (isContainAB)
            {
                Debug.Log("start build assetbundle");
                BuildAB(buildTarget, fold);
                //BuildPipeline.BuildAssetBundles(fold, buildAssetBundleOptions, buildTarget);
                Debug.Log("finish build assetbundle");

                FileHelper.CleanDirectory("Assets/StreamingAssets/");
                FileHelper.CopyDirectory(fold, "Assets/StreamingAssets/");
                AssetDatabase.Refresh();
            }*/

            if (isBuildExe)
            {
                Debug.Log("start build exe==================");
                BuildPipeline.BuildPlayer(new string[] { "Assets/Scenes/Init.unity" }, $"{relativeDirPrefix}/{exeName}", buildTarget, buildOptions);
                Debug.Log("build exe end====================");
            }
            else
            {
                /*if (isContainAB && type == PlatformType.Windows)
                {
                    string targetPath = Path.Combine(relativeDirPrefix, $"{programName}_Data/StreamingAssets/");
                    FileHelper.CleanDirectory(targetPath);
                    Debug.Log($"src dir: {fold}    target: {targetPath}");
                    FileHelper.CopyDirectory(fold, targetPath);
                }*/
            }
        }

        //TODO:默认不使用加密
        public static void BuildAB(BuildTarget _buildTarget, string outDir, int buildVersion = -1)
        {
            string defaultOutputRoot = outDir.IsNullOrWhitespace() ? AssetBundleBuilderHelper.GetDefaultOutputRoot() : outDir;
            BuildParameters buildParameters = new BuildParameters();
            buildParameters.OutputRoot = defaultOutputRoot;
            buildParameters.BuildTarget = _buildTarget;
            buildParameters.BuildPipeline = AssetBundleBuilderSettingData.Setting.BuildPipeline;
            buildParameters.BuildMode = AssetBundleBuilderSettingData.Setting.BuildMode;
            buildParameters.BuildVersion = buildVersion > 0 ? buildVersion : AssetBundleBuilderSettingData.Setting.BuildVersion;
            buildParameters.BuildinTags = AssetBundleBuilderSettingData.Setting.BuildTags;
            buildParameters.VerifyBuildingResult = true;
            buildParameters.EnableAddressable = AssetBundleCollectorSettingData.Setting.EnableAddressable;
            buildParameters.CopyBuildinTagFiles = AssetBundleBuilderSettingData.Setting.BuildMode == EBuildMode.ForceRebuild;
            buildParameters.EncryptionServices = null;//CreateEncryptionServicesInstance();
            buildParameters.CompressOption = AssetBundleBuilderSettingData.Setting.CompressOption;
            buildParameters.OutputNameStyle = AssetBundleBuilderSettingData.Setting.OutputNameStyle;

            if (AssetBundleBuilderSettingData.Setting.BuildPipeline == EBuildPipeline.ScriptableBuildPipeline)
            {
                buildParameters.SBPParameters = new BuildParameters.SBPBuildParameters();
                buildParameters.SBPParameters.WriteLinkXML = true;
            }

            var builder = new AssetBundleBuilder();
            if (builder.Run(buildParameters).Success)
            {
                EditorUtility.RevealInFinder($"{buildParameters.OutputRoot}/{buildParameters.BuildTarget}/{buildParameters.BuildVersion}");
            }
        }
    }
}