#import "InstantpayDeviceAuth.h"
#import <LocalAuthentication/LocalAuthentication.h>

@implementation InstantpayDeviceAuth
RCT_EXPORT_MODULE()

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

- (void)openBiometricAuthenticatePrompt:(NSString * _Nullable)params resolve:(nonnull RCTPromiseResolveBlock)resolve reject:(nonnull RCTPromiseRejectBlock)reject {
    
    // Create a new instance of LAContext for biometric authentication
    LAContext *context = [[LAContext alloc] init];
    NSError *error = nil;
    NSString *SUCCESS = @"Success";
    NSString *FAILED = @"Failed";
    NSString *DATA = @"";
    NSString *ACTCODE = @"";
    NSString *titleObjectError = @"Pass title and subtitle object as arguement using JSON.stringify in  openBiometricAuthenticatePrompt(JSON.stringify(titleObj)) method. You can also pass empty object in  openBiometricAuthenticatePrompt(JSON.stringify({})) method";

    NSString *title = @"";
    NSData *jsonData = [params dataUsingEncoding:NSUTF8StringEncoding];
    NSError *errorTitle;
    NSMutableDictionary *data = [NSJSONSerialization JSONObjectWithData:jsonData
                                                       options:NSJSONReadingAllowFragments
                                                         error:&errorTitle];
    
    if (errorTitle) {
            
            NSDictionary *result = @{
              @"status": FAILED,
              @"message": titleObjectError,
              @"data": DATA,
              @"actCode": ACTCODE
            };
            return resolve(result);
            
        } else {
            if([data objectForKey:@"title"]) {
                title = data[@"title"];
            }else{
                title = @"Unlock";
            }
        }
        
        // Check is Sensor available or not
        BOOL canEvaluatePolicy = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error];

        // If Sensor available
        if (canEvaluatePolicy) {

          // Check if the device supports biometric authentication
          if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error]) {

              // Check if the available biometric on the device is Face ID
              if (context.biometryType == LABiometryTypeFaceID) {
                  // Start the authentication process with Face ID
                  [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication
                          localizedReason:title
                                    reply:^(BOOL success, NSError *error) {
                      if (success) {
                          // Authentication successful
                          NSString *biometricMessage = @"Authentication Success";
                              NSDictionary *result = @{
                                @"status": SUCCESS,
                                @"message": biometricMessage,
                                @"data": DATA,
                                @"actCode": ACTCODE
                              };
                          
                          resolve(result);
                      } else {
                          // Authentication failed
                          NSString *biometricMessage = @"Authentication Failed";
                              NSDictionary *result = @{
                                @"status": FAILED,
                                @"message": biometricMessage,
                                @"data": DATA,
                                @"actCode": ACTCODE
                              };
                          
                          resolve(result);
                      }
                  }];
              }
              else if(context.biometryType == LABiometryTypeTouchID){
                // Start the authentication process with Touch ID
                [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication
                        localizedReason:title
                                  reply:^(BOOL success, NSError *error) {
                    if (success) {
                        // Authentication successful
                        NSString *biometricMessage = @"Authentication Success";
                            NSDictionary *result = @{
                              @"status": SUCCESS,
                              @"message": biometricMessage,
                              @"data": DATA,
                              @"actCode": ACTCODE
                            };
                        
                        resolve(result);
                      } else {
                          // Authentication failed
                          NSString *biometricMessage = @"Authentication Failed";
                              NSDictionary *result = @{
                                @"status": FAILED,
                                @"message": biometricMessage,
                                @"data": DATA,
                                @"actCode": ACTCODE
                              };
                          
                          resolve(result);
                      }
                }];
              }
              else {
                // Start the authentication process with Touch ID
                [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication
                        localizedReason:title
                                  reply:^(BOOL success, NSError *error) {
                    if (success) {
                          // Authentication successful
                        NSString *biometricMessage = @"Authentication Success";
                            NSDictionary *result = @{
                              @"status": SUCCESS,
                              @"message": biometricMessage,
                              @"data": DATA,
                              @"actCode": ACTCODE
                            };
                        
                        resolve(result);
                      } else {
                          // Authentication failed
                          NSString *biometricMessage = @"Authentication Failed";
                              NSDictionary *result = @{
                                @"status": FAILED,
                                @"message": biometricMessage,
                                @"data": DATA,
                                @"actCode": ACTCODE
                              };
                          
                          resolve(result);
                      }
                }];
              }
          } else {
              // Biometric authentication is not available on this device
              NSString *biometricMessage = @"Biometric features not enrolled";
                  NSDictionary *result = @{
                    @"status": SUCCESS,
                    @"message": biometricMessage,
                    @"data": DATA,
                    @"actCode": ACTCODE
                  };
              
              resolve(result);
          }
          
        } else {
          // If Sensor not available
          NSString *errorMessage = [NSString stringWithFormat:@"%@", error];
          NSDictionary *result = @{
            @"status": FAILED,
            @"message": errorMessage,
            @"data": DATA,
            @"actCode": ACTCODE
          };

          resolve(result);
        }
}

@end
