#import "RNZoomVideoSdkUser.h"
#import "RCTConvert+RNZoomVideoSdk.h"
#import "RNZoomVideoSdkShareAction.h"
#import <React/RCTConvert.h>

@implementation RNZoomVideoSdkUser

+ (NSDictionary *)mapUser: (ZoomVideoSDKUser*) user {
    @try {
        return @{
            @"userId": [@([user getUserID]) stringValue],
            @"customUserId": [user getCustomUserId],
            @"userName": [user getUserName],
            @"isHost": @([user isHost]),
            @"isManager": @([user isManager]),
        };
    }
    @catch (NSException *e) {
        return @{};
    }
}

+ (NSMutableArray *)mapUserArray: (NSArray<ZoomVideoSDKUser *> *)userArray {
    NSMutableArray *mappedUserArray = [NSMutableArray array];

    @try {
        [userArray enumerateObjectsUsingBlock:^(ZoomVideoSDKUser * _Nonnull user, NSUInteger idx, BOOL * _Nonnull stop) {
            [mappedUserArray addObject: [RNZoomVideoSdkUser mapUser: user]];
        }];
    }
    @finally {
        return mappedUserArray;
    }
}

+ (ZoomVideoSDKUser *)getUser:(NSString*)userId {
    ZoomVideoSDKUser *_user;
    ZoomVideoSDKUser* myUser = [[[ZoomVideoSDK shareInstance] getSession] getMySelf];

    if ([myUser getUserID] == [userId intValue]) {
      _user = myUser;
    } else {
      NSArray<ZoomVideoSDKUser *>* remoteUsers = [[[ZoomVideoSDK shareInstance] getSession] getRemoteUsers];
      for (ZoomVideoSDKUser* user in remoteUsers) {
          if ([user getUserID] == [userId intValue]) {
            _user = user;
          }
      }
    }
    return _user;
}

RCT_EXPORT_MODULE()

RCT_EXPORT_METHOD(getUserName:(NSString *)userId
                  withResolve:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
    if (user != nil) {
        resolve([user getUserName]);
    }
  });
}

RCT_EXPORT_METHOD(isHost:(NSString *)userId
                  withResolve:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
    if (user != nil) {
      resolve(@([user isHost]));
    }
  });
}
RCT_EXPORT_METHOD(isManager:(NSString *)userId
                  withResolve:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
    if (user != nil) {
      resolve(@([user isManager]));
    }
  });
}

RCT_EXPORT_METHOD(getMultiCameraCanvasList:(NSString *)userId
                  withResolve:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
    if (user != nil) {
      resolve([user getMultiCameraCanvasList]);
    }
  });
}

RCT_EXPORT_METHOD(getUserVolume:(NSString *)userId
                  withIsSharingAudio: (BOOL) isSharingAudio
                  withResolve:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
    if (user != nil) {
      float volume;
      [user getUserVolume:&volume isShareAudio:isSharingAudio];
      resolve(@(volume));
    }
  });
}

RCT_EXPORT_METHOD(setUserVolume:(NSString *)userId
                  withVolume: (float) volume
                  isShareAudio: (BOOL) isSharingAudio
                  withResolve:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
    if (user != nil) {
      resolve(@([user setUserVolume: volume isShareAudio:isSharingAudio]));
    }
  });
}

RCT_EXPORT_METHOD(canSetUserVolume:(NSString *)userId
                  isShareAudio: (BOOL) isSharingAudio
                  withResolve:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
    if (user != nil) {
      resolve(@([user canSetUserVolume: isSharingAudio]));
    }
  });
}

RCT_EXPORT_METHOD(hasIndividualRecordingConsent:(NSString *)userId
                  withResolve:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
    if (user != nil) {
      resolve(@([user isIndividualRecordAgreed]));
    }
  });
}

RCT_EXPORT_METHOD(getUserReference:(NSString *)userId
        withResolve:(RCTPromiseResolveBlock)resolve
        withRejecter:(RCTPromiseRejectBlock)reject)
{
  dispatch_async(dispatch_get_main_queue(), ^{
    ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
    if (user != nil) {
      resolve([user getUserReference]);
    }
  });
}

RCT_EXPORT_METHOD(getShareActionList:(NSString *)userId
        withResolve:(RCTPromiseResolveBlock)resolve
        withRejecter:(RCTPromiseRejectBlock)reject)
{
    if ([userId length] == 0) {
        resolve([[RCTConvert ZoomVideoSDKErrorValuesReversed] objectForKey: @(Errors_Invalid_Parameter)]);
    }
    ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
    if (user != nil) {
        resolve([RNZoomVideoSdkShareAction mapShareActionArray:[user getShareActionList]]);
    } else {
        resolve([[RCTConvert ZoomVideoSDKErrorValuesReversed] objectForKey: @(Errors_Invalid_Parameter)]);
    }
}

RCT_EXPORT_METHOD(getWhiteboardStatus:(NSString *)userId
        withResolve:(RCTPromiseResolveBlock)resolve
        withRejecter:(RCTPromiseRejectBlock)reject)
{
    dispatch_async(dispatch_get_main_queue(), ^{
        ZoomVideoSDKUser *user = [RNZoomVideoSdkUser getUser:userId];
        if (user != nil) {
            ZoomVideoSDKWhiteboardStatus status = [user getWhiteboardStatus];
            resolve([[RCTConvert ZoomVideoSDKWhiteboardStatusValuesReversed] objectForKey: @(status)]);
        } else {
            reject(@"user_not_found", @"User not found", nil);
        }
    });
}

@end
