#import <React/RCTBridgeModule.h>

#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTBridge+Private.h>
#import <React/RCTUtils.h>
#import <ReactCommon/RCTTurboModule.h>
#import "PortalMobileMpcSpec.h"
#endif

@interface RCT_EXTERN_MODULE(PortalMobileMpc, NSObject)

// MARK: - Generate Methods

RCT_EXTERN_METHOD(generate:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  apiHost:(NSString *)apiHost
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(generateEd25519:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  apiHost:(NSString *)apiHost
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(generateSecp256k1:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  apiHost:(NSString *)apiHost
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

// MARK: - Sign Method

RCT_EXTERN_METHOD(sign:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  dkgResult:(NSString *)dkgResult
                  method:(NSString *)method
                  params:(NSString *)params
                  rpcUrl:(NSString *)rpcUrl
                  chainId:(NSString *)chainId
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(presign:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  share:(NSString *)share
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(signWithPresignature:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  share:(NSString *)share
                  presignature:(NSString *)presignature
                  method:(NSString *)method
                  params:(NSString *)params
                  rpcUrl:(NSString *)rpcUrl
                  chainId:(NSString *)chainId
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

// MARK: - Backup Methods

RCT_EXTERN_METHOD(backup:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  dkgResult:(NSString *)dkgResult
                  apiHost:(NSString *)apiHost
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(backupEd25519:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  dkgResult:(NSString *)dkgResult
                  apiHost:(NSString *)apiHost
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(backupSecp256k1:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  dkgResult:(NSString *)dkgResult
                  apiHost:(NSString *)apiHost
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

// MARK: - Recover Methods

RCT_EXTERN_METHOD(recoverSigning:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  dkgResult:(NSString *)dkgResult
                  apiHost:(NSString *)apiHost
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(recoverSigningSecp256k1:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  dkgResult:(NSString *)dkgResult
                  apiHost:(NSString *)apiHost
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(recoverSigningEd25519:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  dkgResult:(NSString *)dkgResult
                  apiHost:(NSString *)apiHost
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(recoverBackup:(NSString *)clientApiKey
                  addr:(NSString *)addr
                  dkgResult:(NSString *)dkgResult
                  apiHost:(NSString *)apiHost
                  metadata:(NSString *)metadata
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

// MARK: - Encryption Methods

RCT_EXTERN_METHOD(encrypt:(NSString *)data
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(decrypt:(NSString *)key
                  cipherText:(NSString *)cipherText
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(encryptWithPassword:(NSString *)data
                  password:(NSString *)password
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(decryptWithPassword:(NSString *)key
                  cipherText:(NSString *)cipherText
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

// MARK: - Eject Methods

RCT_EXTERN_METHOD(ejectSecp256k1:(NSString *)dkgResultOne
                  dkgResultTwo:(NSString *)dkgResultTwo
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(ejectEd25519:(NSString *)dkgResultOne
                  dkgResultTwo:(NSString *)dkgResultTwo
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

// MARK: - Utility Methods

RCT_EXTERN_METHOD(formatShares:(NSString *)shares
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(getCustodianIdClientIdHashes:(NSString *)custodianIdClientIdJson
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)

@end

#ifdef RCT_NEW_ARCH_ENABLED
@interface PortalMobileMpc (TurboModule) <RCTTurboModule>
@end

@implementation PortalMobileMpc (TurboModule)

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
    (const facebook::react::ObjCTurboModule::InitParams &)params {
  return std::make_shared<facebook::react::NativePortalMobileMpcSpecJSI>(params);
}

@end
#endif
