#import "VideoMerger.h"
#import <VideoSDK/ACFVideoMerger.h>
//#import "ACFVideoMerger.h"
#import <VideoSDK/ACFFileHelper.h>
//#import <SotVideoSDK/videoMerger.h>
#import <React/RCTConvert.h>

#ifdef RCT_NEW_ARCH_ENABLED
#import "RNVideoMergerSpec.h"
#endif

@implementation VideoMerger
{
    bool hasListeners;
}

RCT_EXPORT_MODULE()

-(void)startObserving {
    hasListeners = YES;
}

-(void)stopObserving {
    hasListeners = NO;
}

- (NSArray<NSString *> *)supportedEvents
{
    return @[@"RNVideoSDK:dataFromNative"];
}

- (void)sendDataToUI:(id)data
{
    if (!hasListeners) {
        return;
    }
    
    [self sendEventWithName:@"RNVideoSDK:dataFromNative" body:data];
}

// Example method
// See // https://reactnative.dev/docs/native-modules-ios
RCT_REMAP_METHOD(multiply,
                 multiplyWithA:(double)a withB:(double)b
                 withResolver:(RCTPromiseResolveBlock)resolve
                 withRejecter:(RCTPromiseRejectBlock)reject)
{
  NSNumber *result = @(a * b);

  resolve(result);
}


RCT_REMAP_METHOD(cleanCacheDir,
                 cleanCacheDirWithOption:(NSDictionary*)option
                 withResolver:(RCTPromiseResolveBlock)resolve
                 withRejecter:(RCTPromiseRejectBlock)reject)
{
    [[ACFVideoMerger sharedInstance] cleanCacheDir];
    resolve(@{});
}

RCT_REMAP_METHOD(mergeVideos,
                 mergeVideoForParams:(NSDictionary*)params
                 withResolver:(RCTPromiseResolveBlock)resolve
                 withRejecter:(RCTPromiseRejectBlock)reject)
{
    // get params from React Native
    NSArray *_urls = [params objectForKey:@"urls"];
    NSDictionary *_outputSize = [params objectForKey:@"outputSize"];
    NSNumber *_backgroundColor = [params valueForKey:@"backgroundColor"];
    // prepare params for SDK function
    NSMutableArray *urls = [[NSMutableArray alloc] init];
    for (int i = 0; i < _urls.count; i++) {
        NSString *urlString = [_urls objectAtIndex:i];
        [urls addObject:[NSURL fileURLWithPath:urlString]];
    }
    CGSize outputSize = CGSizeZero;
    if (_outputSize != nil) {
        NSNumber *width = [_outputSize valueForKey:@"width"];
        NSNumber *height = [_outputSize valueForKey:@"height"];
        if (width.doubleValue > 0 && height.doubleValue > 0) {
            outputSize = CGSizeMake(width.doubleValue, height.doubleValue);
        }
    }
    UIColor *backgroundColor = nil;
    if (_backgroundColor != nil) {
        backgroundColor = [RCTConvert UIColor:_backgroundColor];
    }
    
    NSLog(@"get merge video params, backgroundColor: %@", backgroundColor);
    __block BOOL hasBeenExecuteResolveOrRejectFunction = NO;
    
    [[ACFVideoMerger sharedInstance] mergeVideos:urls outputSize:outputSize backgroundColor:backgroundColor withBlock:^(ACFVideoMergeState state, NSString * _Nullable outputFilePath, float progress, int errorCode, NSString * _Nullable errorDescription) {
        // NSLog(@"outputFilePath: %@, progress:%f, errorCode: %d", outputFilePath, progress, errorCode);
        NSDictionary *data = @{
            @"outputFilePath": outputFilePath ? outputFilePath : @"",
            @"progress": @(progress),
            @"errorCode": @(errorCode),
            @"errorDescription": errorDescription ? errorDescription : @"",
        };
        [self sendDataToUI:data];
        
        // error
        if (errorCode > 0) {
            if (hasBeenExecuteResolveOrRejectFunction) {
                return;
            }
            hasBeenExecuteResolveOrRejectFunction = YES;
            NSError *error = [[NSError alloc] initWithDomain:@"react-native-video-sdk.sot.app" code:errorCode userInfo:data];
            reject(
                   [NSString stringWithFormat:@"%d", errorCode],
                   errorDescription,
                   error);
        }
        // success
        if (progress == 1) {
            if (hasBeenExecuteResolveOrRejectFunction) {
                return;
            }
            hasBeenExecuteResolveOrRejectFunction = YES;
            resolve(data);
        }
    }];
    /*
    NSString *pathForCacheDir = [ACFFileHelper getCacheDirPath];
    resolve(@{
        @"_urls": _urls,
        @"_outputSize": _outputSize,
        @"_backgroundCOlor": _backgroundColor,
        @"_cacheDir": pathForCacheDir,
    });
    */
}


// Don't compile this code when we build for the old architecture.
#ifdef RCT_NEW_ARCH_ENABLED
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
    (const facebook::react::ObjCTurboModule::InitParams &)params
{
    return std::make_shared<facebook::react::NativeVideoMergerSpecJSI>(params);
}
#endif

@end
