#if UNITY_STANDALONE || UNITY_EDITOR
using System;
using Seayoo.ComboSDK.Windows;
using System.Collections.Generic;
using ThinkingData.Analytics;
using Sentry;
using Seayoo.ComboSDK.Windows.Account;

namespace Combo.Platform
{
    public class NativeWindows
    {
        public static void Setup(SetupOptions opts, Action<Result<SetupResult>> callback)
        {
            ComboSDKWindows.Instance.Setup(
                new ComboSDKSetupOptions
                {
                    gameId = opts.gameId,
                    publishableKey = opts.publishableKey,
                    endpoint = opts.endpoint,
                    extra = opts.extra
                }, result =>
                {
                    if (result.IsSuccess())
                    {
                        var r = result.Get();
                        callback.Invoke(new Result<SetupResult>.Success(
                            new SetupResult()));
                    }
                    else
                    {
                        var e = result.GetError();
                        callback.Invoke(new Result<SetupResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                    }
                }
            );
        }

        public static void Login(Action<Result<LoginResult>> callback)
        {
            ComboSDKWindows.Instance.Login(result =>
            {
                if (result.IsSuccess())
                {
                    var r = result.Get();

                    if (result != null)
                    {
                        TDAnalytics.Login(r.loginInfo.comboId);
                        SentrySdk.ConfigureScope(scope =>
                        {
                            scope.User.Id = r.loginInfo.comboId;
                        });
                    }

                    callback.Invoke(new Result<LoginResult>.Success(
                        new LoginResult
                        {
                            loginInfo = new LoginInfo
                            {
                                comboId = r.loginInfo.comboId,
                                identityToken = r.loginInfo.identityToken
                            }
                        }));
                }
                else
                {
                    var e = result.GetError();
                    callback.Invoke(new Result<LoginResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                }
            });
        }

        public static void Logout(Action<Result<LogoutResult>> callback)
        {
            ComboSDKWindows.Instance.Logout(result =>
            {
                if (result.IsSuccess())
                {
                    TDAnalytics.Logout();
                    var r = result.Get();
                    callback.Invoke(new Result<LogoutResult>.Success(
                        new LogoutResult
                        {
                            comboId = r.comboId,
                        }));
                }
                else
                {
                    var e = result.GetError();
                    callback.Invoke(new Result<LogoutResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                }
            });
        }

        public static void OnKickOut(Action<Result<KickOutResult>> callback)
        {
            ComboSDKWindows.Instance.KickOut(result => {
                if (result.IsSuccess())
                {
                    var r = result.Get();
                    callback.Invoke(new Result<KickOutResult>.Success(
                        new KickOutResult
                        {
                            shouldExit = r.shouldExit,
                    }));
                }
                else
                {
                    var e = result.GetError();
                    callback.Invoke(new Result<KickOutResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                }
            });
        }

        public static LoginInfo GetLoginInfo()
        {
            var info = ComboSDKWindows.Instance.GetLoginInfo();
            if (info == null)
                return null;

            return new LoginInfo
            {
                comboId = info.comboId,
                identityToken = info.identityToken,
                idp = info.idp
            };
        }

        public static string GetVersion()
        {
            return ComboSDKWindows.Instance.GetVersion();
        }

        public static string GetDistro()
        {
            return ComboSDKWindows.Instance.GetDistro();
        }

        public static Dictionary<string, string> GetParameters()
        {
            return ComboSDKWindows.Instance.GetParameters();
        }

        public static string GetDeviceId()
        {
            return ComboSDKWindows.Instance.GetDeviceId();
        }

        public static void Purchase(PurchaseOptions options, Action<Result<PurchaseResult>> callback)
        {
            ComboSDKWindows.Instance.Purchase(options.orderToken, result =>{
                if (result.IsSuccess())
                {
                    var r = result.Get();
                    callback.Invoke(new Result<PurchaseResult>.Success(
                        new PurchaseResult
                        {
                            orderId = r.orderId,
                        }));
                }
                else
                {
                    var e = result.GetError();
                    callback.Invoke(new Result<PurchaseResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                }
            });
        }

        public static string GetUserId()
        {
            return SeayooAccountManager.GetInstance().GetUser().userId;
        }

        public static bool IsFeatureAvailable(Feature feature)
        {
            return ComboSDKWindows.Instance.IsFeatureAvailable((_Combo.Feature)feature);
        }

        public static void GetDownloadUrl(Action<Result<DownloadUrlResult>> callback)
        {
            ComboSDKWindows.Instance.GetDownloadUrl(result =>{
                if (result.IsSuccess())
                {
                    var r = result.Get();
                    callback.Invoke(new Result<DownloadUrlResult>.Success(
                        new DownloadUrlResult
                        {
                            downloadUrl = r.downloadUrl,
                        }));
                }
                else
                {
                    var e = result.GetError();
                    callback.Invoke(new Result<DownloadUrlResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                }
            });
        }

        public static LanguagePreference GetLanguagePreference()
        {
            return (LanguagePreference)ComboSDKWindows.Instance.GetLanguagePreference();
        }

        public static void SetLanguagePreference(LanguagePreference languagePreference)
        {
            ComboSDKWindows.Instance.SetLanguagePreference((_Combo.LanguagePreference)languagePreference);
        }

        public static string GetLanguageCode()
        {
            return ComboSDKWindows.Instance.GetLanguageCode();
        }

#if UNITY_STANDALONE
        public static void ContactSupport()
        {
            ComboSDKWindows.Instance.ContactSupport();
        }

        public static void ManageAccount()
        {
            SeayooAccountManager.GetInstance().LoginWithToken(WebViewLandingPage.ManageAccount);
        }

        public static void ChangePassword()
        {
            SeayooAccountManager.GetInstance().LoginWithToken(WebViewLandingPage.ChangePassword);
        }

        public static void DeleteAccount()
        {
            SeayooAccountManager.GetInstance().LoginWithToken(WebViewLandingPage.DeleteAccount);
        }

        public static void OpenGameUrl(GameUrl gameUrl)
        {
            ComboSDKWindows.Instance.OpenGameUrl((_Combo.GameUrl)gameUrl);
        }

        public static void OpenShortLink(string shortLink, Dictionary<string, string> gameData, Action<Result<OpenShortLinkResult>> callback)
        {
            ComboSDKWindows.Instance.OpenShortLink(shortLink, gameData, result =>{
                if (result.IsSuccess())
                {
                    var r = result.Get();
                    callback.Invoke(new Result<OpenShortLinkResult>.Success(new OpenShortLinkResult()));
                }
                else
                {
                    var e = result.GetError();
                    callback.Invoke(new Result<OpenShortLinkResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                }
            });
        }

        public static void CheckAnnouncements(CheckAnnouncementsOptions opts, Action<Result<CheckAnnouncementsResult>> callback)
        {
            ComboSDKWindows.Instance.CheckAnnouncements(
                new ComboSDKCheckAnnouncementsOptions
                {
                    Profile = opts.Profile,
                    Level = opts.Level,
                }, result =>{
                    if (result.IsSuccess())
                    {
                        var r = result.Get();
                        callback.Invoke(new Result<CheckAnnouncementsResult>.Success(new CheckAnnouncementsResult(){
                            newAnnouncementsAvailable = result.value.NewAnnouncementsAvailable
                        }));
                    }
                    else
                    {
                        var e = result.GetError();
                        callback.Invoke(new Result<CheckAnnouncementsResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                    }
                }
            );
        }

        public static void OpenAnnouncements(OpenAnnouncementsOptions opts, Action<Result<OpenAnnouncementsResult>> callback)
        {
            ComboSDKWindows.Instance.OpenAnnouncements(new ComboSDKOpenAnnouncementsOptions()
            {
                Profile = opts.Profile,
                Level = opts.Level,
                Width = opts.Width,
                Height = opts.Height
            }, result =>{
                if (result.IsSuccess())
                {
                    var r = result.Get();
                    callback.Invoke(new Result<OpenAnnouncementsResult>.Success(new OpenAnnouncementsResult()));
                }
                else
                {
                    var e = result.GetError();
                    callback.Invoke(new Result<OpenAnnouncementsResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                }
            });
        }

        public static void Complain(ComplainOptions opts, Action<Result<ComplainResult>> callback)
        {
            ComboSDKWindows.Instance.Complain(new Seayoo.ComboSDK.Windows.ComplainOptions()
            {
                TargetType = opts.TargetType,
                TargetId = opts.TargetId,
                TargetName = opts.TargetName,
                Category = opts.Category,
                ServerId = opts.ServerId,
                RoleId = opts.RoleId,
                RoleName = opts.RoleName,
                Context = opts.Context,
                Width = opts.Width,
                Height = opts.Height
            }, result =>{
                if (result.IsSuccess())
                {
                    var r = result.Get();
                    callback.Invoke(new Result<ComplainResult>.Success(new ComplainResult()));
                }
                else
                {
                    var e = result.GetError();
                    callback.Invoke(new Result<ComplainResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                }
            });
        }

        public static void RedeemGiftCode(RedeemGiftCodeOptions opts, Action<Result<RedeemGiftCodeResult>> callback)
        {
            ComboSDKWindows.Instance.RedeemGiftCode(new Seayoo.ComboSDK.Windows.RedeemGiftCodeOptions()
            {
                GitfCode = opts.GiftCode,
                ServerId = opts.ServerId,
                RoleId = opts.RoleId,
                RoleName = opts.RoleName,
                Width = opts.Width,
                Height = opts.Height
            }, result =>{
                if (result.IsSuccess())
                {
                    var r = result.Get();
                    callback.Invoke(new Result<RedeemGiftCodeResult>.Success(new RedeemGiftCodeResult()));
                }
                else
                {
                    var e = result.GetError();
                    callback.Invoke(new Result<RedeemGiftCodeResult>.Fail(new Error(e.Error, e.Message, e.DetailMessage)));
                }
            });
        }
#endif

    }
}

#endif