// LICENSE: see License.md in the package root


#import "RNDocumentPicker.h"

#import "RCTConvert+RNDocumentPicker.h"
// this header file is generated by Xcode: https://developer.apple.com/documentation/swift/importing-swift-into-objective-c
// if it cannot be found, try cleaning the build folder and Xcode derived data folder

// When using use_frameworks! :linkage => :static in Podfile
#if __has_include(<react_native_document_picker/react_native_document_picker-Swift.h>)
#import <react_native_document_picker/react_native_document_picker-Swift.h>
#else
#import "react_native_document_picker-Swift.h"
#endif

// for UIModalPresentationStyle conversion
// remove after https://github.com/facebook/react-native/commit/2d547a3252b328251e49dabfeec85f8d46c85411 is released
#import <React/RCTModalHostViewManager.h>

@interface RNDocumentPicker ()
@end

@implementation RNDocumentPicker {
  DocPicker *docPicker;
  DocSaver *docSaver;
}

- (instancetype)init {
  if ((self = [super init])) {
    docPicker = [DocPicker new];
    docSaver = [DocSaver new];
  }
  return self;
}

+ (BOOL)requiresMainQueueSetup {
  return NO;
}

RCT_EXPORT_MODULE()

RCT_EXPORT_METHOD(pick:
                  (NSDictionary *) options
                  resolve:
                  (RCTPromiseResolveBlock) resolve
                  reject:
                  (RCTPromiseRejectBlock) reject)
{
  // https://stackoverflow.com/questions/5270519/what-is-difference-between-uimodaltransitionstyle-and-uimodalpresentationstyle
  UIModalPresentationStyle presentationStyle = [RCTConvert UIModalPresentationStyle:options[@"presentationStyle"]];
  UIModalTransitionStyle transitionStyle = [RCTConvert UIModalTransitionStyle:options[@"transitionStyle"]];
  NSArray *allowedUTIs = [RCTConvert NSArray:options[@"type"]];
  BOOL allowMultiple = [RCTConvert BOOL:options[@"allowMultiSelection"]];
  BOOL showExtensions = [RCTConvert BOOL:options[@"showFileExtensions"]];
  NSString *mode = options[@"mode"];
  NSString *initialDir = options[@"initialDirectoryUrl"];
  BOOL requestLongTermAccess = [RCTConvert BOOL:options[@"requestLongTermAccess"]];
  
  PickerOptions *pickerOptions = [[PickerOptions alloc] initWithTypes:allowedUTIs
                                                                 mode:mode
                                                  initialDirectoryUrl:initialDir
                                                  allowMultiSelection:allowMultiple
                                             shouldShowFileExtensions:showExtensions
                                                      transitionStyle:transitionStyle
                                                    presentationStyle:presentationStyle
                                                requestLongTermAccess:requestLongTermAccess];
  
  [docPicker presentWithOptions:pickerOptions resolve:resolve reject:reject];
}

RCT_EXPORT_METHOD(pickDirectory:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
  void (^resolveWithDirectoryUri)(NSArray<NSDictionary *> *) = ^void(NSArray<NSDictionary *> *pickedValues) {
    NSDictionary* firstObject = pickedValues.firstObject;
    resolve(firstObject);
  };
  
  [self pick:options resolve:resolveWithDirectoryUri reject:reject];
}

RCT_EXPORT_METHOD(keepLocalCopy:
                  (NSDictionary *) options
                  resolve:
                  (RCTPromiseResolveBlock) resolve
                  reject:
                  (RCTPromiseRejectBlock) reject) {
  NSArray *uris = options[@"files"];
  NSString *destination = options[@"destination"];
  
  [[FileOperations class] keepLocalCopyAtUniqueDestinationFrom:uris destinationPreset:destination resolve:resolve];
}

RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, isKnownType:(NSString *)kind value:(NSString *)value) {
  NSDictionary* result = [[IsKnownTypeImpl class] checkType:kind value:value];
  return result;
}

RCT_EXPORT_METHOD(writeDocuments:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
  UIModalPresentationStyle presentationStyle = [RCTConvert UIModalPresentationStyle:options[@"presentationStyle"]];
  UIModalTransitionStyle transitionStyle = [RCTConvert UIModalTransitionStyle:options[@"transitionStyle"]];
  BOOL showExtensions = [RCTConvert BOOL:options[@"showFileExtensions"]];
  BOOL asCopy = [RCTConvert BOOL:options[@"copy"]];

  NSString *initialDir = options[@"initialDirectoryUri"];
  NSArray<NSString*> *documentUrl = options[@"sourceUris"];
  
  SaverOptions* saverOptions = [[SaverOptions alloc] initWithSourceUrlStrings:documentUrl asCopy:asCopy initialDirectoryUrl:initialDir shouldShowFileExtensions:showExtensions transitionStyle:transitionStyle presentationStyle:presentationStyle];
  
  [docSaver presentWithOptions:saverOptions resolve:resolve reject:reject];
}

RCT_EXPORT_METHOD(releaseSecureAccess:(NSArray *)uris resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
  [docPicker stopAccessingOpenedUrls:uris];
  resolve([NSNull null]);
}

RCT_EXPORT_METHOD(releaseLongTermAccess:(NSArray *)uris resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
  resolve([NSNull null]);
}

// Thanks to this guard, we won't compile this code when we build for the old architecture.
#ifdef RCT_NEW_ARCH_ENABLED

- (void)saveDocument:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
  // not needed on iOS
}

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

#endif

@end
