#import "RNZoomWhiteboardView.h"
#import <React/RCTConvert.h>
#import <React/RCTUtils.h>
#import "RCTConvert+RNZoomVideoSdk.h"

static RNZoomWhiteboardView* sharedInstance = nil;

@implementation RNZoomWhiteboardView

+ (instancetype)sharedInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[RNZoomWhiteboardView alloc] init];
    });
    return sharedInstance;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor clearColor];
        hasSubscribed = NO;
        isDisplayLinkActive = NO;
        displayLink = nil;
    }
    return self;
}

- (instancetype)init {
    return [self initWithFrame:CGRectZero];
}

- (UIViewController *)findViewController {
    UIResponder *responder = self;
    while (responder) {
        responder = responder.nextResponder;
        if ([responder isKindOfClass:[UIViewController class]]) {
            return (UIViewController *)responder;
        }
    }
    return RCTPresentedViewController();
}

- (void)willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];
    if (newSuperview == nil) {
        [self hideOptionsButton];
        [self unsubscribeWhiteboard];
    }
}

- (void)didMoveToSuperview {
    [super didMoveToSuperview];
    if (self.superview != nil) {
        hasSubscribed = NO;
        [self setNeedsLayout];
        [self layoutIfNeeded];
    }
}

- (void)didMoveToWindow {
    [super didMoveToWindow];
    if (self.window != nil) {
        hasSubscribed = NO;
        [self setNeedsLayout];
        [self layoutIfNeeded];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self setNeedsLayout];
            [self layoutIfNeeded];
            if (!hasSubscribed && self.superview != nil && self.bounds.size.width > 0 && self.bounds.size.height > 0) {
                [self subscribeWhiteboard];
            }
        });
    }
}

- (void)subscribeWhiteboard {
    if (![NSThread isMainThread]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self subscribeWhiteboard];
        });
        return;
    }

    @try {
        if (self.superview == nil) {
            NSLog(@"Whiteboard: view is not in the view hierarchy yet");
            hasSubscribed = NO; // Reset flag so we can try again later
            return;
        }

        ZoomVideoSDKWhiteboardHelper* whiteboardHelper = [[ZoomVideoSDK shareInstance] getWhiteboardHelper];
        if (whiteboardHelper == nil) {
            NSLog(@"Whiteboard: whiteboardHelper is nil");
            hasSubscribed = NO; // Reset flag so we can try again later
            return;
        }

        BOOL isOtherSharing = [whiteboardHelper isOtherSharingWhiteboard];
        BOOL canStop = [whiteboardHelper canStopShareWhiteboard];
        BOOL isWhiteboardActive = isOtherSharing || canStop;

        if (!isWhiteboardActive) {
            NSLog(@"Whiteboard: No one is sharing whiteboard yet, waiting... (isOtherSharing: %d, canStop: %d)", isOtherSharing, canStop);
            hasSubscribed = NO; // Reset flag so we can try again when whiteboard starts
            return;
        }

        if (self.bounds.size.width == 0 || self.bounds.size.height == 0) {
            NSLog(@"Whiteboard: view has zero size, waiting for layout. Current bounds: %@", NSStringFromCGRect(self.bounds));
            hasSubscribed = NO; // Reset flag so we can try again when layout happens
            // Force layout update
            [self setNeedsLayout];
            [self layoutIfNeeded];
            return;
        }

        UIViewController *viewController = [self findViewController];
        if (viewController == nil) {
            NSLog(@"Whiteboard: Could not find view controller");
            hasSubscribed = NO;
            return;
        }

        ZoomVideoSDKError error = [whiteboardHelper subscribeWhiteboard:viewController];
        if (error != Errors_Success) {
            NSLog(@"Whiteboard: subscribeWhiteboard failed with error: %@", [[RCTConvert ZoomVideoSDKErrorValuesReversed] objectForKey: @(error)]);
            hasSubscribed = NO;
        } else {
            ZoomVideoSDKSession *session = [[ZoomVideoSDK shareInstance] getSession];
            if (session == nil) {
                return;
            }
            ZoomVideoSDKUser *myself = [session getMySelf];
            if (myself == nil) {
                return;
            }
            hasSubscribed = YES;

            if ([myself isHost]) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [self showOptionsButton];
                });
            }
        }
    } @catch (NSException *e) {
        NSLog(@"Whiteboard: Exception in subscribeWhiteboard: %@ - %@", e.name, e.reason);
        hasSubscribed = NO;
    }
}

- (void)unsubscribeWhiteboard {
    if (![NSThread isMainThread]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self unsubscribeWhiteboard];
        });
        return;
    }

    [self hideOptionsButton];

    @try {
        ZoomVideoSDKWhiteboardHelper* whiteboardHelper = [[ZoomVideoSDK shareInstance] getWhiteboardHelper];
        if (whiteboardHelper == nil) {
            hasSubscribed = NO;
            return;
        }

        [whiteboardHelper unSubscribeWhiteboard];
        hasSubscribed = NO;

    } @catch (NSException *e) {
        NSLog(@"Whiteboard: Exception in unsubscribeWhiteboard: %@ - %@", e.name, e.reason);
        hasSubscribed = NO;
    }
}

- (void)layoutSubviews {
    [super layoutSubviews];

    if (self.bounds.size.width > 0 && self.bounds.size.height > 0) {
        for (UIView* subview in self.subviews) {
            if (subview.frame.size.width == 0 || subview.frame.size.height == 0) {
                subview.frame = self.bounds;
                [subview setNeedsLayout];
                [subview layoutIfNeeded];
            }
        }
    }

    if (self.superview != nil && self.bounds.size.width > 0 && self.bounds.size.height > 0 && !hasSubscribed) {
        [self subscribeWhiteboard];
    }

}

- (void)handleDisplayLink:(CADisplayLink*)link {
    if (!isDisplayLinkActive) {
        return;
    }

    if (self.bounds.size.width > 0 && self.bounds.size.height > 0) {
        for (UIView* subview in self.subviews) {
            if (subview.frame.size.width == 0 || subview.frame.size.height == 0) {
                subview.frame = self.bounds;
                [subview setNeedsLayout];
                [subview layoutIfNeeded];
            }
        }
    }

}

- (void)showOptionsButton {
    if (optionsButton != nil) {
        return; // Button already exists
    }

    UIWindow* window = self.window;
    if (window == nil) {
        window = [UIApplication sharedApplication].keyWindow;
    }

    if (window == nil) {
        NSLog(@"Whiteboard: No window found to add options button");
        return;
    }

    UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero;
    if (@available(iOS 11.0, *)) {
        safeAreaInsets = window.safeAreaInsets;
    }

    optionsButton = [UIButton buttonWithType:UIButtonTypeCustom];
    CGFloat buttonX = window.bounds.size.width - 64;
    CGFloat buttonY = 150 + safeAreaInsets.top;
    optionsButton.frame = CGRectMake(buttonX, buttonY, 44, 44);
    optionsButton.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.75];
    optionsButton.layer.cornerRadius = 22;
    optionsButton.layer.shadowColor = [UIColor blackColor].CGColor;
    optionsButton.layer.shadowOffset = CGSizeMake(0, 2);
    optionsButton.layer.shadowOpacity = 0.25;
    optionsButton.layer.shadowRadius = 3.84;

    [optionsButton setTitle:@"⋮" forState:UIControlStateNormal];
    [optionsButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    optionsButton.titleLabel.font = [UIFont boldSystemFontOfSize:24];

    [optionsButton addTarget:self action:@selector(onOptionsButtonTapped:) forControlEvents:UIControlEventTouchUpInside];

    optionsButton.clipsToBounds = NO;

    [window addSubview:optionsButton];
    optionsButton.layer.zPosition = 1000;
    [window bringSubviewToFront:optionsButton];
}

- (void)hideOptionsButton {
    if (optionsButton != nil) {
        [optionsButton removeFromSuperview];
        optionsButton = nil;
    }
}

- (void)onOptionsButtonTapped:(UIButton*)sender {
    UIViewController* viewController = [self findViewController];
    if (viewController == nil) {
        viewController = RCTPresentedViewController();
    }

    if (viewController == nil) {
        NSLog(@"Whiteboard: No view controller found for action sheet");
        return;
    }

    UIAlertController* alertController = [UIAlertController alertControllerWithTitle:nil
                                                                             message:nil
                                                                      preferredStyle:UIAlertControllerStyleActionSheet];

    UIAlertAction* stopAction = [UIAlertAction actionWithTitle:@"Stop Whiteboard"
                                                         style:UIAlertActionStyleDefault
                                                       handler:^(UIAlertAction * action) {
                                                           dispatch_async(dispatch_get_main_queue(), ^{
                                                               ZoomVideoSDKWhiteboardHelper* whiteboardHelper = [[ZoomVideoSDK shareInstance] getWhiteboardHelper];
                                                               if (whiteboardHelper != nil) {
                                                                   [whiteboardHelper stopShareWhiteboard];
                                                               }
                                                           });
                                                       }];

    UIAlertAction* exportAction = [UIAlertAction actionWithTitle:@"Export Whiteboard"
                                                           style:UIAlertActionStyleDefault
                                                         handler:^(UIAlertAction * action) {
                                                             dispatch_async(dispatch_get_main_queue(), ^{
                                                                 ZoomVideoSDKWhiteboardHelper* whiteboardHelper = [[ZoomVideoSDK shareInstance] getWhiteboardHelper];
                                                                 if (whiteboardHelper != nil) {
                                                                     [whiteboardHelper exportWhiteboard:ZoomVideoSDKWhiteboardExport_Format_PDF];
                                                                 }
                                                             });
                                                         }];

    UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
                                                           style:UIAlertActionStyleCancel
                                                         handler:nil];

    [alertController addAction:stopAction];
    [alertController addAction:exportAction];
    [alertController addAction:cancelAction];

    // For iPad, set popover presentation
    if (alertController.popoverPresentationController != nil) {
        alertController.popoverPresentationController.sourceView = sender;
        alertController.popoverPresentationController.sourceRect = sender.bounds;
    }

    [viewController presentViewController:alertController animated:YES completion:nil];
}

- (void)dealloc {
    [self hideOptionsButton];
    [self unsubscribeWhiteboard];
}

@end
