using System;
using System.Collections.Generic;
using Combo.Platform;

namespace Combo
{
    public static class ComboSDK
    {
        /// <summary>
        /// 执行登录操作
        /// </summary>
        /// <param name="callback">登录操作完成后的回调，用于接收登录的结果</param>
        /// <remarks>
        /// 如果登录失败，建议对相应的错误进行处理，例如给出错误提示，或者重新尝试登录
        /// </remarks>
        public static void Login(Action<Result<LoginResult>> callback) => Native.Login(callback);

        /// <summary>
        /// 获取用户的登录信息
        /// </summary>
        /// <remarks>
        /// 请确保在登录成功后再调用此方法, 否则返回 null
        /// </remarks>
        public static LoginInfo GetLoginInfo() => Native.GetLoginInfo();

        /// <summary>
        /// 执行登出操作
        /// </summary>
        /// <param name="callback">登出操作完成后的回调，用于接收登出的结果</param>
        /// <remarks>
        /// 如果登出失败，建议对相应的错误进行处理，例如给出错误提示，或者重新尝试登出
        /// </remarks>
        public static void Logout(Action<Result<LogoutResult>> callback) => Native.Logout(callback);

        /// <summary>
        /// 注册用户被踢出的回调
        /// </summary>
        /// <param name="callback">当用户被踢出时触发的回调</param>
        /// <remarks>
        /// <para> - 建议尽早注册 OnKickOut 的回调，这样可以保证在任何必要的情况下，都能够及时接收并处理强制下线通知</para>
        /// </remarks>
        public static void OnKickOut(Action<Result<KickOutResult>> callback) => Native.OnKickOut(callback);
        /// <summary>
        /// 注册鸿蒙平台 Deep Linking（深度链接）回调
        /// </summary>
        /// <param name="callback">当应用接收到 Deep Link 时触发的回调，参数为完整的链接 URL</param>
        /// <remarks>
        /// <para> - 建议尽早注册 OnDeepLinkActivated 的回调，这样可以确保应用在启动或运行过程中，能够及时接收并处理深度链接</para>
        /// </remarks>
        public static void OnDeepLinkActivated(Action<string> callback) => Native.OnDeepLinkActivated(callback);

        /// <summary>
        /// 执行购买操作。
        /// </summary>
        /// <param name="opts">购买选项</param>
        /// <param name="callback">完成购买操作后的回调方法，用于接收购买的结果</param>
        public static void Purchase(
            PurchaseOptions opts,
            Action<Result<PurchaseResult>> callback
        ) => Native.Purchase(opts, callback);

        /// <summary>
        /// 预加载广告
        /// </summary>
        /// <param name="opts">预加载广告的选项。</param>
        /// <param name="callback">预加载广告完成后的回调，用于接收预加载的结果</param>
        /// <remarks>
        /// <para> - PreloadAd 方法用于预加载广告，只提前加载广告，但不会显示广告。显示广告需要调用 showAd 接口</para>
        /// <para> - 此接口需要在登录成功后才能调用，并推荐在游戏运行时的空闲时机调用</para>
        /// </remarks>
        public static void PreloadAd(
            PreloadAdOptions opts,
            Action<Result<PreloadAdResult>> callback
        ) => Native.PreloadAd(opts, callback);

        /// <summary>
        /// 显示广告
        /// </summary>
        /// <param name="opts">显示广告的选项</param>
        /// <param name="callback">显示广告完成后的回调，用于接收显示广告的结果</param>
        /// <remarks>
        /// <para> - ShowAd 接口可以独立使用，不依赖于 PreloadAd，可以直接调用此 API 来显示广告。但为了优化用户体验，推荐先调用 PreloadAd 接口提前加载广告</para>
        /// <para> - 此接口需要在登录成功后才能调用</para>
        /// <para> - 需要将 ShowAdResult 中的 token 参数传给游戏服务端，游戏服务端对 token 进行验证，验证通过后则发放激励奖励</para>
        /// </remarks>
        public static void ShowAd(ShowAdOptions opts, Action<Result<ShowAdResult>> callback) =>
            Native.ShowAd(opts, callback);
        
        /// <summary>
        /// 社交分享
        /// </summary>
        /// <param name="opts">目标分享方式的选项</param>
        /// <param name="callback">分享操作完成后的回调</param>
        public static void Share(ShareOptions opts, Action<Result<ShareResult>> callback) =>
            Native.Share(opts, callback);

        /// <summary>
        /// 获取可用的分享方式
        /// </summary>
        /// <returns>
        /// 返回一个ShareTarget数组，代表了当前可用的分享方式
        /// </returns>
        public static ShareTarget[] GetAvailableShareTargets() => Native.GetAvailableShareTargets();

        /// <summary>
        /// 上报创建角色信息
        /// </summary>
        /// <remarks>
        /// 需要在用户创建角色成功时调用
        /// </remarks>
        /// <param name="roleInfo">用户角色信息.</param>
        public static void ReportCreateRole(RoleInfo roleInfo) => Native.ReportCreateRole(roleInfo);

        /// <summary>
        /// 上报进入游戏
        /// </summary>
        /// <remarks>
        /// 需要在用户登录并选择角色后调用，配合一次登录只能调用一次，不能多次调用
        /// </remarks>
        /// <param name="roleInfo">用户角色信息.</param>
        public static void ReportEnterGame(RoleInfo roleInfo) => Native.ReportEnterGame(roleInfo);

        /// <summary>
        /// 由世游侧为游戏分配，用于标识游戏的业务代号
        /// </summary>
        /// <returns>
        /// 返回一个游戏业务代号字符串
        /// </returns>
        public static string GetGameId() => Configuration.Instance.GameId;

        /// <summary>
        /// 获取设备ID
        /// </summary>
        /// <returns>
        /// 返回设备ID字符串
        /// </returns>
        public static string GetDeviceId() => Native.GetDeviceId();

        /// <summary>
        /// 游戏客户端的发行版本
        /// </summary>
        public static string GetDistro() => Native.GetDistro();

        /// <summary>
        /// 获取 Unity SDK Version
        /// </summary>
        public static string GetVersion() => Version.SDKVersion;

        /// <summary>
        /// 获取 Unity SDK 内集成的 Native SDK Version (Android, iOS, Windows)
        /// </summary>
        public static string GetVersionNative() => Native.GetVersion();
        
        /// <summary>
        /// 获取游戏的下载链接
        /// </summary>
        /// <param name="callback">获取下载链接完成后的回调，用于接收下载链接的结果</param>
        /// <remarks>
        /// <para>用于获得该发行版本或发行版本分包对应的下载地址</para>
        /// </remarks>
        public static void GetDownloadUrl(Action<Result<DownloadUrlResult>> callback) => Native.GetDownloadUrl(callback);

        /// <summary>
        /// 检查特定功能是否可用。
        /// </summary>
        /// <param name="feature">需要检查的功能。</param>
        /// <returns>如果指定的功能可用，则返回 true，否则返回 false。</returns>
        public static bool IsFeatureAvailable(Feature feature) => Native.IsFeatureAvailable(feature);

        /// <summary>
        /// 打开应用的系统权限设置界面
        /// </summary>
        /// <remarks>
        /// 调用此接口，将打开该应用的系统权限设置界面，用户可在此进行权限授权修改。
        /// </remarks>
        public static void OpenAppSettings() => Native.OpenAppSettings();

        /// <summary>
        /// 打开世游客服系统链接
        /// </summary>
        /// <remarks>
        /// 调用此接口，将打开世游客服系统链接
        /// </remarks>
        public static void ContactSupport() => Native.ContactSupport();

        /// <summary>
        /// 通过 WebView 在游戏内打开一组具有固定功能的 Web 页面
        /// </summary>
        /// <param name="url">需要打开的界面。</param>
        /// <remarks>
        /// 调用此接口，将打开固定功能的 Web 页面
        /// </remarks>
        public static void OpenGameUrl(GameUrl url) => Native.OpenGameUrl(url);

        public static void OpenShortLink(string shortLink, Dictionary<string, string> gameData, Action<Result<OpenShortLinkResult>> callback) =>
        Native.OpenShortLink(shortLink, gameData, callback);

        /// <summary>
        /// 获取当前是否存在新公告
        /// </summary>
        /// <param name="CheckAnnouncementsOptions">判断是否存在新公告的选项。</param>
        /// <param name="callback">判断是否存在新公告完成后的回调</param>
        /// <remarks>
        /// 调用此接口，将获取当前是否存在新公告
        /// </remarks>
        public static void CheckAnnouncements(CheckAnnouncementsOptions opts, Action<Result<CheckAnnouncementsResult>> callback) => Native.CheckAnnouncements(opts, callback);

        /// <summary>
        /// 通过 WebView 在游戏内打开游戏公告
        /// </summary>
        /// <param name="OpenAnnouncementsOptions">打开游戏公告的选项。</param>
        /// <param name="callback">打开游戏公告完成后的回调</param>
        /// <remarks>
        /// 调用此接口，将打开游戏公告
        /// </remarks>
        public static void OpenAnnouncements(OpenAnnouncementsOptions opts, Action<Result<OpenAnnouncementsResult>> callback) => Native.OpenAnnouncements(opts, callback);

        /// <summary>
        /// 通过 WebView 在游戏内打开举报页面
        /// </summary>
        /// <param name="ComplainOptions">游戏内举报参数集合。</param>
        /// <param name="callback">游戏内举报完成后的回调</param>
        /// <remarks>
        /// 调用此接口，将打开游戏内举报页面
        /// </remarks>
        public static void Complain(ComplainOptions opts, Action<Result<ComplainResult>> callback) => Native.Complain(opts, callback);

        /// <summary>
        /// 设置或读取 SDK 的语言偏好
        /// </summary>
        /// <remarks>
        /// 调用此接口，可以设置或读取 SDK 的语言偏好
        /// </remarks>
        public static LanguagePreference LanguagePreference
        {
            get => Native.LanguagePreference;
            set => Native.LanguagePreference = value;
        }

        /// <summary>
        /// 读取 SDK 当前使用的语言代码
        /// </summary>
        /// <remarks>
        /// 调用此接口，可以读取 SDK 当前使用的语言代码
        /// </remarks>
        public static string LanguageCode => Native.LanguageCode;

        /// <summary>
        /// 通过 WebView 在游戏内打开礼包码兑换页面
        /// </summary>
        /// <param name="RedeemGiftCodeOptions">打开礼包码兑换页面的选项。</param>
        /// <param name="callback">打开礼包码兑换页面完成后的回调</param>
        /// <remarks>
        /// 调用此接口，将打开礼包码兑换页面
        /// </remarks>
        public static void RedeemGiftCode(RedeemGiftCodeOptions opts, Action<Result<RedeemGiftCodeResult>> callback) => Native.RedeemGiftCode(opts, callback);

        /// <summary>
        /// 进行抖音双通 SDK 自定义事件上报
        /// </summary>
        /// <param name="eventName">自定义事件名称</param>
        /// <param name="eventParams">自定义事件的参数</param>
        /// <remarks>
        /// 调用此接口，将完成抖音双通 SDK 自定义事件上报
        /// </remarks>
        public static void ReportDouyinCustomEvent(string eventName, Dictionary<string, string> eventParams) => Native.ReportDouyinCustomEvent(eventName, eventParams);

        public static class SeayooAccount
        {
            /// <summary>
            /// 获取世游通行证用户 ID
            /// </summary>
            /// <returns>
            /// 世游通行证用户 ID
            /// </returns>
            public static string UserId => Native.UserId;
            /// <summary>
            /// 打开世游通行证网站
            /// </summary>
            /// <remarks>
            /// 调用此接口，将打开世游通行证网站并自动登录当前通行证账号
            /// </remarks>
            public static void ManageAccount() => Native.ManageAccount();
            /// <summary>
            /// 打开世游通行证修改密码界面
            /// </summary>
            /// <remarks>
            /// 调用此接口，将打开通行证网站的修改密码页面（自动登录）
            /// </remarks>
            public static void ChangePassword() => Native.ChangePassword();
            /// <summary>
            /// 打开世游通行证删除账号界面
            /// </summary>
            /// <remarks>
            /// 调用此接口，将打开通行证网站的删除账号页面（自动登录）
            /// </remarks>
            public static void DeleteAccount() => Native.DeleteAccount();
        }

#region Android-Only

        /// <summary>
        /// 使用发行版本自有更新唤起功能
        /// </summary>
        /// <param name="callback">更新游戏完成后的回调，用于接收更新操作的结果</param>
        /// <remarks>
        /// <para> - 在调用此方法前，需要先调用 IsFeatureAvailable 检查 UpdateGame 功能是否有效</para>
        /// </remarks>
        public static void UpdateGame(Action<Result<UpdateGameResult>> callback) =>
            Native.UpdateGame(new UpdateGameOptions(), callback);

        /// <summary>
        /// 获取游戏分包标识.
        /// </summary>
        /// <returns>如果没有标识则返回 empty string.</returns>
        /// <remarks>
        /// <para> - Combo SDK 已经设置数数的 SuperProperties, 游戏客户端不需要再次设置此属性!</para>
        /// <para> - 游戏客户端可获取此标识, 传递给游戏服务端用于数数埋点上报!</para>
        /// </remarks>
        public static string GetVariant() => Native.GetVariant();
        
        /// <summary>
        /// 获取游戏二级分包标识.
        /// </summary>
        /// <returns>如果没有标识则返回 empty string.</returns>
        /// <remarks>
        /// <para> - Combo SDK 已经设置数数的 SuperProperties, 游戏客户端不需要再次设置此属性!</para>
        /// <para> - 游戏客户端可获取此标识, 传递给游戏服务端用于数数埋点上报!</para>
        /// </remarks>
        public static string GetSubvariant() => Native.GetSubvariant();

        /// <summary>
        /// 退出游戏
        /// </summary>
        /// <param name="callback">退出游戏完成后的回调，用于接收退出操作的结果</param>
        /// <remarks>
        /// <para> - 在调用此方法前，需要先调用 IsFeatureAvailable 检查 Quit 功能是否有效</para>
        /// </remarks>
        public static void Quit(Action<Result<QuitResult>> callback) => Native.Quit(callback);

        /// <summary>
        /// 上报伪付费事件
        /// </summary>
        /// <param name="amount">付费事件金额</param>
        public static void PromoPseudoPurchase(PromoPseudoPurchaseOptions opts) => Native.PromoPseudoPurchase(opts);

        /// <summary>
        /// 抹除当前设备游客账号
        /// </summary>
        public static bool ResetGuest() => Native.ResetGuest();
#endregion
    }
}
