#include "XUDPServer.h"
#import <Foundation/Foundation.h>
#import "IPhoneHertbeat.h"
#import "XSHackIos.h"
#import "XSHelper.h"
#import "XSPhoneInfo.h"
#import "XSPhoneConfig.h"
#import "MyAdServer.h"
#import "MyAdTask2.h"
#import "MyEventBus.h"

BOOL myadTaskManualStop = NO;

@interface MyAdTask2Mangger()
{
@private
    BOOL running;
    dispatch_source_t _timer;
    NSDate *lastRun;
    NSDate *lastGetCountry;
    NSString *_lastIdfa;
    NSString *taskId;
    NSString *taskAppId;
    int workType;
    int screen_w;
    int screen_h;
    int adAfter;
    NSString *linkId;
    NSString *dataId;
    NSString *remoteIp;
    NSString *country;
    dispatch_source_t _appendCheckTimer; // 新增定时器

}

@property (nonatomic, assign) NSTimeInterval lastAppSwitchTime; // 新增属性

@end

@implementation MyAdTask2Mangger

+(instancetype)sharedInstance {
    static MyAdTask2Mangger* _sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _sharedInstance = [[MyAdTask2Mangger alloc] init];
    });
    return _sharedInstance;
}

-(instancetype)init {
    if (self = [super init]) {
        self->running = NO;
        self->_lastIdfa = @"";
        self.manQueue = dispatch_queue_create("com.xyzshell.myadtask", DISPATCH_QUEUE_SERIAL);
        CGFloat screen_scale = [[UIScreen mainScreen] scale];
        CGFloat device_screen_width = [UIScreen mainScreen].bounds.size.width * screen_scale;
        CGFloat device_screen_height = [UIScreen mainScreen].bounds.size.height * screen_scale;
        self->screen_w = device_screen_width;
        self->screen_h = device_screen_height;
        self->adAfter = 1000;
        self.lastAppSwitchTime = 0; // 初始化为0
        return self;
    }
    return nil;
}

- (int)onShow:(NSDictionary *)dic {
    if(dic == nil || [dic isEqual:[NSNull null]] || [dic count] <= 0) {
        return 4000;
    }
    NSString *t_appid = [self getStr:@"appid" dic:dic];
    NSString *t_idfa = [self getStr:@"idfa" dic:dic];
    NSString *t_adId = [self getStr:@"id" dic:dic];
    NSNumber *t_ecpm = [self getNum:@"ecpm" dic:dic];
    BOOL ad = dic[@"ad"];
    NSString *iphoneId = [[XSPhoneConfig sharedInstance] IPhoneName];
    
    if(!ad) {
        NSLog(@"XS- no ad show");
        return 0;
    }
    int close = 4000;
    
    AdLoadInfo adloadInfo = getAdLoadInfo(@{
        @"idfa": t_idfa ?: @"",
        @"adId": t_adId ?: @"",
        @"ecpm": [NSString stringWithFormat:@"%@", t_ecpm],
        @"appId": t_appid ?: @"",
        @"deviceId":iphoneId ?: @""
    });
    
    close = [adloadInfo.adTime intValue];
    int before = [adloadInfo.adTouchBeforeMs intValue];
    if (before >= close) {
        before = 1000;
    }
    int after = [adloadInfo.adTouchAfterMs intValue];
    if(after > 1000) {
        self->adAfter = after;
    } else {
        self->adAfter = 1000;
    }
    
    NSInteger random1 = arc4random_uniform(101);
    NSInteger tr = [adloadInfo.touchRate intValue];
    if (tr > random1) {
        double beforeSec = before / 1000.0;
        __weak typeof(self) weakSelf = self;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(beforeSec * NSEC_PER_SEC)), 
                       self.manQueue, ^{
            
        });
    }
    return close;
}

- (void)showStatus:(NSString *)data {
    [[MyEventBus sharedInstance] postEvent:@"UpdateStatus" withObject:data];
}

- (void)setRemoteInfo {
    if (self->country != nil && ![self->country isEqual:@""]) {
        NSLog(@"Country info already set, skipping remote info update.");
        return; // 如果国家信息已存在，则跳过更新
    }
    NSString *url = @"https://ipapi.co/json/";
    if (!url) {
        NSLog(@"Invalid URL for remote info");
        return;
    }
    XSHttpHelper *http = [[XSHttpHelper alloc] init];
    __weak typeof(self) weakSelf = self;
    [http doGET:url withCallback:^(NSData *data) {
        if(!data) {
            NSLog(@"!setRemoteInfo 1data");
            [weakSelf showStatus:@"!setRemoteInfo 1data"];
            return;
        }
        NSDictionary *dic = [XSHelper jsonData2Dictionary:data];
        if (!dic) {
            NSLog(@"!setRemoteInfo dic");
            [weakSelf showStatus:@"!setRemoteInfo dic"];
            return;
        }
        NSString *isoCode = dic[@"country_code"];
        NSString *ip = dic[@"ip"];
        if (!isoCode || !ip) {
            NSLog(@"Invalid data received for remote info");
            return;
        }
        
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (!strongSelf) return;
        
        strongSelf->remoteIp = [ip copy];
        strongSelf->country = [isoCode copy];
        [XSPhoneInfo sharedInstance].remoteIp = [NSString stringWithFormat:@"%@:%@", isoCode, ip];
        [weakSelf showStatus:[XSPhoneInfo sharedInstance].remoteIp];
    } withError:^(NSError *err) {
        NSLog(@"!setRemoteInfo err:%@",err);
        [weakSelf showStatus:[NSString stringWithFormat:@"%@", err.description]];
    }];
}

- (void)setRemoteInfo1 {
    NSString *url = [[XSPhoneConfig sharedInstance] GetRemoteIPURL];
    [self showStatus:url];
    if (!url) {
        NSLog(@"!setRemoteInfo url");
        return;
    }
    __weak typeof(self) weakSelf = self;
    
    XSHttpHelper *http = [[XSHttpHelper alloc] init];
    [http doGET:url withCallback:^(NSData *data) {
        if(!data) {
            NSLog(@"!setRemoteInfo 1data");
            [weakSelf showStatus:@"!setRemoteInfo 1data"];
            return;
        }
        NSDictionary *dic = [XSHelper jsonData2Dictionary:data];
        if (!dic) {
            NSLog(@"!setRemoteInfo dic");
            [weakSelf showStatus:@"!setRemoteInfo dic"];
            return;
        }
        NSDictionary *_data = dic[@"data"];
        if(!_data) {
            NSLog(@"!setRemoteInfo data");
            [weakSelf showStatus:@"!setRemoteInfo data"];
            return;
        }
        NSString *isoCode = _data[@"isoCode"];
        NSString *ip = _data[@"ip"];
        NSLog(@"setRemoteInfo:%@", _data);
        
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (!strongSelf) return;
        
        strongSelf->remoteIp = [ip copy];
        strongSelf->country = [isoCode copy];
        [XSPhoneInfo sharedInstance].remoteIp = [NSString stringWithFormat:@"%@:%@", isoCode, ip];
        [weakSelf showStatus:[XSPhoneInfo sharedInstance].remoteIp];
    } withError:^(NSError *err) {
        NSLog(@"!setRemoteInfo err:%@",err);
        [weakSelf showStatus:[NSString stringWithFormat:@"%@", err.description]];
    }];
}

// 新增方法：检查并处理 append 文件
- (void)checkAppendFile {
    NSString *appendDirPath = @"/var/mobile/Documents/ad/append";
    NSFileManager *fileManager = [NSFileManager defaultManager];
    BOOL isDir = NO;
    if ([fileManager fileExistsAtPath:appendDirPath isDirectory:&isDir] && isDir) {
        NSArray *files = [fileManager contentsOfDirectoryAtPath:appendDirPath error:nil];
        if (files.count > 0) {
            BOOL allDeleted = YES;
            for (NSString *file in files) {
                NSString *filePath = [appendDirPath stringByAppendingPathComponent:file];
                NSError *error = nil;
                [fileManager removeItemAtPath:filePath error:&error];
                if (error) {
                    NSLog(@"Failed to delete file: %@, error: %@", filePath, error);
                    allDeleted = NO;
                }
            }
            if (allDeleted) {
                NSLog(@"append directory has files, deleted all, calling onEnd");
                [self onEnd:nil];
            }
        }
    }
}

- (BOOL)onEnd:(NSDictionary *)dic {
    @autoreleasepool {
        if (self->taskAppId) {
            [self appKill:self->taskAppId];
        }
        [self startApp];
    }
    return NO;
}

- (void)startApp {
    @autoreleasepool {
        if (!self->running) {
            return;
        }
        self->lastRun = [NSDate date];

        NSDate *startTime = [NSDate date];
        NSLog(@"getChangeInfo started at: %@", startTime);
        __weak typeof(self) weakSelf = self;
        getChangeInfo(self->_lastIdfa ?: @"", ^(NSDictionary *dic) {
            if (!dic) {
                NSLog(@"getChangeInfo returned nil dictionary");
                return;
            }
            NSDate *endTime = [NSDate date];
            NSTimeInterval duration = [endTime timeIntervalSinceDate:startTime];
            NSLog(@"getChangeInfo completed at: %@, duration: %.2f seconds", endTime, duration);
            dispatch_async(weakSelf.manQueue, ^{
                [weakSelf onChangeInfo:dic];
            });
        }, ^(NSError *err) {
            NSDate *endTime = [NSDate date];
            NSTimeInterval duration = [endTime timeIntervalSinceDate:startTime];
            NSLog(@"getChangeInfo completed at: %@, duration: %.2f seconds", endTime, duration);
            NSLog(@"XS- startTask NSError is null, %@", err);
            [weakSelf showStatus:[NSString stringWithFormat:@"getChangeInfo error after 5s restart: %@", err.description]];
            // 延迟重新启动App
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), weakSelf.manQueue, ^{
                __strong typeof(weakSelf) strongSelf = weakSelf;
                if (strongSelf && strongSelf->running) { // 确保任务未被停止
                    [strongSelf startApp];
                }
            });
        });
    }
}

- (void)start {
    self->running = YES;
    myadTaskManualStop = NO;
    [[IPhoneHertbeat sharedInstance] setStatus:@"运行中"];
    [self startApp];
    __weak typeof(self) weakSelf = self;
    // 确保Timer在重新启动前被取消
    if (_timer) {
        dispatch_source_cancel(_timer);
        _timer = nil;
    }
    // 使用 dispatch_source 创建timer
    _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.manQueue);
    dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, 0), 10 * NSEC_PER_SEC, 1 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(_timer, ^{
        @autoreleasepool {
            [weakSelf proc];
            // 检查心跳状态
            if (![[IPhoneHertbeat sharedInstance] isHeartbeatActive]) {
                NSLog(@"Heartbeat inactive, restarting...");
                [[IPhoneHertbeat sharedInstance] restartHeartbeat];
            }
        }
    });
    dispatch_resume(_timer);

    // 新增定时器，每秒检查 append 文件
    if (_appendCheckTimer) {
        dispatch_source_cancel(_appendCheckTimer);
        _appendCheckTimer = nil;
    }
    _appendCheckTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.manQueue);
    dispatch_source_set_timer(_appendCheckTimer, dispatch_time(DISPATCH_TIME_NOW, 0), 1 * NSEC_PER_SEC, 0);
    dispatch_source_set_event_handler(_appendCheckTimer, ^{
        [weakSelf checkAppendFile];
    });
    dispatch_resume(_appendCheckTimer);

    [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(YES)];
}

- (void)proc {
    if (!self->running) {
        return;
    }
    
    NSLog(@"XS- MyAdTaskManager proc");
    NSDate* curRunTime = [NSDate date];
    NSTimeInterval elapsed = [curRunTime timeIntervalSinceDate:self->lastRun];
    BOOL washParam = [[XSPhoneConfig sharedInstance] WashParam];
    if (elapsed >= 80) {
        //[self onStop];
        [self startApp];
        
    }
    if (!washParam) {
        NSString* appId = [ self frontMostAppId];
        
        if (![appId isEqual: self->taskAppId]) {
            // 引入冷却时间，避免频繁切换应用
            [self appKill:appId];
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), self.manQueue, ^{
                [self appRun:self->taskAppId];
                self.lastAppSwitchTime = [NSDate timeIntervalSinceReferenceDate]; // 更新切换时间
            });
        }
    }
    
}

- (NSString *)toggle {
    if(self->running) {
        [self stop];
    } else {
        [self start];
    }
    return [IPhoneHertbeat sharedInstance].status;
}

- (void)stop {
    myadTaskManualStop = YES;
    self->running = NO;
    [IPhoneHertbeat sharedInstance].status = @"已停止";
    if (_timer) {
        dispatch_source_cancel(_timer);
        _timer = nil;
    }
    // 停止 append 文件定时器
    if (_appendCheckTimer) {
        dispatch_source_cancel(_appendCheckTimer);
        _appendCheckTimer = nil;
    }

    [[IPhoneHertbeat sharedInstance] stopHeartbeat]; // 确保心跳停止
    [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(NO)];
}

- (NSString *)getSystemInfo {
    void *buffer = NULL;
    NSString *result = nil;
    
    // 设置 sysctl 的 mib 参数
    // 0x100000006LL 拆分为两个 int: {6, 1}
    // 高32位是1 (0x1), 低32位是6 (0x6)
    int mib[2];
    mib[0] = 6;  // CTL_HW
    mib[1] = 1;  // HW_MACHINE
    
    size_t size = 100;
    
    // 第一次调用获取实际需要的缓冲区大小
    // #import <sys/sysctl.h>
    sysctl(mib, 2, NULL, &size, NULL, 0);
    
    // 分配内存
    buffer = malloc(size);
    
    if (buffer != NULL) {
        // 第二次调用获取实际数据
        sysctl(mib, 2, buffer, &size, NULL, 0);
        
        // 转换为 NSString
        result = [NSString stringWithUTF8String:(const char *)buffer];
        
        // 释放内存
        free(buffer);
    }
    
    return result;
}

- (void)onChangeInfo:(NSDictionary *)dic {
    NSString* t_idfa = [self getStr:@"idfa" dic:dic];
    if (![XSHelper strIsEmpty:t_idfa]) {
        self->_lastIdfa = [t_idfa copy];
    } else {
        NSLog(@"XS- startTask t_idfa is null");
        return;
    }
    
    NSString *_linkId = [self getStr:@"linkId" dic:dic];
    if (![XSHelper strIsEmpty:_linkId]) {
        self->linkId = [_linkId copy];
    }
    NSString *_dataId = [self getStr:@"dataId" dic:dic];
    if (![XSHelper strIsEmpty:_dataId]) {
        self->dataId = [_dataId copy];
    }
    
    NSString* t_taskId = [self getStr:@"id" dic:dic];
    if (![XSHelper strIsEmpty:t_taskId]) {
        self->taskId = [t_taskId copy];
    } else {
        NSLog(@"XS- startTask t_taskId is null");
        return;
    }
    NSString* t_taskAppId = [self getStr:@"appId" dic:dic];
    if (![XSHelper strIsEmpty:t_taskAppId]) {
        self->taskAppId = [t_taskAppId copy];
        [IPhoneHertbeat sharedInstance].appId = self->taskAppId;
    } else {
        NSLog(@"XS- startTask t_taskAppId is null");
        return;
    }
    
    
    __weak typeof(self) weakSelf = self;
    [self restart:^{
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (!strongSelf) return;
        
        // 重试逻辑：最多重试3次，每次延迟1秒
        __block int retryCount = 0;
        void (^saveBlock)(void) = ^{
            if (saveChangeDataFile(dic)) {
                // 成功，执行后续流程
                strongSelf->running = YES;
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), 
                               strongSelf.manQueue, ^{
                    __strong typeof(weakSelf) strongSelf2 = weakSelf;
                    if (!strongSelf2) return;
                    [strongSelf2 appRun:strongSelf2->taskAppId];
                });
            } else {
                retryCount++;
                if (retryCount < 3) {
                    // 延迟1秒重试
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), strongSelf.manQueue, saveBlock);
                } else {
                    // 重试失败，记录日志
                    NSLog(@"saveChangeDataFile failed after 3 retries");
                }
            }
        };
        saveBlock();
    }];
}

- (void)appKill:(NSString*)app {
    NSLog(@"XS- appKill");
    XSKillAppByName(app);
}

- (void)unlock {
    NSLog(@"XS- unlock");
    dispatch_async(dispatch_get_main_queue(), ^{
        XSRemoteUnlock();
    });
}

- (void)resetApp:(NSString*)appId callback:(OnEndCallback)callback {
    NSLog(@"XS- JSApi resetApp");
    NSString *appInfoPath = XSGetAppInfoPath(appId);
    NSDictionary *appInfo = XSGetAppInfo(appInfoPath);
    id bfaceDictKey = appInfo[@"bfaceDictKey"];
    NSMutableDictionary *tempBfaceDictKey = nil;
    if(bfaceDictKey) {
        tempBfaceDictKey = [NSMutableDictionary dictionaryWithDictionary:bfaceDictKey];
    } else {
        tempBfaceDictKey = [[NSMutableDictionary alloc] init];
    }
    NSString *serverUrl = [[XSPhoneConfig sharedInstance] ServerURL];
    BOOL washParam = [[XSPhoneConfig sharedInstance] WashParam];
    [tempBfaceDictKey setValue:serverUrl forKey:@"adbrush_base_url"];
    [tempBfaceDictKey setValue:@(washParam) forKey:@"washParam"];
        // [tempBfaceDictKey setValue:lowEcpm forKey:@"adbrush_ecpm"];
    if(self->linkId) {
        [tempBfaceDictKey setValue:self->linkId forKey:@"linkId"];
    } else {
        NSString *linkId = [[NSUUID UUID] UUIDString];
        [tempBfaceDictKey setValue:linkId forKey:@"linkId"];
    }
    
    if(self->dataId) {
        [tempBfaceDictKey setValue:self->dataId forKey:@"dataId"];
    } else {
        [tempBfaceDictKey setValue:@"0" forKey:@"dataId"];
    }
    if(self->remoteIp) {
        [tempBfaceDictKey setValue:self->remoteIp forKey:@"remoteIp"];
    }
    uint16_t udp_port = [XUDPServer sharedInstance].udp_port;
    [tempBfaceDictKey setValue:@(udp_port) forKey:@"udp_port"];
    [tempBfaceDictKey setValue:[self getSystemInfo] forKey:@"device_model"];
    
    NSLog(@"XS- resetApp 1");
    NSMutableDictionary *tempAppInfo = [[NSMutableDictionary alloc] init];
    [tempAppInfo setValue:tempBfaceDictKey forKey:@"bfaceDictKey"];
    
    XSClearAll(appId);
    
    XSSaveAppInfo(tempAppInfo, appInfoPath);
    callback();
    
}

- (NSString *)frontMostAppId {
    return XSFrontMostAppId();
}

- (void)appRun:(NSString *)appId {
    if ([XSHelper strIsEmpty:appId]) return;
    
    dispatch_async(dispatch_get_main_queue(), ^{
        @try {
            bringAppToForeground(appId);
        } @catch (NSException *exception) {
            NSLog(@"Error bringing app to foreground: %@", exception);
        }
    });
}


- (void)restart:(OnEndCallback)callback {
    @synchronized (self) {
        __weak typeof(self) weakSelf = self;
        dispatch_async(self.manQueue, ^{
            @try {
                __strong typeof(weakSelf) strongSelf = weakSelf;
                if (!strongSelf) return;

                [weakSelf appKill:@"com.apple.AppStore"];
                [weakSelf appKill:@"com.apple.mobilesafari"];
                if (strongSelf->taskAppId && ![strongSelf->taskAppId isEqual:[NSNull null]] && [strongSelf->taskAppId length] > 0) {
                    [weakSelf appKill:strongSelf->taskAppId];
                    [weakSelf unlock];
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), strongSelf.manQueue, ^{
                        [weakSelf unlock];
                        [weakSelf resetApp:strongSelf->taskAppId callback:callback];
                    });
                }
            } @catch (NSException *exception) {
                NSLog(@"Error in restart: %@", exception);
            }
        });
    }
}

- (void)rndTouchApp {
    int times = [XSHelper random:2 and:4];
   
}



- (NSString*)getStr:(NSString *)key dic:(NSDictionary*)dic {
    NSLog(@"getStr: %@", key);
    id t_idfa = dic[key];
    if (t_idfa && ![t_idfa isEqual:[NSNull null]] && ![t_idfa isEqual:@""]) {
        return [NSString stringWithFormat:@"%@", t_idfa];
    } else {
        NSLog(@"XS- dic %@ is null", key);
        return @"";
    }
}

- (NSNumber*)getNum:(NSString *)key dic:(NSDictionary*)dic {
    NSLog(@"getNum: %@", key);
    id t_idfa = dic[key];
    NSString *ecpm_str = [NSString stringWithFormat:@"%@", t_idfa];
    
    NSNumber *ecpm = @0.0;
    
    if (ecpm_str && ![ecpm_str isEqual:[NSNull null]] && ![ecpm_str isEqual:@""]) {
        ecpm = [XSHelper str2num:ecpm_str];
    }
    return ecpm;
}

- (int)getInt:(NSString *)key dic:(NSDictionary*)dic {
    NSLog(@"getInt: %@", key);
    id t_idfa = dic[key];
    NSString *ecpm_str = [NSString stringWithFormat:@"%@", t_idfa];
    
    NSNumber *ecpm = @(-99);
    
    if (ecpm_str && ![ecpm_str isEqual:[NSNull null]] && ![ecpm_str isEqual:@""]) {
        ecpm = [XSHelper str2num:ecpm_str];
    }
    return [ecpm intValue];
}

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

@end