#import "HanselRn.h"
#import "UIView+React.h"
#import <React/RCTBridge.h>

@implementation HanselRn

- (void)getInteractionMaps:(RCTResponseSenderBlock)callback {
    @try {
        [HanselRnUtils returnResult:[Hansel getMaps] withCallback:callback];
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in getMaps method in HanselRn bridge.");
    }
}

- (void)setAppFont:(NSString* _Nonnull)fontFamily {
    @try {
        [Hansel setAppFont:fontFamily];
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in setAppFont method in HanselRn bridge.");
    }
}

- (void)onSetScreen:(NSString*)screenName {
    @try {
        dispatch_async(dispatch_get_main_queue(), ^{
            [Hansel setScreen:screenName];
        });
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in setScreen method in HanselRn bridge.");
    }
}

- (NSString *)getNativeIDFromView:(UIView *)view {
    if (!view) return nil;
    
    NSString *nativeID = nil;
    
    // Direct nativeID property access (Old Architecture)
    if ([view respondsToSelector:@selector(nativeID)]) {
        @try {
            nativeID = [view nativeID];
            if (nativeID && ![nativeID isEqualToString:@""]) {
                return nativeID;
            }
        } @catch (NSException *exception) {
            NSLog(@"Exception accessing nativeID property: %@", exception);
        }
    }
    
    NSArray *possibleKeys = @[@"nativeID", @"nativeId", @"native_id"];
    for (NSString *key in possibleKeys) {
        @try {
            if ([view respondsToSelector:@selector(valueForKey:)]) {
                id value = [view valueForKey:key];
                if (value && [value isKindOfClass:[NSString class]]) {
                    nativeID = (NSString *)value;
                    if (nativeID && ![nativeID isEqualToString:@""]) {
                        return nativeID;
                    }
                }
            }
        } @catch (NSException *exception) {
            NSLog(@"Exception accessing nativeID property via KVC: %@", exception);
        }
    }
    
    return nil;
}

- (NSString *)getTestIDFromView:(UIView *)view {
    if (!view) return nil;
    NSString *testID = nil;
    @try {
        if ([view respondsToSelector:@selector(valueForKey:)]) {
            testID = [view valueForKey:@"testID"];
            if (testID && [testID isKindOfClass:[NSString class]] && ![testID isEqualToString:@""]) {
                // Extract the main part before "#" if it exists
                NSArray *components = [testID componentsSeparatedByString:@"#"];
                if ([components count] > 0) {
                    return components[0];
                }
                return testID;
            }
        }
    } @catch (NSException *exception) {
        NSLog(@"Exception while fetching testID: %@", exception);
    }
    
    return nil;
}

-(void)setHanselIgnoreViewTag:(UIView *)currentView parentsLayerCount:(int)parentsLayerCount andChildLayerIndex:(int)childLayerIndex {
    @try {
        UIView *ignoreView = nil;
        UIView *parentView = currentView;
        for (int i = 0; i <= parentsLayerCount; i++) {
            if (parentView == nil) {
                break;
            }
            
            NSArray *subviews = [parentView subviews];
        
            if (parentsLayerCount == i) {
                if (childLayerIndex < [subviews count]) {
                    ignoreView = [subviews objectAtIndex:childLayerIndex];
                }
            } else {
                if ([subviews count] > 0) {
                    parentView = [subviews objectAtIndex:0];
                } else {
                    break;
                }
            }
        }
        
        if (ignoreView != nil) {
            [ignoreView.layer setValue:@(YES) forKey:HANSEL_IGNORE_VIEW_IDENTIFIER];
        }
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in setting Ignore View Tag: %@", exception);
    }
}

-(void)setHanselIndexViewTag:(UIView *)currentView hanselIndex:(NSString *)hanselIndex andExtraLayers:(int)extraLayers {
    @try {
        UIView *dynamicView = currentView;
        
        for (int singleLayer = 0; singleLayer < extraLayers; singleLayer++) {
            UIView *parentView = [dynamicView superview];
            if (parentView != nil) {
                dynamicView = parentView;
            } else {
                dynamicView = nil;
                break;
            }
        }
        
        if (dynamicView != nil) {
            [Hansel setHanselIndexForView:dynamicView withIndex:hanselIndex];
        }
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in setting Index View Tag: %@", exception);
    }
}

-(void)searchNativeIDView:(NSArray *)subviews {
    @try {
        for (UIView *currentView in subviews) {
            if (currentView) {
                // Try to get nativeID using our universal method
                NSString *nativeID = [self getNativeIDFromView:currentView];
                
                if (nativeID != nil) {
                    
                    if ([nativeID isEqualToString:@"hansel_ignore_view_overlay"]) {
                        NSString *accessibilityId = [currentView accessibilityIdentifier];
                        NSLog(@"Processing ignore view overlay, accessibility: %@", accessibilityId);
                        
                        if (accessibilityId) {
                            NSArray *values = [accessibilityId componentsSeparatedByString:@"#"];
                            int parentsLayerCount = ([values count] > 0) ? [values[0] intValue] : 0;
                            int childLayerIndex = ([values count] > 1) ? [values[1] intValue] : 0;
                            
                            [self setHanselIgnoreViewTag:currentView parentsLayerCount:parentsLayerCount andChildLayerIndex:childLayerIndex];
                        }
                    }
                    else if ([nativeID isEqualToString:@"hansel_dynamic_view"]) {
                        NSString *accessibilityId = [currentView accessibilityIdentifier];
                        if (!accessibilityId) {
                            // Try to get from testID if accessibility is not set
                            NSString *testID = [self getTestIDFromView:currentView];
                            if (testID && [testID containsString:@"#"]) {
                                accessibilityId = testID;
                            }
                        }
                        
                        NSLog(@"🔧 Processing dynamic view, accessibility/testID: %@", accessibilityId);
                        
                        if (accessibilityId) {
                            NSArray *values = [accessibilityId componentsSeparatedByString:@"#"];
                            NSString *hanselIndex = ([values count] > 0) ? values[0] : @"";
                            int extraLayersCount = ([values count] > 1) ? [values[1] intValue] : 0;
                            
                            [self setHanselIndexViewTag:currentView hanselIndex:hanselIndex andExtraLayers:extraLayersCount];
                        }
                    }
                    else if ([nativeID isEqualToString:@"hansel_show_view"]) {
                        [currentView.layer setValue:@(NO) forKey:HANSEL_IGNORE_VIEW_IDENTIFIER];
                    }
                    else {
                        [currentView.layer setValue:@(YES) forKey:HANSEL_IGNORE_VIEW_IDENTIFIER];
                    }
                }
    
                // Continue recursive search
                [self searchNativeIDView:currentView.subviews];
            }
        }
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in searchNativeIDView: %@", exception);
    }
}

- (void)setNativeID {
    @try {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
            [self performSearch];
        });
        
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in setNativeID method: %@", exception);
    }
}

- (void)performSearch {
    @try {
        UIViewController *currentViewController = RCTPresentedViewController();
        if (currentViewController && currentViewController.view) {
            [self searchNativeIDView:currentViewController.view.subviews];
        } else {
            NSLog(@"No current view controller found");
        }
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception in performSearch: %@", exception);
    }
}

- (void)onUnsetScreen {
    @try {
        dispatch_async(dispatch_get_main_queue(), ^{
            [Hansel unSetScreen];
        });
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in unSetScreen method: %@", exception);
    }
}

- (void)enableDebugLogs {
    @try {
        [Hansel enableDebugLogs];
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in enableDebugLogs method: %@", exception);
    }
}

- (void)onBackButtonPressed:(RCTResponseSenderBlock)callback {
    @try {
        dispatch_async(dispatch_get_main_queue(), ^{
            [HanselRnUtils returnResult:[NSNumber numberWithBool:[Hansel onBackButtonPressed]] withCallback:callback];
        });
    } @catch (NSException *exception) {
        NSLog(@"Hansel error: Exception caught in onBackButtonPressed method: %@", exception);
    }
}

@end
