#import "ComboSDKIOSWrapper.h"
#import <CommonCrypto/CommonDigest.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/AdSupport.h>
#import <ComboSDK/ComboSDK-Swift.h>
#import <Foundation/Foundation.h>

#include <sys/types.h>
#include <sys/sysctl.h>

@implementation ComboSDKIOSWrapper

static ComboSDKIOSWrapper* _instance = nil;

+(instancetype) shareInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:NULL] init];
    });
    
    return _instance;
}

+(id) allocWithZone:(struct _NSZone *)zone
{
    
    return [ComboSDKIOSWrapper shareInstance];
}

- (void)setup:(NSString *)jsonData
{
    NSLog(@"[SDK_SETUP]");
    NSData *_jsonData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    NSDictionary *extra = dictionary[@"extra"];
    ComboSDKSetupOptions *options = [[ComboSDKSetupOptions alloc] init];
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    } else {
        options.gameId = [self getValueFromDictionary:dictionary forKey:@"gameId" withType:@"string"];
        options.publishableKey = [self getValueFromDictionary:dictionary forKey:@"publishableKey" withType:@"string"];
        options.endpoint = [self getValueFromDictionary:dictionary forKey:@"endpoint" withType:@"string"];
        options.extra = extra;
    }
    [[ComboSDK shared] setupWithController:UnityGetGLViewController() options:options completionHandler:^(ComboSDKSetupResult * _Nullable result, ComboSDKError * _Nullable error) {
        [self logResultWithOperation:@"初始化" message:options.gameId error:error];
        if (error == nil) {
            UnitySendMessage("ComboSDKIOS", "_SetupSucceed", [@"" UTF8String]);
        } else {
        NSString *jsonString = [self getComboSDKErrorJsonString:error];
        UnitySendMessage("ComboSDKIOS", "_SetupFailed", [jsonString UTF8String]);
        }
    }];

    [[ComboSDK shared] registerKickOutWithCompletionHandler:^(ComboSDKKickOutResult * _Nullable result) {
        [self logResultWithOperation:@"踢出用户" message:@"" error:nil];
        Boolean shouldExit = result.shouldExit;
        NSDictionary *data = @{
            @"shouldExit": @(shouldExit)
        };
        NSString *jsonString = [self convertDictionaryToJsonString:data];
        UnitySendMessage("ComboSDKIOS", "_KickOutSucceed", [jsonString UTF8String]);
    }];
}

- (void)login {
    [[ComboSDK shared] loginWithController:UnityGetGLViewController() completionHandler:^(ComboSDKLoginResult * _Nullable result, ComboSDKError * _Nullable error) {
        NSString * str = [NSString stringWithFormat:@"comboId = %@, token = %@", result.loginInfo.comboId, result.loginInfo.identityToken];
        [self logResultWithOperation:@"登录" message:str error:error];
        
        if (error == nil) {
            NSString *comboId = result.loginInfo.comboId;
            NSString *identityToken = result.loginInfo.identityToken;
            NSDictionary *data = @{
                @"loginInfo": @{
                    @"comboId": comboId,
                    @"identityToken": identityToken
                }
            };
            NSString *jsonString = [self convertDictionaryToJsonString:data];
            UnitySendMessage("ComboSDKIOS", "_LoginSucceed", [jsonString UTF8String]);
        } else {
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_LoginFailed", [jsonString UTF8String]);
        }
    }];
}

- (void)logout
{
    [[ComboSDK shared] logoutWithCompletionHandler:^(ComboSDKLogoutResult * _Nullable result, ComboSDKError * _Nullable error) {
        [self logResultWithOperation:@"登出" message:result.comboId error:error];
        if (error == nil) {
            NSString *comboId = result.comboId;
            NSDictionary *data = @{
                @"comboId": comboId,
            };
            NSString *jsonString = [self convertDictionaryToJsonString:data];
            UnitySendMessage("ComboSDKIOS", "_LogoutSucceed", [jsonString UTF8String]);
        } else {
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_LogoutFailed", [jsonString UTF8String]);
        }
    }];
}


- (void)purchase:(NSString*)jsonData {
    NSLog(@"[SDK_PAY] jsonData：%@", jsonData);
    NSData *_jsonData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    ComboSDKPurchaseOptions *options = [[ComboSDKPurchaseOptions alloc] init];
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    } else {
        options.orderToken = [self getValueFromDictionary:dictionary forKey:@"orderToken" withType:@"string"];
        options.productDescription = [self getValueFromDictionary:dictionary forKey:@"productDescription" withType:@"string"];
    }
    [[ComboSDK shared] purchaseWithOptions:options completionHandler:^(ComboSDKPurchaseResult * _Nullable result, ComboSDKError * _Nullable error) {
        NSString * str = [NSString stringWithFormat:@"orderToken = %@", result.orderId];
        [self logResultWithOperation:@"支付" message:str error:error];
        if (error == nil) {
            NSString *orderId = result.orderId;
            NSDictionary *data = @{
                @"orderId": orderId
            };
            NSString *jsonString = [self convertDictionaryToJsonString:data];
            UnitySendMessage("ComboSDKIOS", "_PurchaseSucceed", [jsonString UTF8String]);
        } else {
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_PurchaseFailed", [jsonString UTF8String]);
        }
    }];
}

//获取用户信息
- (NSString*)getUserInfo{
    ComboSDKLoginInfo *info = [[ComboSDK shared] getLoginInfo];
    NSString *msg = [NSString stringWithFormat:@"comboId = %@, identityToken = %@", info.comboId, info.identityToken];
    [self logCallBack:@"获取用户信息" msg:msg];
    
    NSDictionary *dictionary = @{
        @"comboId": info.comboId,
        @"identityToken": info.identityToken,
        @"idp": info.idp
    };
    
    NSError* error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
    if (error) {
        NSLog(@"转换为JSON时发生错误：%@", error);
        return @"";
    } else {
        // 将JSON数据转为字符串
        NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        NSLog(@"JSON字符串：%@", jsonString);
        return jsonString;
    }
}

// 获取 iOS ComboSDK 版本
- (NSString*)getVersion{
    NSString *version = [[ComboSDK shared] getVersion];
    NSLog(@"SDK version：%@", version);
    return version;
}

// 获取游戏客户端发行版本
- (NSString*)getDistro{
    NSString *distro = [[ComboSDK shared] getDistro];
    NSLog(@"SDK distro：%@", distro);
    return distro;
}

// 获取设备 DeviceId（Unity特供）
- (NSString*)getDeviceId{
    NSString *deviceId = [[ComboSDK shared] getDeviceId];
    NSLog(@"DeviceId:%@", deviceId);
    return deviceId;
}

// 获取 iOS 服务端参数（Unity特供）
- (NSString*)getParameters{
    NSDictionary *parameters = [[ComboSDK shared] getParameters];
    return [self convertDictionaryToJsonString:parameters];
}

//用户中心
- (void)openAccountCenter{
//    [[ComboSDKv3 shared] openAccountCenterWithController:UnityGetGLViewController()];
}

// 分享
- (void)share:(NSString*)type jsonData:(NSString *)jsonData;{
    NSLog(@"[SDK_SHARE] type: %@, jsonData：%@", type, jsonData);
    NSData *_jsonData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    id options;
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    } else {
        if ([type isEqualToString:@"ImageShareOptions"]) {
            options = [self getImageShareOptions:dictionary];
        }
        else if ([type isEqualToString:@"VideoShareOptions"]) {
            options = [self getVideoShareOptions:dictionary];
        }
        else if ([type isEqualToString:@"LinkShareOptions"]) {
            options = [self getLinkShareOptions:dictionary];
        } else {
            NSLog(@"Unsupported share type");
        }
    }
    
    [[ComboSDK shared] shareWithController:UnityGetGLViewController() options:options completionHandler:^(ComboSDKShareResult * _Nullable result, ComboSDKError * _Nullable error) {
        
        [self logResultWithOperation:@"分享" message:nil error:error];
        if (error == nil) {
            NSDictionary *data = @{};
            NSString *jsonString = [self convertDictionaryToJsonString:data];
            UnitySendMessage("ComboSDKIOS", "_ShareSucceed", [jsonString UTF8String]);
        }
        else{
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_ShareFailed", [jsonString UTF8String]);
        }
    }];
}

- (ComboSDKImageShareOptions*)getImageShareOptions:(NSDictionary*) dictionary{
    ComboSDKImageShareOptions *options = [[ComboSDKImageShareOptions alloc] init];
    options.text = [self getValueFromDictionary:dictionary forKey:@"Text" withType:@"string"];
    options.title = [self getValueFromDictionary:dictionary forKey:@"Title" withType:@"string"];
    options.imageUrl = [self getValueFromDictionary:dictionary forKey:@"ImageUrl" withType:@"string"];
    options.hashtag = [self getValueFromDictionary:dictionary forKey:@"Hashtag" withType:@"string"];
    
    NSNumber *scene = [self getValueFromDictionary:dictionary forKey:@"Scene" withType:@"int"];
    NSNumber *target = [self getValueFromDictionary:dictionary forKey:@"Target" withType:@"int"];
    options.target = [self getShareTargetWithInt:target];
    options.scene = [self getShareSceneWithInt:scene];
    
    return options;
}

- (ComboSDKVideoShareOptions*)getVideoShareOptions:(NSDictionary*) dictionary{
    ComboSDKVideoShareOptions *options = [[ComboSDKVideoShareOptions alloc] init];
    options.text = [self getValueFromDictionary:dictionary forKey:@"Text" withType:@"string"];
    options.title = [self getValueFromDictionary:dictionary forKey:@"Title" withType:@"string"];
    options.videoUrl = [self getValueFromDictionary:dictionary forKey:@"VideoUrl" withType:@"string"];
    options.videoCoverUrl = [self getValueFromDictionary:dictionary forKey:@"VideoCoverUrl" withType:@"string"];
    options.hashtag = [self getValueFromDictionary:dictionary forKey:@"Hashtag" withType:@"string"];
    
    NSNumber *scene = [self getValueFromDictionary:dictionary forKey:@"Scene" withType:@"int"];
    NSNumber *target = [self getValueFromDictionary:dictionary forKey:@"Target" withType:@"int"];
    options.target = [self getShareTargetWithInt:target];
    options.scene = [self getShareSceneWithInt:scene];
    
    return options;
}

- (ComboSDKLinkShareOptions*)getLinkShareOptions:(NSDictionary*) dictionary{
    ComboSDKLinkShareOptions *options = [[ComboSDKLinkShareOptions alloc] init];
    options.text = [self getValueFromDictionary:dictionary forKey:@"Text" withType:@"string"];
    options.title = [self getValueFromDictionary:dictionary forKey:@"Title" withType:@"string"];
    options.linkUrl = [self getValueFromDictionary:dictionary forKey:@"LinkUrl" withType:@"string"];
    options.linkCoverUrl = [self getValueFromDictionary:dictionary forKey:@"LinkCoverUrl" withType:@"string"];
    
    NSNumber *target = [self getValueFromDictionary:dictionary forKey:@"Target" withType:@"int"];
    NSNumber *scene = [self getValueFromDictionary:dictionary forKey:@"Scene" withType:@"int"];
    options.target = [self getShareTargetWithInt:target];
    options.scene = [self getShareSceneWithInt:scene];
    
    return options;
}

- (ComboSDKShareTarget)getShareTargetWithInt:(NSNumber*) number {
    ComboSDKShareTarget target;
    switch ([number intValue]) {
        case 0:
            target = ComboSDKShareTargetSystem;
            break;
        case 2:
            target = ComboSDKShareTargetAgora;
            break;
        case 3:
            target = ComboSDKShareTargetWeixin;
            break;
        case 4:
            target = ComboSDKShareTargetWeibo;
            break;
        case 5:
            target = ComboSDKShareTargetDouyin;
            break;
        case 6:
            target = ComboSDKShareTargetQq;
            break;
        default:
            target = ComboSDKShareTargetSystem;
            break;
    }
    return target;
}

- (ComboSDKShareScene)getShareSceneWithInt:(NSNumber*) number {
    ComboSDKShareScene scene;
    switch ([number intValue]) {
        case 0:
            scene = ComboSDKShareSceneWeixinSession;
            break;
        case 1:
            scene = ComboSDKShareSceneWeixinTimeLine;
            break;
        case 2:
            scene = ComboSDKShareSceneWeixinFavorite;
            break;
        case 3:
            scene = ComboSDKShareSceneDouyinEdit;
            break;
        case 4:
            scene = ComboSDKShareSceneDouyinPublish;
            break;
        case 5:
            scene = ComboSDKShareSceneDouyinContacts;
            break;
        case 6:
            scene = ComboSDKShareSceneQq;
            break;
        case 7:
            scene = ComboSDKShareSceneQzone;
            break;
        default:
            scene = ComboSDKShareSceneWeixinSession;
            break;
    }
    return scene;
}

- (void)preloadAd:(NSString*)jsonData{
    NSLog(@"[SDK_PRELOAD_AD] jsonData：%@", jsonData);
    NSData *_jsonData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    NSString *placementId = @"";
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    } else {
        placementId = [self getValueFromDictionary:dictionary forKey:@"placementId" withType:@"string"];
    }
    AdsOptions *options = [[AdsOptions alloc] initWithPlacementId:placementId];
    options.scenarioId = [self getValueFromDictionary:dictionary forKey:@"scenarioId" withType:@"string"];
    [[ComboSDK shared] preloadAdWithController:UnityGetGLViewController() options:options completionHandler:^(ComboSDKPreloadAdResult * _Nullable result, ComboSDKError * _Nullable error) {
        
        [self logResultWithOperation:@"预加载广告" message:result.placementId error:error];
        if (error == nil) {
            NSString *placementId = result.placementId;
            NSDictionary *data = @{
                @"placementId": placementId
            };
            NSString *jsonString = [self convertDictionaryToJsonString:data];
            UnitySendMessage("ComboSDKIOS", "_PreloadAdSucceed", [jsonString UTF8String]);
        }
        else{
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_PreloadAdFailed", [jsonString UTF8String]);
        }
    }];
}

- (void)showAd:(NSString*)jsonData{
    NSLog(@"[SDK_SHOW_AD] jsonData：%@", jsonData);
    NSData *_jsonData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    NSString *placementId = @"";
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    } else {
        placementId = [self getValueFromDictionary:dictionary forKey:@"placementId" withType:@"string"];
    }
    AdsOptions *options = [[AdsOptions alloc] initWithPlacementId:placementId];
    options.scenarioId = [self getValueFromDictionary:dictionary forKey:@"scenarioId" withType:@"string"];
    [[ComboSDK shared] showAdWithController:UnityGetGLViewController() options:options completionHandler:^(ComboSDKShowAdResult * _Nullable result, ComboSDKError * _Nullable error) {
            NSString *status = [NSString stringWithFormat:@"%ld", (long)result.status];
            [self logResultWithOperation:@"播放广告" message:status error:error];
            if (error == nil) {
                NSNumber *status = [NSNumber numberWithInteger:result.status];;
                NSString *token = result.adToken;
                NSDictionary *data = @{
                    @"status": status,
                    @"token": (token != nil) ? token : @""
                };
                NSString *jsonString = [self convertDictionaryToJsonString:data];
                UnitySendMessage("ComboSDKIOS", "_ShowAdSucceed", [jsonString UTF8String]);
            }
            else{
                NSString *jsonString = [self getComboSDKErrorJsonString:error];
                UnitySendMessage("ComboSDKIOS", "_ShowAdFailed", [jsonString UTF8String]);
            }
    }];
    
}

- (void)openAppSettings {
    NSLog(@"[SDK_OPEN_APP_SETTINGS]");
    [[ComboSDK shared] openAppSettings];
}

- (NSString*)getUserId{
    NSLog(@"[SDK_GET_USER_ID]");
    NSString *uid = [ComboSDK.SeayooAccount getUserId];
    [self logResultWithOperation:@"获取通行证 UserId" message:uid error:nil];
    return uid;
}

- (void)manageAccount {
    NSLog(@"[SDK_MANAGE_ACCOUNT]");
    [ComboSDK.SeayooAccount manageAccount];
}

- (void)deleteAccount {
    NSLog(@"[SDK_DELETE_ACCOUNT]");
    [ComboSDK.SeayooAccount deleteAccount];
}

- (void)changePassword {
    NSLog(@"[SDK_CHANGE_PASSWORD]");
    [ComboSDK.SeayooAccount changePassword];
}

- (void)contactSupport {
    NSLog(@"[SDK_CONTACT_SUPPORT]");
    [ComboSDK.SeayooAccount contactSupportWithController:UnityGetGLViewController()];
}

- (void)openGameUrlWithController:(NSString *)gameUrl {
    NSLog(@"[SDK_OPEN_GAME_URL_WITH_CONTROLLER] gameUrl：%@", gameUrl);

    if ([gameUrl isEqualToString:@"USER_AGREEMENT"]) {
        ComboSDKGameUrl gameUrl = ComboSDKGameUrlUserAgreement;
        [ComboSDK.shared openGameUrlWithController: UnityGetGLViewController() gameUrl: gameUrl];
    } else if ([gameUrl isEqualToString:@"PRIVACY_POLICY"]) {
        ComboSDKGameUrl gameUrl = ComboSDKGameUrlPrivacyPolicy;
        [ComboSDK.shared openGameUrlWithController: UnityGetGLViewController() gameUrl: gameUrl];
    } else if ([gameUrl isEqualToString:@"PRIVACY_CHILDREN"]) {
        ComboSDKGameUrl gameUrl = ComboSDKGameUrlPrivacyChildren;
        [ComboSDK.shared openGameUrlWithController: UnityGetGLViewController() gameUrl: gameUrl];
    } else if ([gameUrl isEqualToString:@"THIRD_PARTY"]) {
        ComboSDKGameUrl gameUrl = ComboSDKGameUrlThirdParty;
        [ComboSDK.shared openGameUrlWithController: UnityGetGLViewController() gameUrl: gameUrl];
    } else if ([gameUrl isEqualToString:@"FANGCHENMI"]) {
        ComboSDKGameUrl gameUrl = ComboSDKGameUrlFangchenmi;
        [ComboSDK.shared openGameUrlWithController: UnityGetGLViewController() gameUrl: gameUrl];
    } else {
        return;
    }
}

- (Boolean)isFeatureAvailable:(NSString *)feature {
    NSLog(@"[SDK_IS_FEATURE_AVAILABLE] feature: %@", feature);
    
    if ([feature isEqualToString:@"SEAYOO_ACCOUNT"]) {
        ComboSDKFeature feature = ComboSDKFeatureSeayooAccount;
        return [[ComboSDK shared] isFeatureAvailableWithFeature: feature];
    } else if ([feature isEqualToString:@"CONTACT_SUPPORT"]) {
        ComboSDKFeature feature = ComboSDKFeatureContactSupport;
        return [[ComboSDK shared] isFeatureAvailableWithFeature: feature];
    } else if ([feature isEqualToString:@"REPORT_DOUYIN_CUSTOM_EVENT"]) {
        ComboSDKFeature feature = ComboSDKFeatureReportDouyinCustomEvent;
        return [[ComboSDK shared] isFeatureAvailableWithFeature: feature];
    } else if ([feature isEqualToString:@"COMPLAIN"]) {
        ComboSDKFeature feature = ComboSDKFeatureComplain;
        return [[ComboSDK shared] isFeatureAvailableWithFeature: feature];
    } else if ([feature isEqualToString:@"OPEN_SHORT_LINK"]) {
        ComboSDKFeature feature = ComboSDKFeatureOpenShortLink;
        return [[ComboSDK shared] isFeatureAvailableWithFeature: feature];
    } else {
        return FALSE;
    }
}

- (void)getDownloadUrl {
    NSLog(@"[SDK_GET_DOWNLOAD_URL]");
    [[ComboSDK shared] getDownloadUrlWithCompletionHandler:^(ComboSDKGetDownloadUrlResult * _Nullable result, ComboSDKError * _Nullable error) {
        NSString *url = [NSString stringWithFormat:@"%@", result.downloadUrl];
        [self logResultWithOperation:@"获取下载链接" message:url error:error];
        if (error == nil) {
            NSString *downloadUrl = result.downloadUrl;
            NSDictionary *data = @{
                @"downloadUrl": downloadUrl
            };
            NSString *jsonString = [self convertDictionaryToJsonString:data];
            UnitySendMessage("ComboSDKIOS", "_GetDownloadUrlSucceed", [jsonString UTF8String]);
        }
        else{
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_GetDownloadUrlFailed", [jsonString UTF8String]);
        }
    }];
}

- (NSArray*) getAvailableShareTargets{
    NSLog(@"[SDK_GET_AVAILABLE_SHARE_TARGETS]");
    return [[ComboSDK shared] getAvailableShareTargets];
}

- (void) openShortLink:(NSString *)link gameData:(NSString *)gameData{
    NSLog(@"[SDK_OPEN_SHORT_LINK]");
    NSData *_jsonData = [gameData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *gameDataDic = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    }
    [[ComboSDK shared] openShortLinkWithController:UnityGetGLViewController() shortLink: link gameData: gameDataDic completionHandler:^(ComboSDKOpenShortLinkResult * _Nullable result, ComboSDKError * _Nullable error) {
        [self logResultWithOperation:@"打开短链" message:link error:error];
        if (error == nil) {
            UnitySendMessage("ComboSDKIOS", "_OpenShortLinkSucceed", [@"" UTF8String]);
        } else {
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_OpenShortLinkFailed", [jsonString UTF8String]);
        }
    }];
}

- (void)checkAnnouncements:(NSString *)jsonData {
    NSLog(@"[SDK_CHECK_ANNOUNVEMENTS jsonData: %@", jsonData);
    NSData *_jsonData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    CheckAnnouncementsOptions *options = [[CheckAnnouncementsOptions alloc] init];
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    } else {
        options.profile = [self getValueFromDictionary:dictionary forKey:@"Profile" withType:@"string"];
        NSNumber *level = [self getValueFromDictionary:dictionary forKey:@"Level" withType:@"int"];
        options.level = [level integerValue];
    }
    [[ComboSDK shared] checkAnnouncementsWithController:UnityGetGLViewController() options:options completionHandler:^(CheckAnnouncementsResult * _Nullable result, ComboSDKError * _Nullable error) {
        NSString * str = [NSString stringWithFormat:@"newAnnouncementsAvailable = %d", result.newAnnouncementsAvailable];
        [self logResultWithOperation:@"检查公告" message:str error:error];
        if (error == nil) {
            Boolean newAnnAvailable = result.newAnnouncementsAvailable;
            NSDictionary *data = @{
                @"newAnnouncementsAvailable": @(newAnnAvailable)
            };
            NSString *jsonString = [self convertDictionaryToJsonString:data];
            UnitySendMessage("ComboSDKIOS", "_CheckAnnouncementsSucceed", [jsonString UTF8String]);
        } else {
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_CheckAnnouncementsFailed", [jsonString UTF8String]);
        }
    }];
}

- (void)openAnnouncements:(NSString *)jsonData {
    NSLog(@"[SDK_OPEN_ANNOUNVEMENTS jsonData: %@", jsonData);
    NSData *_jsonData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    OpenAnnouncementsOptions *options = [[OpenAnnouncementsOptions alloc] init];
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    } else {
        options.profile = [self getValueFromDictionary:dictionary forKey:@"Profile" withType:@"string"];
        NSNumber *level = [self getValueFromDictionary:dictionary forKey:@"Level" withType:@"int"];
        options.level = [level integerValue];
        NSNumber *width = [self getValueFromDictionary:dictionary forKey:@"Width" withType:@"int"];
        options.width = [width integerValue];
        NSNumber *height = [self getValueFromDictionary:dictionary forKey:@"Height" withType:@"int"];
        options.height = [height integerValue];
    }
    [[ComboSDK shared] openAnnouncementsWithController:UnityGetGLViewController() options:options completionHandler:^(OpenAnnouncementsResult * _Nullable result, ComboSDKError * _Nullable error) {
        [self logResultWithOperation:@"打开游戏公告" message:@"" error:error];
        if (error == nil) {
            UnitySendMessage("ComboSDKIOS", "_OpenAnnouncementsSucceed", [@"" UTF8String]);
        } else {
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_OpenAnnouncementsFailed", [jsonString UTF8String]);
        }
    }];
}

// 获取公告列表：解析 options → 调用 SDK → 将结果序列化为与 C# GetAnnouncementsResult 匹配的 JSON 回传 Unity
- (void)getAnnouncements:(NSString *)jsonData {
    NSLog(@"[SDK_GET_ANNOUNCEMENTS] jsonData: %@", jsonData);
    NSData *_jsonData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    GetAnnouncementsOptions *options = [[GetAnnouncementsOptions alloc] init];
    if (error) {
        NSLog(@"[SDK_GET_ANNOUNCEMENTS] Error parsing JSON: %@", error.localizedDescription);
    } else {
        options.profile = [self getValueFromDictionary:dictionary forKey:@"Profile" withType:@"string"];
        NSNumber *level = [self getValueFromDictionary:dictionary forKey:@"Level" withType:@"int"];
        options.level = [level integerValue];
    }
    [[ComboSDK shared] getAnnouncementsWithOptions:options completionHandler:^(GetAnnouncementsResult * _Nullable result, ComboSDKError * _Nullable error) {
        [self logResultWithOperation:@"获取公告列表" message:@"" error:error];
        if (error == nil) {
            // 将 SDK 返回的公告列表逐字段映射为 C# Announcement 的 PascalCase JSON
            NSMutableArray *announcementsArray = [NSMutableArray array];
            for (Announcement *item in result.announcements) {
                [announcementsArray addObject:@{
                    @"Id":          item.id ?: @"",
                    @"Title":       item.title ?: @"",
                    @"Subtitle":    item.subtitle ?: @"",
                    @"Content":     item.content ?: @"",
                    @"Format":      item.format ?: @"",
                    @"Lang":        item.lang ?: @"",
                    @"PublishedAt": @(item.publishedAt)
                }];
            }
            NSString *jsonString = [self convertDictionaryToJsonString:@{ @"Announcements": announcementsArray }];
            NSLog(@"[SDK_GET_ANNOUNCEMENTS] Send message to unity: %@", jsonString);
            UnitySendMessage("ComboSDKIOS", "_GetAnnouncementsSucceed", [jsonString UTF8String]);
        } else {
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            NSLog(@"[SDK_GET_ANNOUNCEMENTS] Failed, send message to unity: %@", jsonString);
            UnitySendMessage("ComboSDKIOS", "_GetAnnouncementsFailed", [jsonString UTF8String]);
        }
    }];
}

- (void)complain:(NSString *)jsonData {
    NSLog(@"[SDK_COMPLAIN jsonData: %@", jsonData);
    NSData *_jsonData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    ComplainOptions *options = [[ComplainOptions alloc] init];
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    } else {
        options.targetType = [self getValueFromDictionary:dictionary forKey:@"TargetType" withType:@"string"];
        options.targetId = [self getValueFromDictionary:dictionary forKey:@"TargetId" withType:@"string"];
        options.targetName = [self getValueFromDictionary:dictionary forKey:@"TargetName" withType:@"string"];
        options.category = [self getValueFromDictionary:dictionary forKey:@"Category" withType:@"string"];
        options.serverId = [self getValueFromDictionary:dictionary forKey:@"ServerId" withType:@"string"];
        options.roleId = [self getValueFromDictionary:dictionary forKey:@"RoleId" withType:@"string"];
        options.roleName = [self getValueFromDictionary:dictionary forKey:@"RoleName" withType:@"string"];
        options.targetType = [self getValueFromDictionary:dictionary forKey:@"TargetType" withType:@"string"];
        options.context = [self getValueFromDictionary:dictionary forKey:@"Context" withType:@"string"];
        NSNumber *width = [self getValueFromDictionary:dictionary forKey:@"Width" withType:@"int"];
        options.width = [width integerValue];
        NSNumber *height = [self getValueFromDictionary:dictionary forKey:@"Height" withType:@"int"];
        options.height = [height integerValue];
    }
    [[ComboSDK shared] complainWithController:UnityGetGLViewController() options:options completionHandler:^(ComplainResult * _Nullable result, ComboSDKError * _Nullable error) {
        [self logResultWithOperation:@"游戏内举报" message:@"" error:error];
        if (error == nil) {
            UnitySendMessage("ComboSDKIOS", "_ComplainSucceed", [@"" UTF8String]);
        } else {
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_ComplainFailed", [jsonString UTF8String]);
        }
    }];
}

- (void)redeemGiftCode:(NSString *)jsonData {
    NSLog(@"[SDK_REDEEM_GIFT_CODE jsonData: %@", jsonData);
    NSData *_jsonData = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error;
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:_jsonData options:kNilOptions error:&error];
    RedeemGiftCodeOptions *options = [[RedeemGiftCodeOptions alloc] init];
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    } else {
        NSNumber *serverId = [self getValueFromDictionary:dictionary forKey:@"ServerId" withType:@"int"];
        options.serverId = [serverId integerValue];
        options.giftCode = [self getValueFromDictionary:dictionary forKey:@"GiftCode" withType:@"string"];
        options.roleId = [self getValueFromDictionary:dictionary forKey:@"RoleId" withType:@"string"];
        options.roleName = [self getValueFromDictionary:dictionary forKey:@"RoleName" withType:@"string"];
        NSNumber *width = [self getValueFromDictionary:dictionary forKey:@"Width" withType:@"int"];
        options.width = [width integerValue];
        NSNumber *height = [self getValueFromDictionary:dictionary forKey:@"Height" withType:@"int"];
        options.height = [height integerValue];
    }
    [[ComboSDK shared] redeemGiftCodeWithController:UnityGetGLViewController() options:options completionHandler:^(RedeemGiftCodeResult * _Nullable result, ComboSDKError * _Nullable error) {
        [self logResultWithOperation:@"兑换礼包码" message:@"" error:error];
        if (error == nil) {
            UnitySendMessage("ComboSDKIOS", "_RedeemGiftCodeSucceed", [@"" UTF8String]);
        } else {
            NSString *jsonString = [self getComboSDKErrorJsonString:error];
            UnitySendMessage("ComboSDKIOS", "_RedeemGiftCodeFailed", [jsonString UTF8String]);
        }
    }];
}

- (void)setLanguagePreference: (NSString *)jsonData {
    NSLog(@"[SDK_SET_LANGUAGE_PREFERENCE jsonData: %@", jsonData);
    LanguagePreference p;
    if ([jsonData isEqualToString:@"ChineseSimplified"]) {
        p = LanguagePreferenceChineseSimplified;
    } else if ([jsonData isEqualToString:@"English"]) {
        p = LanguagePreferenceEnglish;
    } else {
        p = LanguagePreferenceFollowSystem;
    }
    [[ComboSDK shared] setLanguagePreferenceWithLanguage:p];
}
- (NSInteger)getLanguagePreference {
    NSLog(@"SDK_GET_LANGUAGE_PREFERENCE");
    return [[ComboSDK shared] getLanguagePreference];
}
- (NSString*)getLanguageCode {
    NSLog(@"SDK_GET_LANGUAGE_CODE");
    return [[ComboSDK shared] getLanguageCode];
}

- (Boolean)resetGuest {
    NSLog(@"SDK_RESET_GUEST");
    return [[ComboSDK shared] resetGuest];
}

- (void) reportDouyinCustomEvent:(NSString *)eventName eventParams:(NSString *)eventParams{
    NSLog(@"[SDK_REPORT_DOUYIN_CUSTOM_EVENT]");
    NSDictionary *dict = [self convertJsonStringToDictionary:eventParams];
    [[ComboSDK shared] reportDouyinCustomEventWithEventName:eventName params:[dict copy]];
}

- (BOOL)isLogin{
    ComboSDKLoginInfo *loginInfo = [ComboSDK shared].getLoginInfo;
    return loginInfo.comboId.length != 0 && loginInfo.comboId.length != 1;
}

- (NSString *)convertDictionaryToJsonString:(NSDictionary *)dict {
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict
                                                       options:0
                                                         error:&error];
    
    if (!jsonData) {
        NSLog(@"Failed to convert dictionary to JSON: %@", error);
        return nil;
    }
    
    return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}

- (NSDictionary *)convertJsonStringToDictionary:(NSString *)jsonString {
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSError *error = nil;
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData
                                                         options:kNilOptions
                                                           error:&error];
    if (error) {
        NSLog(@"Error parsing JSON: %@", error.localizedDescription);
    }
    
    return (NSDictionary *)dict;
}

- (char *)createCStringFromNSString:(NSString *)string {
    if (!string) {
        return NULL;
    }
    return strdup([string UTF8String]);
}

//参数获取
- (id)getValueFromDictionary:(NSDictionary *)dictionary forKey:(NSString *)key withType:(NSString *)type {
    id valueObject = [dictionary objectForKey:key];

    if (valueObject != nil) {
        if ([type isEqualToString:@"int"]) {
            if ([valueObject isKindOfClass:[NSNumber class]]) {
                return @([valueObject intValue]);
            }
        } else if ([type isEqualToString:@"float"]) {
            if ([valueObject isKindOfClass:[NSNumber class]]) {
                return @([valueObject floatValue]);
            }
        } else if ([type isEqualToString:@"string"]) {
            if ([valueObject isKindOfClass:[NSString class]]) {
                return valueObject;
            }
        }
    }
    return nil; // 没有找到或类型不匹配
}

//错误信息
- (NSString*) getComboSDKErrorJsonString:(ComboSDKError *)error {
    NSString *e =error.error; // 错误码
    NSString *message = error.message; // 错误信息
    NSString *detailMessage = error.description; // 错误详细信息
    NSDictionary *data = @{
        @"error": e,
        @"message": message,
        @"detailMessage": detailMessage
    
    };
    return [self convertDictionaryToJsonString:data];
}

- (void)logResultWithOperation:(NSString *)opt message:(NSString *)msg error:(ComboSDKError *)error{
    if (error == nil) {
        [self logCallBack:[NSString stringWithFormat:@"%@成功", opt] msg:msg];
    } else {
        [self logCallBack:[NSString stringWithFormat:@"%@失败", opt] msg:error.message];
    }
}

- (void)logCallBack:(NSString *)cb msg:(NSString *)msg{
    NSString *formatMsg = [NSString stringWithFormat:@"caller=SDK回调(%@)", cb];
    if (msg.length != 0) {
        formatMsg = [formatMsg stringByAppendingFormat:@"result=%@", msg];
    }
    NSLog(@"%@",formatMsg);
}

@end
