using System;
using System.Collections.Generic;

#if UNITY_WEBGL
using Seayoo.LitJson;
#else
using Newtonsoft.Json;
#endif

namespace Combo.Platform
{
    internal static class Native
    {
        internal static void Setup(SetupOptions opts, Action<Result<SetupResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.Setup(opts, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.Setup(opts, callback);
#elif UNITY_STANDALONE || UNITY_EDITOR
            NativeWindows.Setup(opts, callback);
#elif UNITY_WEBGL
            NativeWebGL.Setup(opts, callback);
#elif UNITY_OPENHARMONY
            NativeOpenHarmony.Setup(opts, callback);
#endif
        }

        internal static void Login(Action<Result<LoginResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.Login(callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.Login(callback);
#elif UNITY_STANDALONE || UNITY_EDITOR
            NativeWindows.Login(callback);
#elif UNITY_WEBGL
            NativeWebGL.Login(callback);
#elif UNITY_OPENHARMONY
            NativeOpenHarmony.Login(callback);
#endif
        }

        internal static LoginInfo GetLoginInfo()
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            return NativeAndroid.GetLoginInfo();
#elif UNITY_IOS && !UNITY_EDITOR
            return NativeIOS.GetLoginInfo();
#elif UNITY_STANDALONE || UNITY_EDITOR
            return NativeWindows.GetLoginInfo();
#elif UNITY_WEBGL
            return NativeWebGL.GetLoginInfo();
#elif UNITY_OPENHARMONY
            return NativeOpenHarmony.GetLoginInfo();
#endif
        }

        internal static void Logout(Action<Result<LogoutResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.Logout(callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.Logout(callback);
#elif UNITY_STANDALONE || UNITY_EDITOR
            NativeWindows.Logout(callback);
#elif UNITY_OPENHARMONY
            NativeOpenHarmony.Logout(callback);
#endif
        }

        internal static void Purchase(PurchaseOptions opts, Action<Result<PurchaseResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.Purchase(opts, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.Purchase(opts, callback);
#elif UNITY_STANDALONE || UNITY_EDITOR
            NativeWindows.Purchase(opts, callback);
#elif UNITY_WEBGL
            NativeWebGL.Purchase(opts, callback);
#elif UNITY_OPENHARMONY
            NativeOpenHarmony.Purchase(opts, callback);
#endif
        }

        internal static void PreloadAd(PreloadAdOptions opts, Action<Result<PreloadAdResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.PreloadAd(opts, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.PreloadAd(opts, callback);
#elif UNITY_STANDALONE || UNITY_EDITOR
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.PreloadAd(opts, callback);
#elif UNITY_WEBGL && !UNITY_EDITOR
            NativeWebGL.PreloadAd(opts, callback);
#endif
        }

        internal static void ShowAd(ShowAdOptions opts, Action<Result<ShowAdResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.ShowAd(opts, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.ShowAd(opts, callback);
#elif UNITY_STANDALONE || UNITY_EDITOR
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.ShowAd(opts, callback);
#elif UNITY_WEBGL && !UNITY_EDITOR
            NativeWebGL.ShowAd(opts, callback);
#endif
        }

        internal static void Share(ShareOptions opts, Action<Result<ShareResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.Share(opts, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.Share(opts, callback);
#elif UNITY_STANDALONE || UNITY_EDITOR
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.Share(opts, callback);
#endif
        }

        internal static void ReportCreateRole(RoleInfo roleInfo) {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.ReportCreateRole(roleInfo);
#elif UNITY_IOS && !UNITY_EDITOR
#elif UNITY_STANDALONE || UNITY_EDITOR
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.ReportCreateRole(roleInfo);
#elif UNITY_WEBGL && !UNITY_EDITOR
            NativeWebGL.ReportCreateRole(roleInfo);
#endif
        }

        internal static void ReportEnterGame(RoleInfo roleInfo) {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.ReportEnterGame(roleInfo);
#elif UNITY_IOS && !UNITY_EDITOR
#elif UNITY_STANDALONE || UNITY_EDITOR
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.ReportEnterGame(roleInfo);
#endif
        }

#region
        internal static void OnKickOut(Action<Result<KickOutResult>> callback) {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.OnKickOut(callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.OnKickOut(callback);
#elif UNITY_STANDALONE || UNITY_EDITOR
            NativeWindows.OnKickOut(callback);
#elif UNITY_OPENHARMONY
            NativeOpenHarmony.OnKickOut(callback);
#endif  
        }

        internal static bool IsFeatureAvailable(Feature feature) {
            // HTTPDNS 作为 Combo Unity 包内的核心基础能力，经 HttpDns 桥接层直接查询可用性，
            // 不走 native combo 核心的 Feature 分发（native 核心不感知 HTTPDNS）。
            if (feature == Feature.HTTPDNS)
                return HttpDns.IsAvailable();
#if UNITY_ANDROID && !UNITY_EDITOR
            return NativeAndroid.IsFeatureAvailable(feature);
#elif UNITY_IOS && !UNITY_EDITOR
            return NativeIOS.IsFeatureAvailable(feature);
#elif UNITY_STANDALONE || UNITY_EDITOR
            return NativeWindows.IsFeatureAvailable(feature);
#elif UNITY_WEBGL && !UNITY_EDITOR
            return NativeWebGL.IsFeatureAvailable(feature);
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            return NativeOpenHarmony.IsFeatureAvailable(feature);
#endif  
        }

        internal static void UpdateGame(UpdateGameOptions opts, Action<Result<UpdateGameResult>> callback) {
#if UNITY_ANDROID
            NativeAndroid.UpdateGame(new UpdateGameOptions(), callback);
#endif  
        }

        internal static ShareTarget[] GetAvailableShareTargets() {
#if UNITY_ANDROID && !UNITY_EDITOR
            return NativeAndroid.GetAvailableShareTargets();
#elif UNITY_IOS && !UNITY_EDITOR
            return NativeIOS.GetAvailableShareTargets();
#elif UNITY_STANDALONE || UNITY_EDITOR
            return new ShareTarget[]{ };
#elif UNITY_WEBGL && !UNITY_EDITOR
            return new ShareTarget[]{ };
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            return NativeOpenHarmony.GetAvailableShareTargets();
#endif
        }

        internal static string GetVariant() {
#if UNITY_ANDROID
            return NativeAndroid.GetVariant();
#endif 
            return null;
        }

        internal static string GetSubvariant() {
#if UNITY_ANDROID
            return NativeAndroid.GetSubvariant();
#endif 
            return null;
        }

        internal static void GetDownloadUrl(Action<Result<DownloadUrlResult>> callback) {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.GetDownloadUrl(callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.GetDownloadUrl(callback);
#elif UNITY_STANDALONE || UNITY_EDITOR
            NativeWindows.GetDownloadUrl(callback);
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.GetDownloadUrl(callback);
#endif 
        }

        internal static void Quit(Action<Result<QuitResult>> callback) {
#if UNITY_ANDROID
            NativeAndroid.Quit(callback);
#endif 
        }
#endregion

        internal static void KeepRenderingOnPause() {
#if UNITY_ANDROID
            NativeAndroid.KeepRenderingOnPause();
#endif 
        }

        internal static string GetGameId() {
            return Configuration.Instance.GameId;
        }

        internal static string GetDistro()
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            return NativeAndroid.GetDistro();
#elif UNITY_IOS && !UNITY_EDITOR
            return NativeIOS.GetDistro();
#elif UNITY_STANDALONE || UNITY_EDITOR
            return NativeWindows.GetDistro();
#elif UNITY_WEBGL && !UNITY_EDITOR
            return NativeWebGL.GetDistro();
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            return NativeOpenHarmony.GetDistro();
#endif
        }

        internal static string GetVersion()
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            return NativeAndroid.GetVersion();
#elif UNITY_IOS && !UNITY_EDITOR
            return NativeIOS.GetVersion();
#elif UNITY_STANDALONE || UNITY_EDITOR
            return NativeWindows.GetVersion();
#elif UNITY_WEBGL && !UNITY_EDITOR
            return NativeWebGL.GetVersion();
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            return NativeOpenHarmony.GetVersion();
#endif
        }

        internal static T GetParameters<T>()
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
#if UNITY_ANDROID && !UNITY_EDITOR
            parameters = NativeAndroid.GetParameters();
#elif UNITY_IOS && !UNITY_EDITOR
            parameters = NativeIOS.GetParameters();
#elif UNITY_STANDALONE || UNITY_EDITOR
            parameters = NativeWindows.GetParameters();
#elif UNITY_WEBGL && !UNITY_EDITOR
            parameters = NativeWebGL.GetParameters();
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            parameters = NativeOpenHarmony.GetParameters();
#endif

#if UNITY_WEBGL
            // 使用 LitJson
            string json = JsonMapper.ToJson(parameters);
            return JsonMapper.ToObject<T>(json);
#else
            // 使用 Newtonsoft.Json
            string json = JsonConvert.SerializeObject(parameters);
            return JsonConvert.DeserializeObject<T>(json);
#endif
        }

        internal static string GetDeviceId() {
#if UNITY_ANDROID && !UNITY_EDITOR
            return NativeAndroid.GetDeviceId();
#elif UNITY_IOS && !UNITY_EDITOR
            return NativeIOS.GetDeviceId();
#elif UNITY_STANDALONE || UNITY_EDITOR
            return NativeWindows.GetDeviceId();
#elif UNITY_WEBGL && !UNITY_EDITOR
            return NativeWebGL.GetDeviceId();
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            return NativeOpenHarmony.GetDeviceId();
#endif
        }

        internal static void OpenAppSettings() {
#if UNITY_ANDROID
            NativeAndroid.OpenAppSettings();
#elif UNITY_IOS
            NativeIOS.OpenAppSettings();
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.OpenAppSettings();
#endif 
        }

        internal static string UserId
        {
            get
            {
#if UNITY_ANDROID && !UNITY_EDITOR
                return NativeAndroid.GetUserId();
#elif UNITY_IOS && !UNITY_EDITOR
                return NativeIOS.GetUserId();
#elif UNITY_STANDALONE || UNITY_EDITOR
                return NativeWindows.GetUserId();
#elif UNITY_WEBGL && !UNITY_EDITOR
                return NativeWebGL.GetUserId();
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            return NativeOpenHarmony.GetUserId();
#endif

            }
        }

        internal static void ManageAccount()
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.ManageAccount();
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.ManageAccount();
#elif UNITY_STANDALONE
            NativeWindows.ManageAccount();
#elif UNITY_OPENHARMONY
            NativeOpenHarmony.ManageAccount();
#endif
        }

        internal static void ChangePassword() 
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.ChangePassword();
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.ChangePassword();
#elif UNITY_STANDALONE
            NativeWindows.ChangePassword();
#elif UNITY_OPENHARMONY
            NativeOpenHarmony.ChangePassword();
#endif                             
        }

        internal static void DeleteAccount() 
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.DeleteAccount();
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.DeleteAccount();
#elif UNITY_STANDALONE
            NativeWindows.DeleteAccount();
#elif UNITY_OPENHARMONY
            NativeOpenHarmony.DeleteAccount();
#endif                             
        }

        internal static void ContactSupport() 
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.ContactSupport();
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.ContactSupport();
#elif UNITY_STANDALONE
            NativeWindows.ContactSupport();
#elif UNITY_WEBGL && !UNITY_EDITOR
            NativeWebGL.ContactSupport();
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.ContactSupport();
#endif                             
        }

        internal static void OpenGameUrl(GameUrl url)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.OpenGameUrl(url);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.OpenGameUrl(url);
#elif UNITY_STANDALONE
            NativeWindows.OpenGameUrl(url);
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.OpenGameUrl(url);
#endif                  
        }

        internal static void OpenShortLink(string shortLink, Dictionary<string, string> gameData, Action<Result<OpenShortLinkResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.OpenShortLink(shortLink, gameData, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.OpenShortLink(shortLink, gameData, callback);
#elif UNITY_STANDALONE
            NativeWindows.OpenShortLink(shortLink, gameData, callback);
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.OpenShortLink(shortLink, gameData, callback);
#elif UNITY_WEBGL && !UNITY_EDITOR
            NativeWebGL.OpenShortLink(shortLink, gameData, callback);
#endif
        }

        // 平台分发：按当前运行平台路由到对应原生实现
        internal static void GetAnnouncements(GetAnnouncementsOptions opts, Action<Result<GetAnnouncementsResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.GetAnnouncements(opts, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.GetAnnouncements(opts, callback);
#elif UNITY_STANDALONE
            NativeWindows.GetAnnouncements(opts, callback);
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.GetAnnouncements(opts, callback);
#elif UNITY_WEBGL && !UNITY_EDITOR
            NativeWebGL.GetAnnouncements(opts, callback);
#endif
        }

        internal static void CheckAnnouncements(CheckAnnouncementsOptions opts, Action<Result<CheckAnnouncementsResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.CheckAnnouncements(opts, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.CheckAnnouncements(opts, callback);
#elif UNITY_STANDALONE
            NativeWindows.CheckAnnouncements(opts, callback);
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.CheckAnnouncements(opts, callback);
#elif UNITY_WEBGL && !UNITY_EDITOR
            NativeWebGL.CheckAnnouncements(opts, callback);
#endif
        }

        internal static void OpenAnnouncements(OpenAnnouncementsOptions opts, Action<Result<OpenAnnouncementsResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.OpenAnnouncements(opts, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.OpenAnnouncements(opts, callback);
#elif UNITY_STANDALONE
            NativeWindows.OpenAnnouncements(opts, callback);
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.OpenAnnouncements(opts, callback);
#endif
        }

        internal static void Complain(ComplainOptions opts, Action<Result<ComplainResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.Complain(opts, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.Complain(opts, callback);
#elif UNITY_STANDALONE
            NativeWindows.Complain(opts, callback);
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.Complain(opts, callback);
#elif UNITY_WEBGL && !UNITY_EDITOR
            NativeWebGL.Complain(opts, callback);
#endif
        }

        internal static void PromoPseudoPurchase(PromoPseudoPurchaseOptions opts)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.PromoPseudoPurchase(opts);
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.PromoPseudoPurchase(opts);
#endif
        }

        internal static LanguagePreference LanguagePreference
        {
            get
            {
#if UNITY_ANDROID && !UNITY_EDITOR
                return NativeAndroid.GetLanguagePreference();
#elif UNITY_IOS && !UNITY_EDITOR
                return NativeIOS.GetLanguagePreference();
#elif UNITY_STANDALONE || UNITY_EDITOR
                return NativeWindows.GetLanguagePreference();
#elif UNITY_WEBGL && !UNITY_EDITOR
                return LanguagePreference.ChineseSimplified;
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
                return NativeOpenHarmony.GetLanguagePreference();
#endif
            }

            set
            {
#if UNITY_ANDROID && !UNITY_EDITOR
                NativeAndroid.SetLanguagePreference(value);
#elif UNITY_IOS && !UNITY_EDITOR
                NativeIOS.SetLanguagePreference(value);
#elif UNITY_STANDALONE || UNITY_EDITOR
                NativeWindows.SetLanguagePreference(value);
#endif
            }
        }

        internal static string LanguageCode
        {
            get
            {
#if UNITY_ANDROID && !UNITY_EDITOR
                return NativeAndroid.GetLanguageCode();
#elif UNITY_IOS && !UNITY_EDITOR
                return NativeIOS.GetLanguageCode();
#elif UNITY_STANDALONE || UNITY_EDITOR
                return NativeWindows.GetLanguageCode();
#elif UNITY_WEBGL && !UNITY_EDITOR
                return "zh-cn";
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
                return NativeOpenHarmony.GetLanguageCode();
#endif
            } 
        }

        internal static bool ResetGuest()
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            return NativeAndroid.ResetGuest();
#elif UNITY_IOS && !UNITY_EDITOR
            return NativeIOS.ResetGuest();
#elif UNITY_STANDALONE || UNITY_EDITOR
            return false;
#elif UNITY_WEBGL && !UNITY_EDITOR
            return false;
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            return false;
#endif
        }

        internal static void RedeemGiftCode(RedeemGiftCodeOptions opts, Action<Result<RedeemGiftCodeResult>> callback)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.RedeemGiftCode(opts, callback);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.RedeemGiftCode(opts, callback);
#elif UNITY_STANDALONE
            NativeWindows.RedeemGiftCode(opts, callback);
#elif UNITY_OPENHARMONY && !UNITY_EDITOR
            NativeOpenHarmony.RedeemGiftCode(opts, callback);
#elif UNITY_WEBGL && !UNITY_EDITOR
            NativeWebGL.RedeemGiftCode(opts, callback);
#endif
        }
        
        internal static void OnDeepLinkActivated(Action<string> callback)
        {
#if UNITY_OPENHARMONY
            NativeOpenHarmony.RegisterDeepLinkCallback(callback);
#endif
        }

        internal static void ReportDouyinCustomEvent(string eventName, Dictionary<string, string> eventParams)
        {
#if UNITY_ANDROID && !UNITY_EDITOR
            NativeAndroid.ReportDouyinCustomEvent(eventName, eventParams);
#elif UNITY_IOS && !UNITY_EDITOR
            NativeIOS.ReportDouyinCustomEvent(eventName, eventParams);
#endif
        }
    }
}
