#import "RNScanbotSDK.h"

@import ScanbotSDKNativeWrapper;


@implementation RNScanbotSDK

RCT_EXPORT_MODULE(RNScanbotSDK);

// MARK: SDK Operations

RCT_EXPORT_METHOD(initializeSDK:(NSDictionary *)options
                  success:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
  [SBDWrapper initializeSDKWithConfiguration:options resultDelegate:delegate framework: SBDFrameworkRnCap];
}

RCT_EXPORT_METHOD(getLicenseInfo:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDWrapper getLicenseInfoWithResultDelegate:delegate];
}

RCT_EXPORT_METHOD(getOCRConfigs:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDWrapper getOCRConfigsWithResultDelegate:delegate];
}

RCT_EXPORT_METHOD(cleanup:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDWrapper cleanupWithResultDelegate:delegate];
}


// MARK: PDF Processing
RCT_EXPORT_METHOD(extractPagesFromPdf:(NSDictionary*)configuration
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)
{
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDPDFExtractor extractPagesFromPdfWithOperationConfig:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(extractImagesFromPdf:(NSDictionary*)configuration
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)
{
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDPDFExtractor extractImagesFromPdfWithOperationConfig:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(createPDF:(NSDictionary *)args
                  success:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDImageOperations createPDFWithOperationConfig:args resultDelegate:delegate];
}


// MARK: Filters
RCT_EXPORT_METHOD(applyImageFilters:(NSString *)imageFileUri
                  filter:(NSArray<NSDictionary *> *)filter
                  success:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDImageOperations applyImageFilterWithImageFileUri:imageFileUri parametricFilters:filter resultDelegate:delegate];
}

RCT_EXPORT_METHOD(applyImageFiltersOnPage:(NSDictionary*)pageDict
                  filter:(NSArray<NSDictionary *> *)filter
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDPageOperations applyImageFilterOnPageWithPageDict:pageDict parametricFilters:filter delegate:delegate];
}


// MARK: Image Processing
RCT_EXPORT_METHOD(rotateImage:(NSString *)imageFileUri
                  degrees:(nonnull NSNumber *)degrees
                  success:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDImageOperations rotateImageWithImageFileUri:imageFileUri degrees:[degrees doubleValue] resultDelegate:delegate];
}

RCT_EXPORT_METHOD(documentQualityAnalyzer:(NSDictionary*)args
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDImageOperations documentQualityAnalyzerWithOperationConfig:args resultDelegate:delegate];
}

RCT_EXPORT_METHOD(getImageData:(NSString *)imageFileUri
                  success:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDImageOperations getImageDataWithImageFilePath:imageFileUri resultDelegate:delegate];
}

RCT_EXPORT_METHOD(performOCR:(NSDictionary *)args
                  success:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDRecognizers performOCRWithOperationConfig:args resultDelegate:delegate];
}

RCT_EXPORT_METHOD(writeTIFF:(NSDictionary *)args
                  success:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDImageOperations writeTIFFWithOperationConfig:args resultDelegate:delegate];
}


// MARK: Detection
RCT_EXPORT_METHOD(detectDocument:(nonnull NSString *)imageFileUri
                  success:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDRecognizers detectDocumentWithImageFilePath:imageFileUri resultDelegate:delegate];
}

RCT_EXPORT_METHOD(detectDocumentOnPage:(NSDictionary*)pageDict
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDPageOperations detectDocumentOnPageWithPageDict:pageDict resultDelegate:delegate];
}

RCT_EXPORT_METHOD(recognizeMrz:(nonnull NSString *)imageFileUri
                  success:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDRecognizers recognizeMrzWithImageFilePath:imageFileUri resultDelegate:delegate];
}

RCT_EXPORT_METHOD(recognizeCheck:(NSDictionary*)args
                  success:(RCTPromiseResolveBlock)resolve
                  failure:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDRecognizers recognizeCheckOnImageWithOptions:args resultDelegate:delegate];
}

RCT_EXPORT_METHOD(detectBarcodesOnImage:(NSDictionary *)configuration
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)
{
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDRecognizers detectBarcodesWithOptions:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(recognizeMedicalCertificate:(NSDictionary *)configuration
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)
{
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDRecognizers recognizeMedicalCertificateWithOptions:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(recognizeEHIC:(nonnull NSString *)imageFileUri
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)
{
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDRecognizers recognizeEHICWithImageFilePath:imageFileUri resultDelegate:delegate];
}

RCT_EXPORT_METHOD(recognizeGenericDocument:(NSDictionary *)configuration
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)
{
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDRecognizers recognizeGenericDocumentWithOptions:configuration resultDelegate:delegate];
}


// MARK: Page Processing
RCT_EXPORT_METHOD(createPage:(NSString*)imageFileUri
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDPageOperations createPageWithImageFileUri:imageFileUri resultDelegate:delegate];
}

RCT_EXPORT_METHOD(removePage:(NSDictionary*)pageDict
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDPageOperations removePageWithPageDict:pageDict resultDelegate:delegate];
}

RCT_EXPORT_METHOD(rotatePage:(NSDictionary*)pageDict
                  times:(nonnull NSNumber *)times
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDPageOperations rotatePageWithPageDict:pageDict times:[times intValue] resultDelegate:delegate];
}

RCT_EXPORT_METHOD(refreshImageUris:(NSDictionary *)configuration
                  resolve:(RCTPromiseResolveBlock)resolve
                  reject:(RCTPromiseRejectBlock)reject)
{
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDPageOperations refreshImageUrisWithOperationConfig:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(setDocumentImage:(NSDictionary*)pageDict
                  imageFileUri:(NSString*)imageFileUri
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject) {
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDPageOperations setDocumentImageWithPageDict:pageDict imageFileUri:imageFileUri resultDelegate:delegate];
}

// MARK: Document V2
RCT_EXPORT_METHOD(createDocument:(NSDictionary*)config
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations createScannedDocumentWithOperationConfiguration:config resultDelegate:delegate];
}

RCT_EXPORT_METHOD(createDocumentFromLegacyPages:(NSDictionary*)config
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations documentFromLegacyPagesWithOperationConfiguration:config resultDelegate:delegate];
}
    
RCT_EXPORT_METHOD(documentExists:(NSString *)documentID
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations documentExistsWithDocumentID:documentID resultDelegate:delegate];
}

RCT_EXPORT_METHOD(loadDocument:(NSString *)documentID
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations loadDocumentWithDocumentID:documentID resultDelegate:delegate];
}

RCT_EXPORT_METHOD(storedDocumentIDs:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations storedDocumentIDsWithResultDelegate:delegate];
}

RCT_EXPORT_METHOD(cloneDocument:(NSString *)documentID
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations cloneDocumentWithDocumentID:documentID resultDelegate:delegate];
}

RCT_EXPORT_METHOD(deleteDocument:(NSString *)documentID
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations deleteDocumentWithDocumentID:documentID resultDelegate:delegate];
}

RCT_EXPORT_METHOD(createPDFForDocument:(NSDictionary *)configuration
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations createPDFWithOperationConfiguration:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(createTIFFForDocument:(NSDictionary *)configuration
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations createTIFFWithOperationConfiguration:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(addPage:(NSDictionary *)configuration
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations addPageWithOperationConfiguration:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(movePage:(NSDictionary *)configuration
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations movePageWithOperationConfiguration:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(modifyPage:(NSDictionary *)configuration
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations modifyPageWithOperationConfiguration:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(removePageFromDocument:(NSDictionary *)configuration
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations removePageWithOperationConfiguration:configuration resultDelegate:delegate];
}

RCT_EXPORT_METHOD(removeAllPages:(NSString *)documentID
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations removeAllPagesWithDocumentID:documentID resultDelegate:delegate];
}

RCT_EXPORT_METHOD(createDocumentFromPDF:(NSString *)pdfUri
                  withResolver:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations createDocumentFromPDFWithPdfURL:pdfUri resultDelegate:delegate];
}

RCT_EXPORT_METHOD(deleteAllDocuments:(RCTPromiseResolveBlock)resolve
                  withRejecter:(RCTPromiseRejectBlock)reject){
    RNProxyDelegate* delegate = [[RNProxyDelegate alloc] initWithResolveBlock:resolve andRejectBlock:reject];
    [SBDDocumentOperations deleteAllDocumentsWithResultDelegate:delegate];
}


@end
