//
//  IosSystemCmd.m
//  nochange
//
//  Created by mac on 2024/8/27.
//


#import "IosSystemCmd.h"
#import "XSPhoneConfig.h"
#import "XSPhoneInfo.h"
#import "XSHelper.h"
#import "XSHackIos.h"
#import "MyEventBus.h"
#import "XSHttpHelper.h"
#import "MyAdTask2.h"
#import "MyAdServer.h"

#define CMD_RES @"/ios/top_selection/system_cmd_response"
#define CMD @"/ios/top_selection/system_cmds"

@implementation IosSystemCmd
{
@private
    XSPhoneConfig *_config;
    XSHttpHelper *http;
    dispatch_source_t _timer;  // 替换 NSTimer
    dispatch_queue_t _workQueue;
}

+ (instancetype)sharedInstance {
    static IosSystemCmd *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        self->_config = [XSPhoneConfig sharedInstance];
        self->http = [[XSHttpHelper alloc] init];
    }
    return self;
}

- (NSString *)cmdUrl {
    return [NSString stringWithFormat:@"%@%@", _config.MainServerURL, CMD];
}
- (NSString *)cmdResUrl {
    return [NSString stringWithFormat:@"%@%@", _config.MainServerURL, CMD_RES];
}

- (void) start {
    if (_timer) return;
    _workQueue = dispatch_queue_create("com.iossystemcmd.queue", DISPATCH_QUEUE_SERIAL);
    _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _workQueue);
    dispatch_source_set_timer(_timer, dispatch_time(DISPATCH_TIME_NOW, 0), 2 * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC);
    
    __weak typeof(self) weakSelf = self;
    dispatch_source_set_event_handler(_timer, ^{
        @autoreleasepool {
            [weakSelf runTask];
        }
    });
    
    dispatch_resume(_timer);
}

- (void) runTask {
    NSLog(@"XC- run system task...");
    NSString *deviceId = [_config DeviceId];
    NSString *ip = [[XSPhoneInfo sharedInstance] IPAddress];
    NSString *name = [_config IPhoneName];
    NSDictionary *dic = @{
        @"deviceId": deviceId,
        @"ip": ip,
        @"iphoneId": name
    };
    /*
    pushInfo(2,
             [XSHelper dic2Json:dic],
             ^(NSString *data) {
                if(data){
                    NSDictionary *dic = [XSHelper json2Dictionary:data];
                    [self executeTask:dic];
                } else {
                    NSLog(@"XC- get system cmd error");
                }
            }, ^(NSError *err) {
                NSLog(@"XC- get system cmd error:%@",err);
            });
     */
    __weak typeof(self) weakSelf = self;
    [self->http doPOST:[self cmdUrl] json:[XSHelper dic2Json:dic] withCallback:^(NSData *data) {
        if (data) {
            NSDictionary *dic = [XSHelper jsonData2Dictionary:data];
            if (dic && [dic objectForKey:@"data"]) {
                id data = dic[@"data"];
                if (data && data != [NSNull null]) {
                    [weakSelf executeTask:data];
                }
            }
        } else {
            NSLog(@"XC- get system cmd error");
        }
        
    } withError:^(NSError *err) {
        NSLog(@"XC- get system cmd error:%@",err);
    }];
     
}

- (void) executeTask: (NSDictionary*)dic {
    if ([dic objectForKey:@"cmd"]) {
        NSString *cmd = dic[@"cmd"];
        NSString *taskId = dic[@"taskId"];
        if ([cmd isEqual:@"EDIT_NAME"]) {
            [self executeEditName:taskId data:dic[@"cmdData"]];
            return;
        }
        if ([cmd isEqual:@"UPLOAD_APPS"]) {
            [self executeUploadApps:taskId data:dic[@"cmdData"]];
            return;
        }
        if ([cmd isEqual:@"START"]) {
            [self executeStart:taskId data:dic[@"cmdData"]];
            return;
        }
        if ([cmd isEqual:@"STOP"]) {
            [self executeStop:taskId data:dic[@"cmdData"]];
            return;
        }
        if ([cmd isEqual:@"SCREENSHOT"]) {
            [self executeScreenshot:taskId data:dic[@"cmdData"]];
            return;
        }
        if ([cmd isEqual:@"UNLOCK"]) {
            [self executeUnlock:taskId data:dic[@"cmdData"]];
            return;
        }
        if ([cmd isEqual:@"RESTART_SYSTEM"]) {
            [self executeRestart:taskId data:dic[@"cmdData"]];
            return;
        }
        if ([cmd isEqual:@"RESTART"]) {
            [self executeReboot:taskId data:dic[@"cmdData"]];
            return;
        }
        if ([cmd isEqual:@"TOUCH"]) {
            [self executeTouch:taskId data:dic[@"cmdData"]];
            return;
        }
        if ([cmd isEqual:@"KEY"]) {
            [self executeKey:taskId data:dic[@"cmdData"]];
            return;
        }
        if ([cmd isEqual:@"UPDATE_KEY"]) {
            [self executeUpdateKey:taskId data:dic[@"cmdData"]];
            return;
        }
    }
}

- (void) putTask: (NSString*)taskId error: (NSString*)error data:(NSString*)data {
    NSDictionary *dic = @{
        @"taskId": taskId,
        @"data": data,
        @"error": error
    };
    /*
    pushInfo(3, [XSHelper dic2Json:dic], ^(NSString *data) {
        if(data) {
            NSLog(@"XS- %@", data);
        }
    }, ^(NSError *err) {
        NSLog(@"XS- %@", err);
    });
    */
    
    [self->http doPOST:[self cmdResUrl] json:[XSHelper dic2Json:dic] withCallback:^(NSData *data) {
        if (data) {
            NSLog(@"XS- %@", [XSHelper data2str:data]);
        }
    } withError:^(NSError *err) {
        NSLog(@"XS- %@", err);
    }];
     
}

- (void) executeEditName: (NSString*)taskId data:(NSString*)data {
    if (data) {
        BOOL setSs = [_config SetIPhoneName:data];
        [[MyEventBus sharedInstance] postEvent:@"UpdateName" withObject:data];
        NSString *r = [NSString stringWithFormat:@"set:%@", setSs == YES ?@ "YES": @"NO"];
        [self putTask:taskId error:r data:data];
    }
}

- (void) executeUploadApps: (NSString*)taskId data:(NSString*)data {
    NSArray *apps = [self getMyApps];
    NSData *appsData = [XSHelper obj2JsonData:apps];
    if (appsData) {
        [self putTask:taskId error:@"" data:[XSHelper data2str:appsData]];
    } else {
        NSLog(@"upload apps error");
    }
}

- (void) executeStart: (NSString*)taskId data:(NSString*)data  {
    //[[XSConsole sharedInstance] restart];
    [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(YES)];
    [[MyAdTask2Mangger sharedInstance] start];
    [self putTask:taskId error:@"" data:data];
}

- (void) executeStop: (NSString*)taskId data:(NSString*)data  {
    //[[XSConsole sharedInstance] stop];
    [[MyAdTask2Mangger sharedInstance] stop];
    [[MyEventBus sharedInstance] postEvent:@"UpdateRunStatus" withObject:@(NO)];
    [self putTask:taskId error:@"" data:data];
}

- (void) executeScreenshot:(NSString*)taskId data:(NSString*)data {
    @try {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"executeScreenshot;%@;%@",taskId, data);
            UIImage *img = XSCcaptureScreen2();
            NSString *base64 = [XSHelper base64StringFromJpgImage:img];
            if (base64) {
                [self putTask:taskId error:@"" data:base64];
            } else {
                [self putTask:taskId error:@"截屏失败" data:data];
            }
        });
    } @catch (NSException *exception) {
        [self putTask:taskId error:@"截屏失败" data:data];
    }
}

- (void) executeUnlock: (NSString*) taskId data:(NSString*)data {
    @try {
        
        //[[[XSJsApi alloc] init] unlock];
        dispatch_async(dispatch_get_main_queue(), ^{
            XSRemoteUnlock();
        });
        
    } @catch (NSException *exception) {
       
    }
}
- (void) executeRestart: (NSString*) taskId data:(NSString*)data {
    @try {
        dispatch_async(dispatch_get_main_queue(), ^{
            XSKillApp(@"SpringBoard");
        });
    } @catch (NSException *exception) {
       
    }
}
- (void) executeReboot: (NSString*) taskId data:(NSString*)data {
    @try {
        dispatch_async(dispatch_get_main_queue(), ^{
            XSReboot();
        });
    } @catch (NSException *exception) {
       
    }
}

- (void) executeTouch: (NSString*) taskId data:(NSString*)data {
    @try {
        dispatch_async(dispatch_get_main_queue(), ^{
            if(data && ![data isEqual:[NSNull null]]) {
                NSDictionary *dic = [XSHelper json2Dictionary:data];
                if (dic && ![dic isEqual:[NSNull null]]) {
                    NSNumber *x = dic[@"x"];
                    NSNumber *y = dic[@"y"];
                    float nx = [x floatValue];
                    float ny = [y floatValue];
                    //[[[XSJsApi alloc] init] tap:10 x:nx y:ny];
                }
            }
        });
    } @catch (NSException *exception) {
       
    }
}

- (void) executeUpdateKey: (NSString*) taskId data:(NSString*)data {
    [[XSPhoneConfig sharedInstance] SetApiKey:data];
}

- (void) executeKey: (NSString*) taskId data:(NSString*)data {
    @try {
        dispatch_async(dispatch_get_main_queue(), ^{
            if(data && ![data isEqual:[NSNull null]]) {
                NSDictionary *dic = [XSHelper json2Dictionary:data];
                if (dic && ![dic isEqual:[NSNull null]]) {
                    NSNumber *k = dic[@"key"];
                    long key = [k longValue];
                }
            }
        });
    } @catch (NSException *exception) {
       
    }
}


- (NSArray*) getMyApps {
    NSArray *apps = XSGetApps();
    NSMutableArray *resApps = [[NSMutableArray alloc] init];
    [apps enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (obj) {
            NSDictionary *oldDic = obj;
            NSString *appId = oldDic[@"bundleId"];
            if ([appId hasPrefix:@"com.apple."]) {
               
            } else {
                NSString *icon = @"";
                if ([oldDic objectForKey:@"icon"]) {
                    if (oldDic[@"icon"] && oldDic[@"icon"] != [NSNull null]) {
                        icon = [XSHelper base64StringFromJpgImage:oldDic[@"icon"]];
                    }
                }
                NSDictionary *dic = @{
                    @"bundleId": oldDic[@"bundleId"],
                    @"name":oldDic[@"name"],
                    @"containerPath": oldDic[@"containerPath"],
                    @"version": oldDic[@"version"],
                    @"shortVersion": oldDic[@"shortVersion"],
                    @"icon": icon,
                };
                [resApps addObject:dic];
            }
        }
    }];
    return resApps;
}

- (void)stop {
    if (_timer) {
        dispatch_source_cancel(_timer);
        _timer = nil;
    }
}

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

@end
