#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

extern "C" void UnitySendMessage(const char *obj, const char *method, const char *msg);

#import <InMobiCMP/InMobiCMP-Swift.h>

static NSString* _nexusReceiverObj = nil;
typedef void (*NexusCmpDoneFn)(void);
static NexusCmpDoneFn _doneFn = NULL;

@interface NexusChoiceDelegate : NSObject <ChoiceCmpDelegate>
@property (nonatomic) BOOL uiShown;
@property (nonatomic) BOOL userInteracted;
@property (nonatomic) BOOL done;
@end

@implementation NexusChoiceDelegate

- (void)reset {
    self.uiShown = NO;
    self.userInteracted = NO;
    self.done = NO;
}

- (void)finish {
    if (self.done) return;
    self.done = YES;

    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"[Nexus] InMobi CMP finish → Unity");
        if (_doneFn) _doneFn();
        if (_nexusReceiverObj)
            UnitySendMessage(_nexusReceiverObj.UTF8String, "OnCmpDone", "");
    });
}

- (void)cmpDidLoadWithInfo:(PingResponse * _Nonnull)info {
    NSLog(@"[Nexus] InMobi cmpDidLoad displayStatus=%ld", (long)info.displayStatus);
    if (info.displayStatus == DisplayStatusVisible) {
        self.uiShown = YES;
        return;
    }
    if (!self.uiShown &&
        (info.displayStatus == DisplayStatusDismissed || info.displayStatus == DisplayStatusDisabled)) {
        [self finish];
    }
}

- (void)cmpUIStatusChangedWithInfo:(DisplayInfo * _Nonnull)info {
    NSLog(@"[Nexus] InMobi cmpUIStatusChanged displayStatus=%ld", (long)info.displayStatus);
    if (info.displayStatus == DisplayStatusVisible) {
        self.uiShown = YES;
        return;
    }
    if (info.displayStatus == DisplayStatusDismissed) {
        [self finish];
        return;
    }
    if ((self.uiShown || self.userInteracted) && info.displayStatus == DisplayStatusHidden) {
        [self finish];
    }
}

- (void)didReceiveActionButtonTapWithAction:(enum ActionButtons)action {
    NSLog(@"[Nexus] InMobi actionButtonTap action=%ld", (long)action);
    self.userInteracted = YES;
}

- (void)didReceiveIABVendorConsentWithGdprData:(GDPRData * _Nonnull)gdprData updated:(BOOL)updated {
    NSLog(@"[Nexus] InMobi IAB consent updated=%d uiShown=%d", updated, self.uiShown);
    if (!updated && !self.uiShown) {
        // Consent already stored from a prior session — CMP skipped the UI.
        __weak typeof(self) weakSelf = self;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [weakSelf finish];
        });
        return;
    }
    if (!updated) return;
    self.userInteracted = YES;
    __weak typeof(self) weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.75 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [weakSelf finish];
    });
}

- (void)didReceiveUSRegulationsConsentWithUsRegData:(USRegulationsData * _Nonnull)usRegData { }

- (void)cmpDidErrorWithError:(NSError * _Nonnull)error {
    NSLog(@"[Nexus] InMobi cmpDidError: %@", error);
    [self finish];
}

- (void)didReceiveNonIABVendorConsentWithNonIabData:(NonIABData * _Nonnull)nonIabData updated:(BOOL)updated { }
- (void)didReceiveAdditionalConsentWithAcData:(ACData * _Nonnull)acData updated:(BOOL)updated { }
- (void)userDidMoveToOtherState { }

@end

extern "C" {
    void NexusInMobiCmp_SetDoneCallback(NexusCmpDoneFn fn) {
        _doneFn = fn;
    }

    void NexusInMobiCmp_StartChoice(const char* pcode, const char* gameObjectName) {
        if (!pcode || !gameObjectName) return;

        @autoreleasepool {
            _nexusReceiverObj = [NSString stringWithUTF8String:gameObjectName];
            NSString* pc = [NSString stringWithUTF8String:pcode];

            static NexusChoiceDelegate* del = nil;
            if (!del) del = [NexusChoiceDelegate new];
            [del reset];

            dispatch_async(dispatch_get_main_queue(), ^{
                [[ChoiceCmp shared] startChoiceWithPcode:pc
                                               delegate:del
                                           ccpaDelegate:nil
                                            gbcDelegate:nil
                                      shouldDisplayIDFA:NO
                                                 style:nil];
            });
        }
    }
}
