#import <ZoomVideoSDK/ZoomVideoSDK.h>
#import "RNZoomView.h"
#import "RNZoomVideoSdkUser.h"
#import "RNZoomVideoSdkAnnotationHelper.h"
#import "RCTConvert+RNZoomVideoSdk.h"
#import "SDKPiPHelper.h"
#import "SDKCallKitManager.h"

@implementation RNZoomView {
    NSString* userId;
    BOOL sharing;
    BOOL preview;
    BOOL hasMultiCamera;
    BOOL isPiPView;
    NSString* multiCameraIndex;
    ZoomVideoSDKVideoAspect videoAspect;
    ZoomVideoSDKVideoResolution videoResolution;
    ZoomVideoSDKVideoCanvas* currentCanvas;
    NSString* currentUserId;
    BOOL needsUpdateCanvas;
    BOOL isAttachedToWindow;
    NSInteger subscribeRetryCount;
}

- (instancetype)init {
    if (self = [super init]) {
        needsUpdateCanvas = YES;
        isAttachedToWindow = NO;
        subscribeRetryCount = 0;
    }
    return self;
}

- (void)willMoveToSuperview:(UIView *)newSuperview {
    [super willMoveToSuperview:newSuperview];
    if (newSuperview == nil) {
        // View is being removed from superview, immediately clean up
        isAttachedToWindow = NO;
        [self cleanupCanvas];
    } else {
        isAttachedToWindow = YES;
        needsUpdateCanvas = YES;
    }
}

- (void)didMoveToSuperview {
    [super didMoveToSuperview];
    if (self.superview != nil) {
        // View was added to superview, update canvas if needed
        if (needsUpdateCanvas) {
            [self setViewingCanvas];
            needsUpdateCanvas = NO;
        }
    }
}

- (void)layoutSubviews {
    [super layoutSubviews];
    // Only update canvas if view is attached and we have valid dimensions
    if (isAttachedToWindow && self.superview != nil && self.bounds.size.width > 0 && self.bounds.size.height > 0) {
        if (needsUpdateCanvas) {
            [self setViewingCanvas];
            needsUpdateCanvas = NO;
        }
    }
}

- (void)cleanupCanvas {
    if (currentCanvas != nil) {
        [currentCanvas unSubscribeWithView:self];
        currentCanvas = nil;
    }
    currentUserId = nil;
    subscribeRetryCount = 0;
}

- (void)setUserId:(NSString*)newUserId {
    if ([userId isEqualToString:newUserId]) {
        return;
    }
    userId = newUserId;
    needsUpdateCanvas = YES;
    [self setNeedsLayout];
}

- (void)setSharing:(BOOL)newSharing {
    if (sharing == newSharing) {
        return;
    }
    sharing = newSharing;
    needsUpdateCanvas = YES;
    [self setNeedsLayout];
}

- (void)setVideoAspect:(NSString*)newVideoAspect {
    ZoomVideoSDKVideoAspect aspect = [RCTConvert ZoomVideoSDKVideoAspect: newVideoAspect];
    if (videoAspect == aspect) {
        return;
    }
    videoAspect = aspect;
    needsUpdateCanvas = YES;
    [self setNeedsLayout];
}

- (void)setVideoResolution:(NSString*)newVideoResolution {
    ZoomVideoSDKVideoResolution resolution = [RCTConvert ZoomVideoSDKVideoResolution: newVideoResolution];
    if (videoResolution == resolution) {
        return;
    }
    videoResolution = resolution;
    needsUpdateCanvas = YES;
    [self setNeedsLayout];
}

- (void)setIsPiPView:(BOOL)newIsPiPView {
    if (isPiPView == newIsPiPView) {
        return;
    }
    if (newIsPiPView) {
        [[SDKCallKitManager sharedManager] startCallWithHandle:@"testemail@zoom.us" complete:^{
            [[SDKPiPHelper shared] presetPiPWithSrcView:self];
        }];
        [[SDKPiPHelper shared] presetPiPWithSrcView:self];
    } else {
        [[SDKPiPHelper shared] cleanUpPictureInPicture];
    }
    isPiPView = newIsPiPView;
    [self setNeedsLayout];
}

- (void)setHasMultiCamera:(BOOL)newHasMultiCamera {
    if (hasMultiCamera == newHasMultiCamera) {
        return;
    }
    hasMultiCamera = newHasMultiCamera;
}

- (void)setMultCameraIndex:(NSString*)newIndex {
    if (multiCameraIndex == newIndex) {
        return;
    }
    multiCameraIndex = newIndex;
    needsUpdateCanvas = YES;
    [self setNeedsLayout];
}

- (void)setPreview:(BOOL)newPreview {
    if (preview == newPreview) {
        return;
    }
    preview = newPreview;

    ZoomVideoSDKVideoHelper* videoHelper = [[ZoomVideoSDK shareInstance] getVideoHelper];
    if (preview == YES && currentCanvas == nil) {
        [videoHelper startVideoCanvasPreview: self andAspectMode: videoAspect];
    } else {
        [videoHelper stopVideoCanvasPreview: self];
    }
}

- (void)dealloc {
    [self cleanupCanvas];
}

- (void)setViewingCanvas {
    if (!isAttachedToWindow || self.superview == nil) {
        return;
    }

    [self cleanupCanvas];

    ZoomVideoSDKUser* user = [RNZoomVideoSdkUser getUser:userId];
    if (user == nil) {
        return;
    }

    ZoomVideoSDKUser* myself = [[[ZoomVideoSDK shareInstance] getSession] getMySelf];
    if (myself == nil) {
        return;
    }

    NSString *myselfUserId = [NSString stringWithFormat:@"%ld", [myself getUserID]];

    if (sharing && ![myselfUserId isEqualToString: userId]) {
        for (ZoomVideoSDKShareAction * shareAction in [user getShareActionList]) {
            if ([shareAction getShareStatus] == ZoomVideoSDKReceiveSharingStatus_Start) {
                currentCanvas = [shareAction getShareCanvas];
                break;
            }
        }
        [[SDKPiPHelper shared] updatePiPVideoUser:user videoType:ZoomVideoSDKVideoType_ShareData];
    } else {
        [[SDKPiPHelper shared] updatePiPVideoUser:user videoType:ZoomVideoSDKVideoType_VideoData];

        if (hasMultiCamera) {
            NSArray <ZoomVideoSDKVideoCanvas *> *multiCameraList = [user getMultiCameraCanvasList];
            NSInteger index = [multiCameraIndex integerValue];
            if (index >= 0 && index < [multiCameraList count]) {
                currentCanvas = multiCameraList[index];
            }
        } else {
            currentCanvas = [user getVideoCanvas];
        }
    }

    if (currentCanvas != nil) {
        subscribeRetryCount = 0;
        [self trySubscribeWithRetry];
    }

    bool annotationEnable = [[[ZoomVideoSDK shareInstance] getShareHelper] isAnnotationFeatureSupport];
    if (sharing && annotationEnable) {
        ZoomVideoSDKAnnotationHelper* helper = [[[ZoomVideoSDK shareInstance] getShareHelper] createAnnotationHelper: self];
        [[RNZoomVideoSdkAnnotationHelper alloc] setAnnotationHelper: helper];
    }
}

- (void)trySubscribeWithRetry {
    if (currentCanvas == nil || !isAttachedToWindow || self.superview == nil) {
        subscribeRetryCount = 0;
        return;
    }

    NSInteger attemptNumber = subscribeRetryCount + 1;
    ZoomVideoSDKError error;
    BOOL success = NO;

    if (isPiPView) {
        error = [currentCanvas subscribeWithPiPView:self aspectMode:0 andResolution:videoResolution];
    } else {
        error = [currentCanvas subscribeWithView:self aspectMode: videoAspect andResolution: videoResolution];
    }

    if (error == Errors_Success) {
        success = YES;
        subscribeRetryCount = 0;
    } else {
        success = NO;
    }

    if (!success && subscribeRetryCount < 2) {
        subscribeRetryCount++;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.03 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            if (self->currentCanvas != nil && self->isAttachedToWindow && self.superview != nil) {
                [self trySubscribeWithRetry];
            } else {
                self->subscribeRetryCount = 0;
            }
        });
    } else if (!success) {
        NSLog(@"RNZoomView: subscribeWithView failed after 3 attempts");
        subscribeRetryCount = 0;
    }
}

@end

