namespace Hive.Unity.Editor
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Xml;
    using System.ComponentModel;
    #if UNITY_EDITOR
    using UnityEditor;
    #endif
    using UnityEngine;

    public class HiveConfigXmlStep : HiveStep
    {
        private static bool autoValidation = false;
        private static readonly string hiveConfigXmlCommonGuideLink = "https://developers.hiveplatform.ai/ko/latest/dev/basic-config/xml/common/";
        private static readonly string hiveConfigXmlAuthGuideLink = "https://developers.hiveplatform.ai/ko/latest/dev/authv4/hive-sdk-prep/common/idp-console-keys/";
        private static readonly string hiveConfigXmlMarketGuideLink = "https://developers.hiveplatform.ai/ko/latest/dev/billing/";
        private static readonly string hiveConfigXmlAnalyticsGuideLink = "https://developers.hiveplatform.ai/ko/latest/dev/marketing-attribution/hive-sdk-prep/common/";
        private static readonly string hiveConfigXmlOptionalGuideLink = hiveConfigXmlCommonGuideLink;

        enum HiveConfigPlatform
        {
            [Description("Android")]
            android,
            [Description("iOS")]
            ios,
            [Description("macOS")]
            mac,
            [Description("Windows")]
            windows
        }

        enum HiveConfigMenu
        {
            common, auth, market, analytics, optional
        }

        HiveConfigXmlData[] configs;
        HiveConfigXmlData config {
            get {
                return configs[(int)selectedPlatform];
            }
        }

        internal override HiveConfigStep currentStep {
            get {
                return HiveConfigStep.Step_Hive_Config;
            }
        }
        HiveConfigMenu currentMenu;
        HiveConfigPlatform selectedPlatform;
        HiveConfigPlatform currentPlatform {
            get {
                switch (EditorUserBuildSettings.activeBuildTarget) {
                    case BuildTarget.Android: return HiveConfigPlatform.android;
                    case BuildTarget.iOS: return HiveConfigPlatform.ios;
                    case BuildTarget.StandaloneOSX: return HiveConfigPlatform.mac;
                    case BuildTarget.StandaloneWindows: return HiveConfigPlatform.windows;
                    default: return HiveConfigPlatform.android;
                }
            }
        }

        internal HiveConfigXmlStep(Rect position): base(position)
        {
            this.selectedPlatform = currentPlatform;
            this.configs = new HiveConfigXmlData[] {
                new HiveConfigXmlData((int)HiveConfigPlatform.android),
                new HiveConfigXmlData((int)HiveConfigPlatform.ios),
                new HiveConfigXmlData((int)HiveConfigPlatform.mac),
                new HiveConfigXmlData((int)HiveConfigPlatform.windows),
            };
        }

        internal override HiveConfigStep dropdownMenu()
        {
            HiveConfigStep step;
            step = HiveConfigStep.Step_Hive_Config;
            return step;
        }

        internal override void titleArea()
        {
            gui.Vertical(()=>{
                gui.Space(10);
                gui.HeaderText("Hive Config", HiveGUI.HeaderSize.h1);
                gui.Label("\'Hive Config\' settings are supported independently for each OS.\n(Hive Config 설정은 각 OS별로 독립적으로 지원합니다.)\n");
            });
            gui.Separator();
        }

        internal override void selectPlatformArea()
        {
            string title = " Config";
            HiveGUI.Icon icon = HiveGUI.Icon.android;
            switch (selectedPlatform) {
                case HiveConfigPlatform.android:
                    title = "Android Config";
                    icon = HiveGUI.Icon.android;
                break;
                case HiveConfigPlatform.ios:
                    title = "iOS Config";
                    icon = HiveGUI.Icon.ios;
                break;
                case HiveConfigPlatform.mac:
                    title = "macOS Config";
                    icon = HiveGUI.Icon.mac;
                break;
                case HiveConfigPlatform.windows:
                    title = "Windows Config";
                    icon = HiveGUI.Icon.windows;
                break;
            }

            gui.Space(20);

            gui.Horizontal(()=>{
                gui.IconHeaderText(title, icon, HiveGUI.HeaderSize.h2);
                gui.Filler();
                gui.DropdownMenu("", "", ref selectedPlatform);
            });

            gui.Space(20);
        }

        internal override void contentsArea()
        {
            toolBar();
            scrollView();
            checkingView();
        }

        internal override void buttonsArea()
        {
            buttonsView();
        }

        void toolBar()
        {
            string[] menuNames = new string[]{"Common", "Auth", "Market", "Analytics", "Optional"};
            gui.Horizontal(()=>{
                currentMenu = (HiveConfigMenu)GUILayout.Toolbar((int)currentMenu, menuNames, GUILayout.Height(30));
            });
        }

        void scrollView()
        {
            EditorGUI.BeginChangeCheck();   // UI 변경사항 감지

            int scrollHeight = (int)(rect.height * 0.45);
            gui.BoxArea(scrollHeight, "config_contents", ()=>{
                switch (currentMenu) {
                    case HiveConfigMenu.common:         // Common
                        showCommonConfig();
                    break;
                    case HiveConfigMenu.auth:           // Auth
                        showAuthConfig();
                    break;
                    case HiveConfigMenu.market:         // Market
                        showMarketConfig();
                    break;
                    case HiveConfigMenu.analytics:      // Analytics
                        showAnalyticsConfig();
                    break;
                    case HiveConfigMenu.optional:       // Optional
                        showOptionalConfig();
                    break;
                }
            });

            if (EditorGUI.EndChangeCheck())
            {
                HiveLogger.Log("Hive Config UI option changed.");
                HiveSdkSettings.checkChangedUI = true;
            }

            gui.Space();
        }

        void checkingView()
        {
            if (selectedPlatform == HiveConfigPlatform.android)
            {
                string classNameValue = "";
#if UNITY_2023_1_OR_NEWER
                if (PlayerSettings.Android.applicationEntry == AndroidApplicationEntry.Activity)
                    classNameValue = Utility.GetConstStringValue("HiveManifestMod", "HiveUnityMainActivity");
                else
                    classNameValue = Utility.GetConstStringValue("HiveManifestMod", "HiveUnityMainGameActivity");
#else
                classNameValue = Utility.GetConstStringValue("HiveManifestMod", "HiveUnityMainActivity");
#endif

                gui.SelectableText(
                    "Package Name", 
                    "aka: the bundle identifier", 
                    config.Xml.HIVEAppID
                );
                gui.SelectableText(
                    "Class Name", 
                    "aka: the activity class name for Launch & Engagements as Deeplink", 
                    classNameValue
                );
            }

            if (selectedPlatform == HiveConfigPlatform.ios)
            {
                gui.SelectableText(
                    "Bundle Id", 
                    "iOS Bundle Identifier. Change in Player Settings.", 
                    PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.iOS)
                );
                gui.SelectableText(
                    "URL Scheme Suffix", 
                    "Use this to share Facebook APP ID's across multiple iOS apps.",
                    config.Xml.facebookAppID
                );
                gui.SelectableText(
                    "Hive URL Scheme", 
                    "Use this for Hive Deeplink across multiple iOS apps.",
                    config.Xml.HIVEAppID
                );
            }

            gui.Space();
        }

        void buttonsView()
        {
            string actionMsg1 = "";
            string actionMsg2 = "";
            string actionMsg3 = "";

            switch (selectedPlatform) {
                case HiveConfigPlatform.android:
                    actionMsg1 = "Save & Regenerate setting files";     // 버튼 택스트 간소화
                    actionMsg3 = "Open Hive Dependencies";
                break;
                case HiveConfigPlatform.ios:
                    actionMsg1 = "Save & Regenerate setting files";     // 버튼 택스트 간소화
                    actionMsg2 = "Build iOS project post process settings";
                    actionMsg3 = "Open Hive Dependencies";
                break;
                case HiveConfigPlatform.mac:
                    actionMsg1 = "macOS Button";
                break;
                case HiveConfigPlatform.windows:
                    actionMsg1 = "Windows Button";
                break;
            }

            // button 1, 2
            if (selectedPlatform == HiveConfigPlatform.android) {
                gui.TintedButton(
                    actionMsg1,
                    "#8294a8",
                    HiveGUI.ButtonSize.wide,
                    ()=>{
                        processSettings();
                        HiveSdkSettings.checkChangedUI = false;

                        // Save 버튼 플로우 마지막에 완료 팝업 노출
                        if (EditorUtility.DisplayDialog("Hive Config", "Setup and save complete.\n설정 및 저장 완료.", "OK"))
                        {
                            HiveLogger.Log("OK button clicked.");
                        }
                    }
                );
            } else {
                gui.Horizontal(()=>{
                    gui.TintedButton(
                        actionMsg1,
                        "#8294a8",
                        HiveGUI.ButtonSize.medium,
                        string.IsNullOrEmpty(actionMsg2) ? 1 : 0.5f, 
                        ()=>{
                            processSettings();
                            HiveSdkSettings.checkChangedUI = false;

                            // Save 버튼 플로우 마지막에 완료 팝업 노출
                            if (EditorUtility.DisplayDialog("Hive Config", "Setup and save complete.\n설정 및 저장 완료.", "OK"))
                            {
                                HiveLogger.Log("OK button clicked.");
                            }
                        }
                    );
                    gui.Filler();
                    if (!string.IsNullOrEmpty(actionMsg2)) {
                        gui.Button(
                            actionMsg2,
                            HiveGUI.ButtonSize.medium,
                            0.5f, 
                            ()=>{
                                processPostProcess();
                            }
                        );
                    }
                });
            }

            // button 3
            if (!string.IsNullOrEmpty(actionMsg3)) {
                gui.Button(
                    actionMsg3,
                    HiveGUI.ButtonSize.wide,
                    ()=>{
                        ExternalDependencyEditor.create();
                    }
                );
            }
        }

        void processSettings()
        {
            switch (selectedPlatform) {
                case HiveConfigPlatform.android:
                    PrepareAndroidSetting();
                break;
                case HiveConfigPlatform.ios:
                    HiveConfigXML.iOS.commit();
                break;
                case HiveConfigPlatform.mac:
                    HiveConfigXML.macOS.commit();
                break;
                case HiveConfigPlatform.windows:
                    HiveConfigXML.Windows.commit();
                break;
                default:
                    config.Xml.commit();
                break;
            }
        }

        void processPostProcess()
        {
            switch (selectedPlatform) {
                case HiveConfigPlatform.ios:
                    Utility.InvokeMethod("HivePostProcessMenu", "showHivePostProcessEditorIOS");
                break;
                default:
                break;
            }
        }

        // GUI in ScrollView
        void showCommonConfig()
        {   
            XmlCommon commonConfig = new XmlCommon(config);

            if (selectedPlatform == HiveConfigPlatform.ios) {
                gui.EditableText(
                    "Universal Link", 
                    "Fill the form when you need universal link", 
                    ref commonConfig.universalLink
                );
                gui.Space();
                gui.Separator();
                gui.Space();
            }

            gui.EditableText(
                "Hive App Id", 
                "(hive_config.xml appId) 게임 빌드 식별자", 
                ref commonConfig.hiveAppId,
                hiveConfigXmlCommonGuideLink
            );
            gui.Space(); 

            gui.DropdownMenu(
                "Zone", 
                "(hive_config.xml zone) Hive 클라이언트가 접속할 서버(sandbox:테스트, real:운영)", 
                ref commonConfig.zone,
                hiveConfigXmlCommonGuideLink
            );
            gui.Space();

            gui.ToggleWide(
                "Logging", 
                "(hive_config.xml useLog) Hive 클라이언트K 내부 동작 로그 활성 여부", 
                ref commonConfig.useLog,
                hiveConfigXmlCommonGuideLink
            );
            gui.Space();

            gui.ToggleWide(
                "AgeGateU13",
                "(hive_config.xml ageGateU13) COPPA ageGateU13 적용 여부",
                ref commonConfig.ageGateU13,
                hiveConfigXmlCommonGuideLink
            );
            gui.Space();

            gui.DropdownMenu(
                "Hive Orientation", 
                "(hive_config.xml hiveOrientation) 스크린 내 Hive UI 노출 방향(undefined, all, portrait, landscape)",
                ref commonConfig.hiveOrientation,
                hiveConfigXmlCommonGuideLink
            );
            gui.Space();

            gui.EditableText(
                "Channel", 
                "(hive_config.xml channel) 게임 빌드에서 사용하는 로그인 서비스 플랫폼", 
                ref commonConfig.channel,
                hiveConfigXmlCommonGuideLink
            );
            gui.Space();

            // Market 값의 경우 설정한 값이 없는 경우 OS 구분하여 기본값을 보여주도록 제어 (25.2.0)
            if (selectedPlatform == HiveConfigPlatform.android) {
                if(commonConfig.market == null || commonConfig.market == "") {
                    commonConfig.market = "GO";
                }
                gui.EditableText(
                    "Market", 
                    "(hive_config.xml market) 게임 빌드에서 인앱 구매를 사용하는 마켓", 
                    ref commonConfig.market,
                    hiveConfigXmlCommonGuideLink
                );
            }
            else if (selectedPlatform == HiveConfigPlatform.ios) {
                if(commonConfig.market == null || commonConfig.market == "") {
                    commonConfig.market = "AP";
                }
                gui.EditableText(
                    "Market", 
                    "(hive_config.xml market) 게임 빌드에서 인앱 구매를 사용하는 마켓", 
                    ref commonConfig.market,
                    hiveConfigXmlCommonGuideLink
                );
            }
            else {  // case : ( selectedPlatform == HiveConfigPlatform.mac || selectedPlatform == HiveConfigPlatform.windows)
                if(commonConfig.market == null || commonConfig.market == "") {
                    commonConfig.market = "";
                }
                gui.EditableText(
                    "Market", 
                    "(hive_config.xml market) 게임 빌드에서 인앱 구매를 사용하는 마켓", 
                    ref commonConfig.market,
                    hiveConfigXmlCommonGuideLink
                );
            }
            gui.Space();

            commonConfig.Apply();
        }

        void showAuthConfig()
        {
            XmlAuth authConfig = new XmlAuth(config);

            // Facebook: android, ios
            gui.HeaderText("Facebook");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.Facebook);
            gui.EditableText(
                "Facebook App Id",
                "Facebook 로그인 기능 사용을 위한 앱 ID",
                ref authConfig.facebook.appId,
                hiveConfigXmlAuthGuideLink
            );
            gui.EditableText(
                "Facebook Client Token",
                "Facebook 로그인 기능을 사용을 위한 클라이언트 토큰",
                ref authConfig.facebook.clientToken,
                "https://developers.facebook.com/docs/facebook-login/guides/access-tokens/#clienttokens"
            );
            gui.ValueInputField(
                "Facebook Permissions",
                "(hive_config.xml facebook-permissions) Facebook 기능 사용 시 게임 빌드에서 사용할 Facebook 권한",
                ref authConfig.facebook.permissions,
                hiveConfigXmlAuthGuideLink
            );
            authConfig.facebook.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();

            // Google: android, ios
            gui.HeaderText("Google SignIn");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.Google);
            if (selectedPlatform == HiveConfigPlatform.android)
                gui.EditableText(
                    "Google App Id",
                    "(hive_config.xml google-playAppId) Google Cloud 콘솔에서 발급받은 Android 유형 클라이언트 ID",
                    ref authConfig.google.appId,
                    hiveConfigXmlAuthGuideLink
                );
            if (selectedPlatform == HiveConfigPlatform.ios || selectedPlatform == HiveConfigPlatform.mac || selectedPlatform == HiveConfigPlatform.windows)
                gui.EditableText(
                    "Google Client Id",
                    "Google Cloud 콘솔에서 발급받은 클라이언트 ID",
                    ref authConfig.google.clientId,
                    "https://play.google.com/apps/publish/#GameListPlace"
                );
            if (selectedPlatform == HiveConfigPlatform.ios)
                gui.EditableText(
                    "Google Reversed Client Id",
                    "(hive_config.xml google-reversedClientId) Google Cloud 콘솔에서 발급받은 역순 클라이언트 ID",
                    ref authConfig.google.reversedClientId,
                    hiveConfigXmlAuthGuideLink
                );
            if (selectedPlatform == HiveConfigPlatform.android || selectedPlatform == HiveConfigPlatform.ios)
                gui.EditableText(
                    "Google Server Client Id",
                    "(hive_config.xml google-serverClientId) Google Cloud 콘솔에서 발급받은 웹 애플리케이션 클라이언트 ID",
                    ref authConfig.google.serverClientId,
                    hiveConfigXmlAuthGuideLink
                );
            if (selectedPlatform == HiveConfigPlatform.mac || selectedPlatform == HiveConfigPlatform.windows)
                gui.EditableText(
                    "Google Device Flow Client Id",
                    "(hive_config.xml google-deviceFlowClientId) Google Cloud 콘솔에서 발급받은 클라이언트 유형의 클라이언트 ID",
                    ref authConfig.google.deviceFlowClientId,
                    hiveConfigXmlAuthGuideLink
                );
            authConfig.google.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();

            // Google Play Games: android
            if (selectedPlatform == HiveConfigPlatform.android) {
                gui.HeaderText("Google Play Games");
                checkActivatedDependency(selectedPlatform, ExternalDependencyType.GooglePlayGames);
                gui.EditableText(
                    "GooglePlayGames App Id",
                    "(hive_config.xml googleplaygames-playAppId) Google Cloud 콘솔에서 발급받은 Android 유형 클라이언트 ID",
                    ref authConfig.googlePlayGames.appId,
                    hiveConfigXmlAuthGuideLink
                );
                gui.EditableText(
                    "GooglePlayGames Server Client Id",
                    "(hive_config.xml googleplaygames-serverClientId) Google Cloud 콘솔에서 발급받은 웹 애플리케이션 클라이언트 ID",
                    ref authConfig.googlePlayGames.serverClientId,
                    hiveConfigXmlAuthGuideLink
                );
                authConfig.googlePlayGames.Apply();
                gui.Space();
                changeEnableUI(true);
                gui.Separator();
                gui.Space();
            }

            // QQ: android, ios
            if (selectedPlatform == HiveConfigPlatform.android || selectedPlatform == HiveConfigPlatform.ios) {
                gui.HeaderText("QQ");
                checkActivatedDependency(selectedPlatform, ExternalDependencyType.QQ);
                gui.EditableText(
                    "QQ App Id",
                    "(hive_config.xml qq-id) QQ 서비스에 게임 앱 등록 요청을 통해 발급받은 QQ APP ID",
                    ref authConfig.qq.appId,
                    hiveConfigXmlAuthGuideLink
                );
                authConfig.qq.Apply();
                gui.Space();
                changeEnableUI(true);
                gui.Separator();
                gui.Space();
            }

            // Wechat: android, ios
            if (selectedPlatform == HiveConfigPlatform.android || selectedPlatform == HiveConfigPlatform.ios) {
                gui.HeaderText("Wechat");
                checkActivatedDependency(selectedPlatform, ExternalDependencyType.Wechat);
                gui.EditableText(
                    "Wechat App Id",
                    "(hive_config.xml wechat-id) Wechat 콘솔에 있는 게임 앱 식별자 APP ID",
                    ref authConfig.wechat.appId,
                    hiveConfigXmlAuthGuideLink
                );
                gui.EditableText(
                    "Wechat App Secret",
                    "(hive_config.xml wechat-secret) Wechat 콘솔에 있는 AppSecret",
                    ref authConfig.wechat.appSecret,
                    hiveConfigXmlAuthGuideLink
                );
                authConfig.wechat.Apply();
                gui.Space();
                changeEnableUI(true);
                gui.Separator();
                gui.Space();
            }

            // VK: android, ios
            if (selectedPlatform == HiveConfigPlatform.android || selectedPlatform == HiveConfigPlatform.ios) {
                gui.HeaderText("VK");
                checkActivatedDependency(selectedPlatform, ExternalDependencyType.VK);
                gui.EditableText(
                    "VK App Id",
                    "(hive_config.xml vk-appId) VK 서비스 페이지에서 발급받은 VK ID",
                    ref authConfig.vk.appId,
                    hiveConfigXmlAuthGuideLink
                );
                authConfig.vk.Apply();
                gui.Space();
                changeEnableUI(true);
                gui.Separator();
                gui.Space();
            }

            // Line: android, ios
            gui.HeaderText("Line");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.Line);
            gui.EditableText(
                "Line Channel Id",
                "(hive_config.xml line-channelId) Line 콘솔에서 Providers 항목 내 Basic settings에서 확인할 수 있는 Channel ID",
                ref authConfig.line.channelId,
                hiveConfigXmlAuthGuideLink
            );
            authConfig.line.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();

            // Weverse: android, ios
            if (selectedPlatform == HiveConfigPlatform.android || selectedPlatform == HiveConfigPlatform.ios) {
                gui.HeaderText("Weverse");
                checkActivatedDependency(selectedPlatform, ExternalDependencyType.Weverse);
                gui.EditableText(
                    "Weverse Client Id",
                    "(hive_config.xml weverse-clientId) Weverse 로그인을 위한 고유 식별자 Client ID",
                    ref authConfig.weverse.clientId,
                    hiveConfigXmlAuthGuideLink
                );
                authConfig.weverse.Apply();
                gui.Space();
                changeEnableUI(true);
                gui.Separator();
                gui.Space();
            }

            // Apple: android, ios
            gui.HeaderText("Apple SignInWithApple");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.AppleSignIn);
            gui.EditableText(
                "SignInWithApple Service Id",
                "(hive_config.xml signinwithapple-serviceid) Apple 개발자 센터에서 발급받은 Services ID",
                ref authConfig.apple.serviceId,
                hiveConfigXmlAuthGuideLink
            );
            authConfig.apple.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();

            // Steam: android, ios
            gui.HeaderText("Steam");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.Steam);
            gui.EditableText(
                "Steam Realm",
                "(hive_config.xml steam-realm) Steam OpenID 인증에서 realm 정보로 사용하는 게임 개발팀 소유의 도메인",
                ref authConfig.steam.realm,
                hiveConfigXmlAuthGuideLink
            );
            authConfig.steam.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();

            // X: android, ios
            gui.HeaderText("X");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.X);
            gui.EditableText(
                "X Client Id",
                "(hive_config.xml x-clientId) X 콘솔(X Developer Portal)의 OAuth 2.0 Client ID",
                ref authConfig.x.clientId,
                hiveConfigXmlAuthGuideLink
            );
            authConfig.x.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();

            // Telegram: android, ios
            gui.HeaderText("Telegram");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.X);
            gui.EditableText(
                "Telegram Bot Id",
                "(hive_config.xml telegram-botId) Telegram 로그인 서비스를 위한 botId",
                ref authConfig.telegram.botId,
                hiveConfigXmlAuthGuideLink
            );
            gui.EditableText(
                "Telegram Bot Domain",
                "(hive_config.xml telegram-botDomain) Telegram 로그인 서비스를 위한 botDomain",
                ref authConfig.telegram.botDomain,
                hiveConfigXmlAuthGuideLink
            );
            authConfig.telegram.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();

            // Xiaomi: android
            gui.HeaderText("Xiaomi");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.Xiaomi);
            gui.EditableText(
                "Xiaomi App Id",
                "(hive_config.xml xiaomi-appId) Xiaomi 로그인 서비스를 위한 appId",
                ref authConfig.xiaomi.appId,
                hiveConfigXmlAuthGuideLink
            );
            gui.EditableText(
                "Xiaomi App Key",
                "(hive_config.xml xiaomi-appKey) Xiaomi 로그인 서비스를 위한 appKey",
                ref authConfig.xiaomi.appKey,
                hiveConfigXmlAuthGuideLink
            );
            authConfig.xiaomi.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();
        }

        void showMarketConfig()
        {
            if (selectedPlatform != HiveConfigPlatform.android) {
                gui.HeaderText("No Settings");
                return;
            }

            XmlMarket marketConfig = new XmlMarket(config);

            // Lebi: android
            gui.HeaderText("Lebi");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.MarketLebi);
            gui.EditableText(
                "Wechat Payment Key",
                "(hive_config.xml wechat-paymentKey) wechat pay 기능을 사용을 위한 payment key",
                ref marketConfig.lebi.wechatPaymentKey,
                hiveConfigXmlMarketGuideLink
            );
            gui.Space();
            gui.Space();
            changeEnableUI(true);
        }

        void showAnalyticsConfig()
        {
            if (selectedPlatform != HiveConfigPlatform.android && selectedPlatform != HiveConfigPlatform.ios) {
                gui.HeaderText("No Settings");
                return;
            }

            XmlAnalytics analyticsConfig = new XmlAnalytics(config);
            
            // Adjust: android, ios
            gui.HeaderText("Adjust");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.Adjust);
            gui.EditableText(
                "appToken",
                "(hive_config.xml adjust-key) Adjust 콘솔의 게임 앱에 대한 App token",
                ref analyticsConfig.adjust.appToken,
                hiveConfigXmlAnalyticsGuideLink
            );
            gui.KeyValueInputField(
                "Add Event",
                "Adjust에 등록한 게임 앱에 대한 이벤트",
                ref analyticsConfig.adjust.eventKeys,
                ref analyticsConfig.adjust.eventValues
            );
            analyticsConfig.adjust.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();
            gui.Space();

            // Singular: android, ios
            gui.HeaderText("Singular");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.Singular);
            gui.EditableText(
                "appId",
                "(hive_config.xml singular-id) Singular 콘솔의 게임 앱에 대한 SDK Key",
                ref analyticsConfig.singular.appId,
                hiveConfigXmlAnalyticsGuideLink
            );
            gui.EditableText(
                "secret",
                "(hive_config.xml singular-key) Singular 콘솔의 게임 앱에 대한 SDK Secret",
                ref analyticsConfig.singular.secret,
                hiveConfigXmlAnalyticsGuideLink
            );
            gui.KeyValueInputField(
                "Add Event",
                "Singular에 등록한 게임 앱에 대한 이벤트",
                ref analyticsConfig.singular.eventKeys,
                ref analyticsConfig.singular.eventValues
            );
            analyticsConfig.singular.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();
            gui.Space();

            // AppsFlyer: android, ios
            gui.HeaderText("AppsFlyer");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.AppsFlyer);
            gui.EditableText(
                "key",
                "(hive_config.xml appsflyer-key) Appsflyer 콘솔에서 App Settings 페이지의 SDK authentication의 Dev key",
                ref analyticsConfig.appsflyer.key,
                hiveConfigXmlAnalyticsGuideLink
            );
            gui.EditableText(
                "Itunes Connect App Id",
                "(hive_config.xml appsflyer-itunesConnectAppId) Apple App Store Connect 콘솔에서 게임 앱의 앱 정보 페이지의 Apple ID",
                ref analyticsConfig.appsflyer.itunesConnectAppId,
                hiveConfigXmlAnalyticsGuideLink
            );
            gui.KeyValueInputField(
                "Add Event",
                "Appsfyler에 등록한 게임 앱에 대한 이벤트",
                ref analyticsConfig.appsflyer.eventKeys,
                ref analyticsConfig.appsflyer.eventValues
            );
            analyticsConfig.appsflyer.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();
            gui.Space();

            // Firebase: android, ios
            gui.HeaderText("Firebase");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.Firebase);
            gui.KeyValueInputField(
                "Add Event",
                "Firebase에 등록한 게임 앱에 대한 이벤트",
                ref analyticsConfig.firebase.eventKeys,
                ref analyticsConfig.firebase.eventValues
            );
            analyticsConfig.firebase.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();
            gui.Space();

            // Airbridge: android, ios
            gui.HeaderText("Airbridge");
            checkActivatedDependency(selectedPlatform, ExternalDependencyType.Airbridge);
            gui.EditableText(
                "key",
                "(hive_config.xml airbridge-key) Airbridge 콘솔의 앱 서비스에 고유 부여된 식별자값인 앱 SDK 토큰",
                ref analyticsConfig.airbridge.key,
                hiveConfigXmlAnalyticsGuideLink
            );
            gui.EditableText(
                "appName",
                "(hive_config.xml airbridge-appName) Airbridge 콘솔의 이름",
                ref analyticsConfig.airbridge.appName,
                hiveConfigXmlAnalyticsGuideLink
            );
            gui.EditableText(
                "secretId",
                "(hive_config.xml airbridge-secretId) Airbridge SDK 시그니처 적용을 위한 시크릿 ID",
                ref analyticsConfig.airbridge.secretId,
                hiveConfigXmlAnalyticsGuideLink
            );
            gui.EditableText(
                "secret",
                "(hive_config.xml airbridge-secret) Airbridge SDK 시그니처</a> 적용을 위한 시크릿",
                ref analyticsConfig.airbridge.secret,
                hiveConfigXmlAnalyticsGuideLink
            );
            gui.KeyValueInputField(
                "Add Event",
                "Airbridge에 등록한 게임 앱에 대한 이벤트",
                ref analyticsConfig.airbridge.eventKeys,
                ref analyticsConfig.airbridge.eventValues
            );
            analyticsConfig.airbridge.Apply();
            gui.Space();
            changeEnableUI(true);
            gui.Separator();
            gui.Space();
            gui.Space();
        }

        void showOptionalConfig()
        {
            XmlOptional optionalConfig = new XmlOptional(config);

            if (selectedPlatform == HiveConfigPlatform.android) {
                gui.ValueInputField(
                    "Unsupported UA Share Type",
                    "(hive_config.xml unsupportedUAShareType) 유저 애퀴지션(UA) 공유하기 기능 사용 시 아이콘으로 노출하지 않을 공유앱을 설정",
                    ref optionalConfig.unsupportedUaShareType,
                    hiveConfigXmlOptionalGuideLink
                );
                optionalConfig.Apply();
                gui.Space();
                gui.Separator();
                gui.Space();
            }

            if (selectedPlatform == HiveConfigPlatform.android || selectedPlatform == HiveConfigPlatform.ios) {
                gui.DropdownMenu(
                    "agreementDetermineBase", 
                    "(hive_config.xml agreementDetermineBase) 약관 동의를 받는 기준을 결정(device: 단말 기준, account: 계정 기준)", 
                    ref optionalConfig.agreementDetermineBase,
                    hiveConfigXmlOptionalGuideLink
                );
                optionalConfig.Apply();
                gui.Space();
                gui.Separator();
                gui.Space();
            }

            gui.Slider(
                "httpConnectTimeout",
                "(hive_config.xml httpConnectTimeout) Hive SDK 내부에서 사용되는 HTTP Connect Timeout 시간을 초단위로 설정 (특별한 경우가 아니면 변경 금지)",
                ref optionalConfig.httpConnectTimeout,
                0,
                60,
                hiveConfigXmlOptionalGuideLink
            );
            gui.Space();

            gui.Slider(
                "httpReadTimeout",
                "(hive_config.xml httpReadTimeout) Hive SDK 내부에서 사용되는 HTTP Read Timeout 시간을 초단위로 설정 (특별한 경우가 아니면 변경 금지)",
                ref optionalConfig.httpReadTimeout,
                0,
                60,
                hiveConfigXmlOptionalGuideLink
            );
            gui.Space();
            
            gui.Slider(
                "maxGameLogSize",
                "(hive_config.xml maxGameLogSize) 비정형 데이터 파일로 저장하는 게임 로그의 최대 저장 개수 설정 (특별한 경우가 아니면 변경 금지)",
                ref optionalConfig.maxGameLogSize,
                0,
                1000,
                hiveConfigXmlOptionalGuideLink
            );
            gui.Space();
            
            gui.EditableNumber(
                "analyticsSendLimit",
                "(hive_config.xml analyticsSendLimit) 로그 전송 주기마다 전송할 로그의 최대치",
                ref optionalConfig.analyticsSendLimit,
                hiveConfigXmlOptionalGuideLink
            );
            gui.Space();
            
            gui.EditableNumber(
                "analyticsQueueLimit",
                "(hive_config.xml analyticsQueueLimit) 쌓을 수 있는 로그의 최대치",
                ref optionalConfig.analyticsQueueLimit,
                hiveConfigXmlOptionalGuideLink
            );
            gui.Space();
            
            gui.EditableNumber(
                "analyticsSendCycle",
                "(hive_config.xml analyticsSendCycle) 로그 전송 주기",
                ref optionalConfig.analyticsSendCycle,
                hiveConfigXmlOptionalGuideLink
            );
            gui.Space();

            if (selectedPlatform == HiveConfigPlatform.ios) {
                gui.ToggleWide(
                    "saveAnalyticsLogBeforeCrash",
                    "(hive_config.xml saveAnalyticsLogBeforeCrash) 앱이 NSException 타입 에러 또는 Unix signal 타입 에러 때문에 강제 종료되기 직전 상황을 감지하여 서버에 전송하지 않고 대기중인 애널리틱스 로그를 파일로 저장할지 여부를 설정",
                    ref optionalConfig.saveAnalyticsLogBeforeCrash,
                    hiveConfigXmlOptionalGuideLink
                );
                gui.Space();
            }

            optionalConfig.Apply();
        }

        public static bool isAutoValidation()
        {
            return autoValidation;
        }
        
        static public void PrepareAndroidSetting()
        {    
            /*
             * NOTE
             * CreateAttribute 를 통해 속성 추가시 namespace prefix 'tools:' 가 정상적으로 붙지 않는 이슈 존재
             */
            Utility.InvokeMethod("HiveManifestMod", "GenerateManifest");
            Utility.InvokeMethod("HiveManifestMod", "GenerateManifest");
            // HiveConfigXML.Instance.load();
            // HiveConfigXML.Instance.commit();
            Utility.InvokeMethod("HiveMultidexResolver", "resolveMultidex");
            HiveConfigXML.Android.commit();

            /*
             if android build system was Gradle(New!) and UnityVersion after than 5.6.0p1 or 5.5.2p4, skip below copy process. except 2017.1 and after version.
             5.6.0p1
             (888274) - Android: Fixed an issue where ApplicationId was missing from AndroidManifest.xml in Gradle builds
             https://issuetracker.unity3d.com/issues/android-applicationid-is-not-being-provided-in-the-build-dot-gradle
             5.5.2p4
             (888274) - Android: Fixed an issue where ApplicationId was missing from AndroidManifest.xml in Gradle builds.
             */
            bool bGradleApplicationIdBugFixed = false;
            #if UNITY_5_5_OR_NEWER
            int version = Utility.GetUnityVersion();
            if( EditorUserBuildSettings.androidBuildSystem == AndroidBuildSystem.Gradle )
            {
                if( (version >= 5524 && version < 5600) ||
                    (version >= 5601 && version < 5700) ||
                    (version >= 2017100) ) {
                    bGradleApplicationIdBugFixed = true;
                }
            }
            else
            {
                if( !EditorPrefs.GetBool("noShowGradle",false) ) {
                    int result = EditorUtility.DisplayDialogComplex(
                    "Select Android Build System.",
                    "We recommand Gradle Build for Android Build System. Do you want change to Gradle Build?",
                    "Yes, I will change Now.",
                    "No",
                    "No, I Don't want see any more.");

                    if ( result == 0 ) {
                        EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle;
                        bGradleApplicationIdBugFixed = true;
                    } else if ( result == 2 ) {
                        EditorPrefs.SetBool("noShowGradle",true);
                    }
                }
            }
            #endif

            string sdkPath = "Assets/Hive_SDK_v4/Plugins/Android/libs/";
            string pluginPath = "Assets/Plugins/Android/";
            string SDKFile = "HIVE_SDK.aar";
            string SDKPluginFile = "HIVE_SDK_UnityPlugin.aar";
            string SDKDirectory = "HIVE_SDK";
            string SDKPluginDirectory = "HIVE_SDK_UnityPlugin";
            if( File.Exists(sdkPath+SDKFile) || File.Exists(sdkPath+SDKPluginFile) )
            {
                HiveLogger.Log("Reimport Assets/Hive_SDK_v4/Plugins");

                if( File.Exists(sdkPath+SDKFile) )
                {
                    PluginImporter hiveBundle = (PluginImporter)PluginImporter.GetAtPath(sdkPath+SDKFile);
                    hiveBundle.SetCompatibleWithAnyPlatform(false);
                    hiveBundle.SetCompatibleWithEditor(false);
                    hiveBundle.SetCompatibleWithPlatform(BuildTarget.Android, bGradleApplicationIdBugFixed);
                    hiveBundle.SaveAndReimport();
                    if( bGradleApplicationIdBugFixed ) {
                        FileUtil.DeleteFileOrDirectory(pluginPath+SDKDirectory);
                    } else if( !File.Exists(pluginPath+SDKFile) )
                        FileUtil.CopyFileOrDirectory(sdkPath+SDKFile,pluginPath+SDKFile);
                }
                if( File.Exists(sdkPath+SDKPluginFile) )
                {
                    PluginImporter hiveBundle = (PluginImporter)PluginImporter.GetAtPath(sdkPath+SDKPluginFile);
                    hiveBundle.SetCompatibleWithAnyPlatform(false);
                    hiveBundle.SetCompatibleWithEditor(false);
                    hiveBundle.SetCompatibleWithPlatform(BuildTarget.Android, bGradleApplicationIdBugFixed);
                    hiveBundle.SaveAndReimport();
                    if( bGradleApplicationIdBugFixed ) {
                        FileUtil.DeleteFileOrDirectory(pluginPath+SDKPluginDirectory);
                    } else if( !File.Exists(pluginPath+SDKPluginFile) )
                        FileUtil.CopyFileOrDirectory(sdkPath+SDKPluginFile,pluginPath+SDKPluginFile);
                }
            }

            //Just once fire!
            HiveDependencies.RegisterAndroidDependencies();
            Google.VersionHandler.UpdateNow();
            GooglePlayServices.PlayServicesResolver.MenuForceResolve();

            if(Directory.Exists(pluginPath+SDKDirectory))
            {
                PluginImporter hiveBundle = (PluginImporter)PluginImporter.GetAtPath(pluginPath+SDKDirectory);
                hiveBundle.SetCompatibleWithAnyPlatform(false);
                hiveBundle.SetCompatibleWithEditor(false);
                hiveBundle.SetCompatibleWithPlatform(BuildTarget.Android,true);
                hiveBundle.SaveAndReimport();
            }

            if(Directory.Exists(pluginPath+SDKPluginDirectory))
            {
                PluginImporter hiveBundle = (PluginImporter)PluginImporter.GetAtPath(pluginPath+SDKPluginDirectory);
                hiveBundle.SetCompatibleWithAnyPlatform(false);
                hiveBundle.SetCompatibleWithEditor(false);
                hiveBundle.SetCompatibleWithPlatform(BuildTarget.Android,true);
                hiveBundle.SaveAndReimport();
            }
        }

        // 미사용중인 Dependency 여부를 확인하여 UI 비활성
        private void checkActivatedDependency(HiveConfigPlatform platform, ExternalDependencyType type) {
            if(platform == HiveConfigPlatform.mac || platform == HiveConfigPlatform.windows) {
                return;
            }

            ExternalDependencyDictionaryManager.SupportOSType osType = ExternalDependencyDictionaryManager.SupportOSType.Android;
            if(platform == HiveConfigPlatform.ios) {
                osType = ExternalDependencyDictionaryManager.SupportOSType.iOS;
            }

            if(!ExternalDependencyDictionaryManager.isUseDependency(osType, type)) {
                gui.TintedLabel("If you need, activate in Hive Dependencies.", Color.red);
                changeEnableUI(false);
            }
        }

        // 해당 메서드 이하에 모든 UI를 활성 또는 비활성
        private void changeEnableUI(bool value) {
            GUI.enabled = value;
        }

        public class Tracker
        {
            public string name = "";
            public List<string> eventName = new List<string>();
            public List<string> eventValue = new List<string>();

            public void AddEvent(string name, string value)
            {
                eventName.Add(name);
                eventValue.Add(value);
            }
            public void RemoveEventByName(string name)
            {
                int index = eventName.BinarySearch(name);
                eventName.RemoveAt(index);
                eventValue.RemoveAt(index);
            }
        }

        public class AdjustTracker : Tracker {
            public string id = "";
            public string key = "";
        }

        public class SingularTracker : Tracker {
            public string id = "";
            public string key = "";
        }

        public class AppsFlyerTracker : Tracker{
            public string id = "";
            public string key = "";
            public string itunesConnectAppId = "";

        }

        public class FirebaseTracker : Tracker{

        }

        public class AirbridgeTracker : Tracker
        {
            public string id = "";
            public string key = "";
            public string appName = "";
            public string secretId = "";
            public string secret = "";
        }

        private string[] GetEnumDescriptions<T>() where T : Enum
        {
            var enumValues = Enum.GetValues(typeof(T));
            string[] descriptions = new string[enumValues.Length];

            for (int i = 0; i < enumValues.Length; i++)
            {
                var enumValue = (T)enumValues.GetValue(i);
                descriptions[i] = Utility.GetEnumDescription(enumValue); // 각 Enum의 Description을 가져옴
            }

            return descriptions;
        }

        private GUIStyle getEditorTitleStyle()
        {
            GUIStyle titleStyle = new GUIStyle();
            titleStyle.fontSize = 30;
            titleStyle.normal.textColor = Color.white;
            return titleStyle;
        }

    }

}