//
//  KBKeyboardPermissionManager.m
//

#import "KBKeyboardPermissionManager.h"
#import <Security/Security.h>
#import "KBConfig.h"

// Keychain 存储：记录上次扩展上报的“完全访问”状态
static NSString * const kKBPermService = @"com.loveKey.nyx.perm";
static NSString * const kKBPermAccount = @"full_access"; // 保存一个字节/数字：0/1/2

@implementation KBKeyboardPermissionManager

+ (instancetype)shared {
    static KBKeyboardPermissionManager *m; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ m = [KBKeyboardPermissionManager new]; });
    return m;
}

#pragma mark - App side

- (BOOL)isKeyboardEnabled {
    // 与 AppDelegate 中同思路：遍历 activeInputModes，匹配自家扩展 bundle id
    for (UITextInputMode *mode in [UITextInputMode activeInputModes]) {
        NSString *identifier = nil;
        @try { identifier = [mode valueForKey:@"identifier"]; } @catch (__unused NSException *e) { identifier = nil; }
        if ([identifier isKindOfClass:NSString.class] && [identifier rangeOfString:KB_KEYBOARD_EXTENSION_BUNDLE_ID].location != NSNotFound) {
            return YES;
        }
    }
    return NO;
}

- (KBFARecord)lastKnownFullAccess {
    NSData *data = [self keychainRead];
    if (data.length == 0) return KBFARecordUnknown;
    uint8_t v = 0; [data getBytes:&v length:1];
    if (v > KBFARecordGranted) v = KBFARecordUnknown;
    return (KBFARecord)v;
}

- (void)presentPermissionIfNeededFrom:(UIViewController *)presenting {
    BOOL enabled = [self isKeyboardEnabled];
    KBFARecord fa = [self lastKnownFullAccess];
    // 策略：
    // - 未启用键盘：一定引导；
    // - 已启用键盘：仅当明确知道“完全访问被拒绝”才引导；Unknown 不打扰（等待扩展上报）。
    BOOL needGuide = (!enabled) || (enabled && fa == KBFARecordDenied);
    if (!needGuide || !presenting) return;

    Class cls = NSClassFromString(@"KBPermissionViewController");
    if (!cls) return; // 主 App 才存在该类
    UIViewController *guide = [cls new];
    guide.modalPresentationStyle = UIModalPresentationFullScreen;
    [presenting presentViewController:guide animated:YES completion:nil];
}

#pragma mark - Extension side

- (void)reportFullAccessFromExtension:(BOOL)granted {
    uint8_t v = granted ? KBFARecordGranted : KBFARecordDenied;
    NSData *data = [NSData dataWithBytes:&v length:1];
    [self keychainWrite:data];
}

#pragma mark - Keychain shared blob

- (NSMutableDictionary *)baseKCQuery {
    NSMutableDictionary *q = [@{ (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                                 (__bridge id)kSecAttrService: kKBPermService,
                                 (__bridge id)kSecAttrAccount: kKBPermAccount } mutableCopy];
    q[(__bridge id)kSecAttrAccessGroup] = KB_KEYCHAIN_ACCESS_GROUP;
    return q;
}

- (BOOL)keychainWrite:(NSData *)data {
    NSMutableDictionary *query = [self baseKCQuery];
    SecItemDelete((__bridge CFDictionaryRef)query);
    query[(__bridge id)kSecValueData] = data ?: [NSData data];
    query[(__bridge id)kSecAttrAccessible] = (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;
    OSStatus st = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
    return (st == errSecSuccess);
}

- (NSData *)keychainRead {
    NSMutableDictionary *query = [self baseKCQuery];
    query[(__bridge id)kSecReturnData] = @YES;
    query[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne;
    CFTypeRef dataRef = NULL; OSStatus st = SecItemCopyMatching((__bridge CFDictionaryRef)query, &dataRef);
    if (st != errSecSuccess || !dataRef) return nil;
    return (__bridge_transfer NSData *)dataRef;
}

@end
