//
//  MyAdTask2.m
//  nochange
//
//  Created by mac on 2024/11/6.
//

#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;
    // NSTimer *timer;
    dispatch_source_t _timer;  // 使用GCD timer替代NSTimer
    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;
}

@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;
        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];
    // NSString *ipAddr = [[XSPhoneInfo sharedInstance] IPAddress];
    
    /*
    saveAdTaskLog(@{
        @"title": @"广告展示",
        @"message": [XSHelper dic2Json:dic],
        @"level": @(1),
        @"appid": t_appid,
        @"idfa":t_idfa,
        @"adid": t_adId,
        @"ecpm": [NSString stringWithFormat:@"%@", t_ecpm],
        @"taskId": self->taskId,
        @"iphoneId":iphoneId,
        @"ipAddr":ipAddr
        
    });
     */
    
    /* --
     if (self->current > -1 && self->current < (NSInteger)self->tasks.count) {
     cur = self->tasks[self->current];
     }
     */
    if(!ad) {
        NSLog(@"XS- no ad show");
        return 0;
    }
    int close = 4000;
    //--new
    AdLoadInfo adloadInfo = getAdLoadInfo(@{
        @"idfa": t_idfa ?: @"",
        @"adId": t_adId ?: @"",
        @"ecpm": [NSString stringWithFormat:@"%@", t_ecpm],
        @"appId": t_appid ?: @"",
        @"deviceId":iphoneId ?: @""
    });
    
    // cur.loads = adloadInfo.loads;
    //cur.adTouchBeforeMs = adloadInfo.adTouchBeforeMs;
    // cur.adTime= adloadInfo.adTime;
    
    
    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); // 0-100
    NSInteger tr = [adloadInfo.touchRate intValue];
    if (tr > random1) {
        [self touchAppTask: before / 1000];
    }
    return close;
}

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

- (void) setRemoteInfo  {
    NSString *url = @"https://ipapi.co/json/";
    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"];
        // callback(ip, isoCode);
        __strong typeof(weakSelf) strongSelf = weakSelf;
        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;
        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]];
    }];
    
   
    
}


- (BOOL) onEnd: (NSDictionary *)dic {
    NSNumber *maxEcpm = dic[@"max_ecpm"];
    int sec = self->adAfter / 1000;
    __weak typeof(self) weakSelf = self;
    if([maxEcpm doubleValue] <= 0.0) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, sec * NSEC_PER_SEC), self.manQueue, ^{
            @autoreleasepool {
                [weakSelf startApp];
            }
        });
        return NO;
    }
    BOOL res = needAdContinue(self->taskAppId, self->_lastIdfa, maxEcpm);
    if(res) {
        return YES;
    }
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, sec * NSEC_PER_SEC), self.manQueue, ^{
        @autoreleasepool {
            [weakSelf startApp];
        }
    });

    return NO;
}

- (void) startApp {
    @autoreleasepool {
        if(!self->running){
            return;
        }
        self->lastRun = [NSDate date];
        if (self->country == nil || [self->country isEqual:NULL] || [self->country isEqual:@""]) {
            [self setRemoteInfo];
            self->lastGetCountry = [NSDate date];
        } else {
            NSDate *curRunTime = [NSDate date];
            NSTimeInterval elapsed = [curRunTime timeIntervalSinceDate:self->lastGetCountry];
            if (elapsed >= 300) {
                [self setRemoteInfo];
                self->lastGetCountry = [NSDate date];
            }
        }
        
        /*
        if(![@"US" isEqual:self->country]) {
            [self showStatus:[NSString stringWithFormat:@"%@:%@, Not US", self->country, self->remoteIp]];
            return;
        }
         */
        __weak typeof(self) weakSelf = self;
        getChangeInfo(self->_lastIdfa, ^(NSDictionary *dic) {
            dispatch_async(weakSelf.manQueue, ^{
                // 耗时操作
                [weakSelf onChangeInfo: dic];
            });
            
        }, ^(NSError *err) {
            NSLog(@"XS- startTask NSError is null, %@", err);
        });
    }
}

- (void) start {
    self->running = YES;
    myadTaskManualStop = NO;
    [[IPhoneHertbeat sharedInstance] setStatus: @"运行中"];
    [self startApp];
    __weak typeof(self) weakSelf = self;
    // 使用 dispatch_source 创建timer
    if (!_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];
            }
        });
        dispatch_resume(_timer);
    }
    [[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];
    
    if (elapsed >= 30) {
        //[self onStop];
        [self start];
        
    } else {
        NSString* appId = [ self frontMostAppId];
        
        if (![appId isEqual: self->taskAppId]) {
            [self appKill:appId];
            sleep(1);
            [self appRun:self->taskAppId];
        }
    }
    
}

- (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;
    }
    [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(NO)];
}


- (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;
    }

    NSDictionary *workerInfo = dic[@"workerInfo"];
    if(workerInfo && ![workerInfo isEqual:[NSNull null]]) {
        
    } else {
        NSLog(@"XS- startTask workerInfo is null");
       
        return;
    }
    
    int t_workType = [self getInt:@"workType" dic:workerInfo];
    if (t_workType > -99) {
        self->workType = t_workType;
    } else {
        NSLog(@"XS- startTask workType is null");
       
    }
    [self restart:^{
        saveChangeDataFile(dic);
        self->running = YES;
        sleep(1);
        [self appRun:self->taskAppId];
    }];
    //sleep(1);
}


- (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];
   
    [tempBfaceDictKey setValue:@"http://127.0.0.1:6000" forKey:@"adbrush_local_url"];
    [tempBfaceDictKey setValue:serverUrl forKey:@"adbrush_base_url"];
    __weak typeof(self) weakSelf = self;
    getLowEcpm(^(NSNumber *lowEcpm) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        BOOL washParam = strongSelf->workType == 0 ? YES : NO;
        [tempBfaceDictKey setValue:@(washParam) forKey:@"washParam"];
        [tempBfaceDictKey setValue:lowEcpm forKey:@"adbrush_ecpm"];
        if(strongSelf->linkId) {
            [tempBfaceDictKey setValue:strongSelf->linkId forKey:@"linkId"];
        }  else {
            NSString *linkId = [[NSUUID UUID] UUIDString];
            [tempBfaceDictKey setValue:linkId forKey:@"linkId"];
        }
        
        if(strongSelf->dataId) {
            [tempBfaceDictKey setValue:strongSelf->dataId forKey:@"dataId"];
        }  else {
            NSString *dataId = @"0";
            [tempBfaceDictKey setValue:dataId forKey:@"dataId"];
        }
        if(strongSelf->remoteIp) {
            [tempBfaceDictKey setValue:strongSelf->remoteIp forKey:@"remouteIP"];
        }

        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) tap: (int) i x:(int)x y:(int)y {
}

- (void) restart: (OnEndCallback) callback {
    __weak typeof(self) weakSelf = self;
    dispatch_async(self.manQueue, ^{
        @try {
            __strong typeof(weakSelf) strongSelf = weakSelf;
            [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];
                sleep(1);
                [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];
    for (int i = 1; i <= times; i++) {
        int x = [XSHelper random:40 and:screen_w - 20];
        int y = [XSHelper random:50 and:screen_h - 240];
        NSString* appId = [self frontMostAppId];
        if ([appId isEqual:self->taskAppId]) {
            [self tap:1 x:x y:y];
            usleep(2000);
        } else {
            break;
        }
    }

}

- (void) touchAppTask: (int) beforeTouch {
    if (beforeTouch > 0) {
        sleep(beforeTouch);
    }
    [self rndTouchApp];
    sleep(2);
    
    int x = [XSHelper random:40 and:screen_w - 20];
    int y = [XSHelper random:50 and:screen_h - 240];
    [self tap:1 x:x y:y];
    
    NSString* appId = [ self frontMostAppId];
   
    if (![appId isEqual: self->taskAppId]) {
        // [self appKill:appId];
        sleep(1);
    }
    
    [self appRun:self->taskAppId];
}
- (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

