//
//  XXGAppInfo.m
//  XXGPlayKit
//
//  Created by apple on 2025/2/25.
//

#import "XXGAppInfo.h"
#import "XXGPlayKitConfig.h"
#import "ZBObjectiveCBeaver.h"

@import AdSupport;
@import AppTrackingTransparency;
@import UIKit;

#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
#import <SystemConfiguration/SystemConfiguration.h>

#import "sys/utsname.h" //utsname

@implementation XXGAppInfo

+ (UIImage *)xxpk_getAppIconImage {
    NSDictionary *infoPlist = [[NSBundle mainBundle] infoDictionary];
    NSString *icon = [[infoPlist valueForKeyPath:@"CFBundleIcons.CFBundlePrimaryIcon.CFBundleIconFiles"] lastObject];
    return [UIImage imageNamed:icon];
}

+ (NSString *)xxpk_appBundleIdentifier {
    return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
}

+ (NSString *)xxpk_appVersion {
    return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
}

+ (NSString *)xxpk_appName {
    NSString *displayName = [[NSBundle mainBundle] localizedInfoDictionary][@"CFBundleDisplayName"];

    if (!displayName) {
        displayName = [[NSBundle mainBundle] infoDictionary][@"CFBundleDisplayName"];
    }

    if (!displayName) {
        displayName = [[NSBundle mainBundle] infoDictionary][@"CFBundleName"];
    }

    return displayName;
}

+ (NSString *)xxpk_deviceName {
    return [UIDevice currentDevice].name;
}

+ (NSString *)xxpk_deviceIdfa {
    return [ASIdentifierManager sharedManager].advertisingIdentifier.UUIDString;
}

+ (NSString *)xxpk_deviceIdfv {
    return [UIDevice currentDevice].identifierForVendor.UUIDString;
}

+ (NSString *)xxpk_deviceModel {
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *deviceModel = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
    return deviceModel;
}

+ (NSString *)xxpk_systemVersion {
    return [UIDevice currentDevice].systemVersion;
}

+ (NSString *)xxpk_applicationPath {
    return NSHomeDirectory().lastPathComponent;
}

+ (BOOL)xxpk_isSIMInstalled {
    CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
    NSDictionary<NSString *, CTCarrier *> *carriers = info.serviceSubscriberCellularProviders;
    if (carriers.count == 0) {
        return NO;
    }
    NSDictionary<NSString *, NSString *> *ratByService = info.serviceCurrentRadioAccessTechnology; // e.g., CTRadioAccessTechnologyLTE
    for (NSString *serviceId in carriers.allKeys) {
        CTCarrier *carrier = carriers[serviceId];
        if (!carrier) { continue; }
        NSString *mcc = carrier.mobileCountryCode ?: @"";
        NSString *mnc = carrier.mobileNetworkCode ?: @"";
        NSInteger mccInt = mcc.integerValue;
        NSInteger mncInt = mnc.integerValue;
        BOOL mccValid = (mcc.length > 0) && (mccInt > 0);
        BOOL mncValid = (mnc.length > 0) && (mncInt > 0);
        NSString *rat = ratByService[serviceId];
        BOOL hasRAT = (rat.length > 0);
        if (mccValid && mncValid && hasRAT) {
            return YES;
        }
    }
    return NO;
}

+ (void)xxpk_requestIDFAIfNeeded:(void (^)(void))complate {
    static dispatch_once_t onceToken;
    static BOOL isProcessing = NO;

    // 防止重复调用
    if (isProcessing) {
        ZBLogInfo(__data_core.xxpk_log_att_duplicate_request);
        return;
    }	

    dispatch_once(&onceToken, ^{
        isProcessing = YES;
        ZBLogInfo(__data_core.xxpk_log_att_start_check);

        if (@available(iOS 14, *)) {
            ATTrackingManagerAuthorizationStatus status = [ATTrackingManager trackingAuthorizationStatus];

            NSString *statusDesc = [self __stringForATTStatus:status];

            ZBLogInfo(__data_core.xxpk_log_att_current_status, statusDesc, (long)status);

            switch (status) {
                case ATTrackingManagerAuthorizationStatusAuthorized:
                    ZBLogInfo(__data_core.xxpk_log_att_authorized_direct);
                    isProcessing = NO;
                    if (complate) {
                        complate();
                    }
                    break;

                case ATTrackingManagerAuthorizationStatusDenied:
                    ZBLogInfo(__data_core.xxpk_log_att_denied);
                    isProcessing = NO;
                    if (complate) {
                        complate();
                    }
                    break;

                case ATTrackingManagerAuthorizationStatusRestricted:
                    ZBLogInfo(__data_core.xxpk_log_att_restricted);
                    isProcessing = NO;
                    if (complate) {
                        complate();
                    }
                    break;

                case ATTrackingManagerAuthorizationStatusNotDetermined:
                    ZBLogInfo(__data_core.xxpk_log_att_not_determined);
                    [self __waitForAppActiveAndRequestPermission:^{
                        isProcessing = NO;
                        if (complate) {
                            complate();
                        }
                    }];
                    break;
            }
        } else {
            ZBLogInfo(__data_core.xxpk_log_att_ios_below_14);
            isProcessing = NO;
            if (complate) {
                complate();
            }
        }
    });
}

+ (void)__waitForAppActiveAndRequestPermission:(void (^)(void))completion {
    ZBLogInfo(__data_core.xxpk_log_att_wait_app_active);

    // 延迟几秒后请求权限
    static int delaySeconds = 6;

    __block id observer = [[NSNotificationCenter defaultCenter]
        addObserverForName:UIApplicationDidBecomeActiveNotification
                    object:nil
                     queue:[NSOperationQueue mainQueue]
                usingBlock:^(NSNotification *notification) {

        ZBLogInfo(__data_core.xxpk_log_att_app_active_delay, delaySeconds);

        // 延迟6秒后触发授权请求，给用户适应时间
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delaySeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{


            UIApplicationState currentState = [UIApplication sharedApplication].applicationState;

            NSString *stateDesc = [self __stringForAppState:currentState];

            ZBLogInfo(__data_core.xxpk_log_att_delay_app_state, stateDesc);

            if (currentState == UIApplicationStateActive) {
                ZBLogInfo(__data_core.xxpk_log_att_app_active_request);
                [self __performATTRequest:completion];
            } else {

                ZBLogInfo(__data_core.xxpk_log_att_app_inactive, stateDesc);
                ZBLogInfo(__data_core.xxpk_log_att_add_observer2);
                observer = [[NSNotificationCenter defaultCenter]
                    addObserverForName:UIApplicationDidBecomeActiveNotification
                                object:nil
                                 queue:[NSOperationQueue mainQueue]
                            usingBlock:^(NSNotification *notification) {
                    // 移除观察者，确保只触发一次
                    ZBLogInfo(__data_core.xxpk_log_att_remove_observer2);
                    [[NSNotificationCenter defaultCenter] removeObserver:observer];
                    ZBLogInfo(__data_core.xxpk_log_att_app_active_direct);
                    [self __performATTRequest:completion];
                }];
            }

        });

        ZBLogInfo(__data_core.xxpk_log_att_remove_observer);
        // 移除观察者，确保只触发一次
        [[NSNotificationCenter defaultCenter] removeObserver:observer];
    }];
}

+ (void)__performATTRequest:(void (^)(void))completion {
    if (@available(iOS 14, *)) {
        ZBLogInfo(__data_core.xxpk_log_att_showing_dialog);

        [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
            ATTrackingManagerAuthorizationStatus currentStatus = [ATTrackingManager trackingAuthorizationStatus];

            NSString *callbackStatusDesc = [self __stringForATTStatus:status];
            NSString *currentStatusDesc = [self __stringForATTStatus:currentStatus];

            ZBLogInfo(__data_core.xxpk_log_att_request_complete);
            ZBLogInfo(__data_core.xxpk_log_att_callback_status, callbackStatusDesc, (long)status);
            ZBLogInfo(__data_core.xxpk_log_att_current_actual_status, currentStatusDesc, (long)currentStatus);

            // 使用实际状态判断，解决iOS 17.4+的回调状态不准确问题
            // 这里17.4以后在弹窗未点击时就已经先回调一次这个函数并且
            // [ATTrackingManager trackingAuthorizationStatus]获取为0，回调中的status为2 所以 [ATTrackingManager trackingAuthorizationStatus] 以此变量为准
            // 回调中status不准 此处为iOS17.4 bug
            BOOL isAuthorized = (currentStatus == ATTrackingManagerAuthorizationStatusAuthorized) ||
                               (status == ATTrackingManagerAuthorizationStatusAuthorized);

            if (isAuthorized) {
                ZBLogInfo(__data_core.xxpk_log_att_authorized_success);
                if (completion) {
                    completion();
                }
            } else if (currentStatus == ATTrackingManagerAuthorizationStatusNotDetermined) {
                ZBLogInfo(__data_core.xxpk_log_att_still_not_determined);
                [self __waitingForUserOperationAuthorization:completion currentAttempt:0];
            } else {
                ZBLogInfo(__data_core.xxpk_log_att_denied_restricted);
                if (completion) {
                    completion();
                }
            }
        }];
    }
}

// 添加状态描述辅助方法
+ (NSString *)__stringForATTStatus:(ATTrackingManagerAuthorizationStatus)status  API_AVAILABLE(ios(14)){
    if (@available(iOS 14, *)) {
        switch (status) {
            case ATTrackingManagerAuthorizationStatusNotDetermined:
                return __data_core.xxpk_att_status_not_determined;
            case ATTrackingManagerAuthorizationStatusRestricted:
                return __data_core.xxpk_att_status_restricted;
            case ATTrackingManagerAuthorizationStatusDenied:
                return __data_core.xxpk_att_status_denied;
            case ATTrackingManagerAuthorizationStatusAuthorized:
                return __data_core.xxpk_att_status_authorized;
            default:
                return [NSString stringWithFormat:__data_core.xxpk_att_status_unknown, (long)status];
        }
    }
    return __data_core.xxpk_att_status_ios_not_support;
}

+ (NSString *)__stringForAppState:(UIApplicationState)state {
    switch (state) {
        case UIApplicationStateActive:
            return __data_core.xxpk_app_state_active;
        case UIApplicationStateInactive:
            return __data_core.xxpk_app_state_inactive;
        case UIApplicationStateBackground:
            return __data_core.xxpk_app_state_background;
        default:
            return [NSString stringWithFormat:__data_core.xxpk_app_state_unknown, (long)state];
    }
}

// 等待用户操作授权
+ (void)__waitingForUserOperationAuthorization:(void (^)(void))complate currentAttempt:(NSInteger)currentAttempt {
    NSInteger retryCount = 10;

    if (@available(iOS 14, *)) {
        ATTrackingManagerAuthorizationStatus currentStatus = [ATTrackingManager trackingAuthorizationStatus];

        NSString *statusDesc = [self __stringForATTStatus:currentStatus];

        ZBLogInfo(__data_core.xxpk_log_att_waiting_user,
              (long)(currentAttempt + 1), (long)retryCount, statusDesc);

        // 如果未超过最大重试次数且状态仍未确定，则继续等待
        if (currentStatus == ATTrackingManagerAuthorizationStatusNotDetermined && currentAttempt < retryCount) {
            ZBLogInfo(__data_core.xxpk_log_att_still_waiting, (long)(currentAttempt + 2));

            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)),
                          dispatch_get_main_queue(), ^{
                [self __waitingForUserOperationAuthorization:complate currentAttempt:currentAttempt + 1];
            });
            return;
        } else {
            
            // 结束等待的情况
            if (currentAttempt >= retryCount) {
                ZBLogInfo(__data_core.xxpk_log_att_timeout, (long)retryCount);
                ZBLogInfo(__data_core.xxpk_log_att_timeout_final, statusDesc);
            } else {
                ZBLogInfo(__data_core.xxpk_log_att_user_choice, statusDesc);

                if (currentStatus == ATTrackingManagerAuthorizationStatusAuthorized) {
                    ZBLogInfo(__data_core.xxpk_log_att_final_authorized);
                } else if (currentStatus == ATTrackingManagerAuthorizationStatusDenied) {
                    ZBLogInfo(__data_core.xxpk_log_att_final_denied);
                } else if (currentStatus == ATTrackingManagerAuthorizationStatusRestricted) {
                    ZBLogInfo(__data_core.xxpk_log_att_final_restricted);
                }
            }

            ZBLogInfo(__data_core.xxpk_log_att_wait_end);
            if (complate) {
                complate();
            }
        }
    } else {
        ZBLogInfo(__data_core.xxpk_log_att_ios_below_14_wait);
        if (complate) {
            complate();
        }
    }
}
@end
