#import <UIKit/UIKit.h>
#import <objc/message.h>
#import <objc/runtime.h>
#import "StatusBarTap.h"

// Performs the actual swizzle once per process. Safe to call multiple times.
static void mm_installStatusBarTapSwizzleOnce(void) {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class cls = [UIStatusBarManager class];
        SEL originalSelector = NSSelectorFromString(@"handleTapAction:");
        SEL swizzledSelector = NSSelectorFromString(@"mm_handleTapAction:");

        Method originalMethod = class_getInstanceMethod(cls, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(cls, swizzledSelector);
        if (!originalMethod || !swizzledMethod) return;

        // Verify the original method matches the (id) -> void shape we expect.
        // Encoding may include byte offsets (e.g. "v32@0:8@16") so we filter
        // digits out before comparing.
        const char *encPtr = method_getTypeEncoding(originalMethod);
        if (encPtr) {
            NSMutableString *enc = [NSMutableString string];
            for (const char *p = encPtr; *p; p++) {
                if (!(*p >= '0' && *p <= '9')) [enc appendFormat:@"%c", *p];
            }
            if (![enc isEqualToString:@"v@:@"]) return;
        }

        BOOL didAdd = class_addMethod(cls,
                                      originalSelector,
                                      method_getImplementation(swizzledMethod),
                                      method_getTypeEncoding(swizzledMethod));
        if (didAdd) {
            class_replaceMethod(cls,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

@implementation MoMoStatusBarTap
+ (NSNotificationName)notificationName { return @"statusBarSelected"; }
+ (void)install { mm_installStatusBarTapSwizzleOnce(); }
@end

// MARK: - Swizzle target on UIStatusBarManager
// `mm_handleTapAction:` is the replacement IMP. After the add/exchange,
// this selector points at the original UIKit IMP — calling it inside
// the body invokes UIKit's real handler so UIScrollView.scrollsToTop
// and any other side effects continue to work.

@interface UIStatusBarManager (MoMoStatusBarTap)
@end

@implementation UIStatusBarManager (MoMoStatusBarTap)

// Auto-install at framework load. Commented out so the swizzle stays
// opt-in via `[MoMoStatusBarTap install]`. Uncomment to revert to
// auto-installation before main().
//
// + (void)load {
//     mm_installStatusBarTapSwizzleOnce();
// }

- (void)mm_handleTapAction:(id)action {
    [self mm_handleTapAction:action];
    [[NSNotificationCenter defaultCenter] postNotificationName:MoMoStatusBarTap.notificationName
                                                        object:nil];
}

@end
