//
//  DKHelper.m
//  testHookDylib
//
//  Created by 朱德坤 on 2019/1/21.
//  Copyright © 2019 DKJone. All rights reserved.
//

#import "DKHelper.h"
@interface DKHelper(){
    BtnBlock act1;
    BtnBlock act2;
    NSArray* allFriends;
}
@end

@implementation DKHelper

+ (instancetype)shared {
    static DKHelper *helper = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        helper = [[DKHelper alloc] init];
        helper.checkFriendsEnd = true;
    });
    return helper;
}

+ (UINavigationController *)navigationContrioller{
    return ((UINavigationController *)([objc_getClass("CAppViewControllerManager") getCurrentNavigationController]));
}

+ (UIBarButtonItem *)leftNavigationItem{

    UINavigationController * navc =  [DKHelper navigationContrioller];
    for (UIViewController *vc in navc.childViewControllers) {
        UIBarButtonItem * item = vc.navigationItem.leftBarButtonItem;
        if (item) { return item; }
    }
    return nil;
}

+ (UIColor *)backgroundColor{
    return [DKHelper tableManageWithViewFrame].tableView.backgroundColor;
}

-(NSString *)groupURL{
    if (_groupURL.length) {
        return _groupURL;
    }else{
        _groupURL = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://gitee.com/DKJone/projects-configuration/raw/master/wxQrCode"] encoding:NSUTF8StringEncoding error:nil];
        return  _groupURL;
    }
}

+ (CGRect)viewFrame{
    CGFloat width =  [FUiUtil screenWidthCurOri];
    CGFloat y = [FUiUtil navigationBarHeightCurOri] + [FUiUtil normalStatusBarHeight];
    CGFloat height = [FUiUtil visibleHeight:[DKHelper navigationContrioller].viewControllers.firstObject] - y;
    return CGRectMake(0, y, width, height);

}

+ (NSArray<CContact*> *)allFriends{
    // 好友缓存为空时去数据库加载
    if (!DKHelper.shared->allFriends.count){
        NSMutableArray * friends = [NSMutableArray array];
        CContactMgr *contactMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("CContactMgr") class]];
        NSArray* contacts = [contactMgr getContactList:1 contactType:0];
        for(CContact* contact in contacts){
            if (!contact.isBrandContact && contact.m_uiSex != 0 && ![contact.m_nsUsrName containsString:@"@openim"]) {
                [friends addObject:contact];
            }
        }
        DKHelper.shared->allFriends = friends;
    }
    return DKHelper.shared->allFriends;
}

+ (NSMutableArray<WCUserComment *>*)commentUsers{
    NSMutableArray* likeCommentUsers = [NSMutableArray array];
    [DKHelper.allFriends enumerateObjectsUsingBlock:^(CContact * curAddContact, NSUInteger idx, BOOL * _Nonnull stop) {
        WCUserComment* likeComment = [[objc_getClass("WCUserComment") alloc] init];
        likeComment.username = curAddContact.m_nsUsrName;
        likeComment.nickname = curAddContact.m_nsNickName;
        likeComment.type = 2;
        likeComment.commentID = [NSString stringWithFormat:@"%lu", (unsigned long)idx];
        likeComment.createTime = [[NSDate date] timeIntervalSince1970];
        [likeCommentUsers addObject:likeComment];
        *stop = (DKHelperConfig.likeCount.integerValue == idx);
    }];
    return likeCommentUsers;
}

+ (NSMutableArray<WCUserComment *>*)commentWith:(WCDataItem *) origItem{

    NSMutableArray* origComment = origItem.commentUsers;
    if (origComment.count >= DKHelperConfig.commentCount.intValue){ return origComment;}
    NSMutableArray* newComments = [NSMutableArray array];

    [newComments addObjectsFromArray:origComment];
    NSArray<NSString *> *defaultComments = [DKHelperConfig.comments componentsSeparatedByString:@",,"];
    if (!DKHelperConfig.comments.length){ defaultComments = @[@"赞",@"👍"];}
    int timeInterval = NSDate.date.timeIntervalSince1970 - origItem.createtime;
___addComment:
    [DKHelper.allFriends enumerateObjectsUsingBlock:^(CContact * curAddContact, NSUInteger idx, BOOL * _Nonnull stop) {
        WCUserComment* newComment = [[objc_getClass("WCUserComment") alloc] init];
        newComment.username = curAddContact.m_nsUsrName;
        newComment.nickname = curAddContact.m_nsNickName;
        newComment.type = 2;
        newComment.commentID = [NSString stringWithFormat:@"%lu", (unsigned long)idx + origComment.count];
        newComment.createTime = NSDate.date.timeIntervalSince1970 - arc4random() % timeInterval ;
        newComment.content = defaultComments[arc4random() % defaultComments.count];
        [newComments addObject:newComment];
        *stop = DKHelperConfig.commentCount.intValue <= idx + origComment.count;
    }];
    if(DKHelperConfig.commentCount.intValue > newComments.count ){
        goto ___addComment;
    }

    [newComments sortUsingComparator:^NSComparisonResult(WCUserComment*  _Nonnull obj1, WCUserComment *  _Nonnull obj2) {
        return obj1.createTime < obj2.createTime ? NSOrderedAscending : NSOrderedDescending;
    }];
    return newComments;
}

+ (WCTableViewManager *)tableManageWithViewFrame{
    CGRect tableFrame = [DKHelper viewFrame];
    WCTableViewManager* manager = [[objc_getClass("WCTableViewManager") alloc] initWithFrame:tableFrame style:1];
    manager.tableView.frame = tableFrame;
    return manager;
}

+ (WCTableViewSectionManager *) sectionManage{
    return [objc_getClass("WCTableViewSectionManager") defaultSection];
}

+ (WCTableViewNormalCellManager *)cellWithSel:(SEL)sel target:(id)target title:(NSString *)title{
    return [objc_getClass("WCTableViewNormalCellManager") normalCellForSel:sel target:target title:title];
}
+ (WCTableViewNormalCellManager *)cellWithSel:(SEL)sel target:(id)target title:(NSString *)title rightValue:(NSString *)rightValue accessoryType:(long long) acctype{

    return  [objc_getClass("WCTableViewNormalCellManager") normalCellForSel:sel target:target title:title rightValue:rightValue accessoryType:acctype];
}

+ (WCTableViewNormalCellManager *)switchCellWithSel:(SEL)sel target:(id)target title:(NSString *)title switchOn:(BOOL)switchOn{

    return  [objc_getClass("WCTableViewNormalCellManager") switchCellForSel:sel target:target title:title on:switchOn];
}

+ (WCUIAlertView *)showAlertWithTitle:(NSString *)title message:(NSString *)msg btnTitle:(NSString *)btnTitle handler:(BtnBlock)handler{
    WCUIAlertView * alert = [objc_getClass("WCUIAlertView") showAlertWithTitle:title message:msg btnTitle:btnTitle target:DKHelper.shared sel:@selector(action1:)];
    DKHelper.shared->act1 = handler;
    return alert;
}

+ (WCUIAlertView *)showAlertWithTitle:(NSString *)title message:(NSString *)msg btnTitle:(NSString *)btn1 handler:(BtnBlock)handler1 btnTitle:(NSString *)btn2 handler:(BtnBlock)handler2{
    WCUIAlertView * alert = [objc_getClass("WCUIAlertView") showAlertWithTitle:title message:msg btnTitle:btn1 target:DKHelper.shared sel:@selector(action1:) btnTitle:btn2 target:DKHelper.shared sel:@selector(action2:)];
    DKHelper.shared->act1 = handler1;
    DKHelper.shared->act2 = handler2;
    return alert;

}


- (void)action1:(id)sender{
    NSArray<UIButton *> *array = [sender valueForKey:@"btnArray"];
    act1(array[0]);
}

- (void)action2:(id)sender{
    NSArray<UIButton *> *array = [sender valueForKey:@"btnArray"];
    act2(array[1]);

}
      // 发送消息
+ (void)sendMsg:(NSString *)msg toContactUsrName:(NSString *)userName {
    [DKHelper sendMsg:msg toContactUsrName:userName uiMsgType:1];
}
+ (void)sendMsg:(NSString *)msg toContactUsrName:(NSString *)userName uiMsgType:(int)type{
    CMessageWrap *wrap = [[objc_getClass("CMessageWrap") alloc] initWithMsgType:type];
    id usrName = [objc_getClass("SettingUtil") getLocalUsrName:0];
    [wrap setM_nsFromUsr:usrName];
    [wrap setM_nsContent:msg];
    [wrap setM_nsToUsr:userName];
    wrap.m_uiMesLocalID = 11;

    MMNewSessionMgr *sessionMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("MMNewSessionMgr")];
    [wrap setM_uiCreateTime:[sessionMgr GenSendMsgTime]];
    [wrap setM_uiStatus:YES];

    CMessageMgr *chatMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:objc_getClass("CMessageMgr")];
    [chatMgr AddMsg:userName MsgWrap:wrap];
}

+(BOOL)vapFileExit{
    NSString *path = [vapPath stringByAppendingPathComponent:@"launchBgm.mp3"];
    return [NSFileManager.defaultManager fileExistsAtPath:path];
}
+(void)checkFriends{
    DKHelper.shared->allFriends = @[];
    NSOperationQueue *_serialFriendCheckQueue = [[NSOperationQueue alloc] init];
    _serialFriendCheckQueue.maxConcurrentOperationCount = 1;
    DKHelper.shared.friendCheckSem = dispatch_semaphore_create(0);
    DKHelper.shared.invalidFriends = [NSMutableArray new];
    DKHelper.shared.validFriends = [NSMutableArray new];
    DKHelper.shared.notFriends = [NSMutableArray new];
    DKHelper.shared.checkFriendsEnd = NO;
    __block int currentCount = 1;
    int allCount = (int)[DKHelper allFriends].count;
    for (CContact *payUser in [DKHelper allFriends]) {
        [_serialFriendCheckQueue addOperationWithBlock:^{
            //发送检测请求
            WCPayTransferPrepayRequestStruct *payReq = [[objc_getClass("WCPayTransferPrepayRequestStruct") alloc]init];
            payReq.m_nsReceiverUserName = payUser.m_nsUsrName ;
            payReq.m_uiFeeType = 1;
            payReq.m_uiTotalFee = 1;//转账金额单位：分
            payReq.m_uiPayScene = 31;
            payReq.m_transferScene = 2;
            payReq.m_uiPayChannel = 11;
            payReq.m_nsProducetDesc = @"DKWechathelper";
            //时间戳
            long timeinterval = (long)([[NSDate date] timeIntervalSince1970] * 1000);
            payReq.placeorderReserves = [NSString stringWithFormat:@"%ld",timeinterval];
            WCPayLogicMgr *mgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("WCPayLogicMgr") class]];
            [mgr GetTransferPrepayRequest:payReq];
            NSLog(@"开始检测---%@(%@)",payUser.m_nsNickName,payUser.m_nsRemark);
            NSString *msg = [NSString stringWithFormat:@"正在检测：%@(%d/%d)",payUser.m_nsNickName,currentCount,allCount];
            [NSNotificationCenter.defaultCenter postNotificationName:@"checkFriendsEnd" object:nil userInfo:@{@"success":@NO,@"msg":msg}];
            currentCount += 1;
            //等待结果
            long result = dispatch_semaphore_wait(DKHelper.shared.friendCheckSem, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.5 * NSEC_PER_SEC)));
            if (result != 0) { // 检测超时
                // 尝试重传一次
                [mgr GetTransferPrepayRequest:payReq];
                long repeatResult = dispatch_semaphore_wait(DKHelper.shared.friendCheckSem, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.5 * NSEC_PER_SEC)));
                if(repeatResult != 0) { // 重传后依然能失败
                    [DKHelper.shared.invalidFriends addObject:payUser];
                    return;
                }
            }
            NSLog(@"检测结果---%@(%@)：%@%@",payUser.m_nsNickName,payUser.m_nsRemark,DKHelper.shared.currentCheckResult[@"retmsg"],DKHelper.shared.currentCheckResult[@"wx_error_msg"]);
            //获取到结果，处理
            NSDictionary * resultDic = DKHelper.shared.currentCheckResult;
            // 失败 retmsg = ""   retcode = 268502017 wx_error_msg = 你不是收款方好友，对方添加你为好友后才能发起转账
            // 成功 retmsg = ok   retcode = 0         wx_error_msg = ""
            if ([@"ok" isEqualToString:[resultDic valueForKey:@"retmsg"]]){
                // 可以转账
                [DKHelper.shared.validFriends addObject:payUser];
            }else if([@"268502017" isEqualToString:[resultDic valueForKey:@"retcode"]]){
                // 不是好友
                [DKHelper.shared.notFriends addObject:payUser];
            }else{
                // 其他原因失败了
                [DKHelper.shared.invalidFriends addObject:payUser];
            }

        }];
    }
    [_serialFriendCheckQueue addOperationWithBlock:^{
        // 检测结束操作
        DKHelper.shared.checkFriendsEnd = YES;
        DKHelper.shared.currentCheckResult = @{};
        [NSNotificationCenter.defaultCenter postNotificationName:@"checkFriendsEnd" object:nil userInfo:@{@"success":@YES}];
    }];
}

@end



//MARK: - WeChatRedEnvelop From:https://github.com/buginux/WeChatRedEnvelop

@implementation WeChatRedEnvelopParam

- (NSDictionary *)toParams {
    return @{
             @"msgType": self.msgType,
             @"sendId": self.sendId,
             @"channelId": self.channelId,
             @"nickName": self.nickName,
             @"headImg": self.headImg,
             @"nativeUrl": self.nativeUrl,
             @"sessionUserName": self.sessionUserName,
             @"timingIdentifier": self.timingIdentifier
             };
}
@end

@interface WBRedEnvelopParamQueue ()
@property (strong, nonatomic) NSMutableArray *queue;
@end

@implementation WBRedEnvelopParamQueue
+ (instancetype)sharedQueue {
    static WBRedEnvelopParamQueue *queue = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        queue = [[WBRedEnvelopParamQueue alloc] init];
    });
    return queue;
}

- (instancetype)init {
    if (self = [super init]) {
        _queue = [[NSMutableArray alloc] init];
    }
    return self;
}

- (void)enqueue:(WeChatRedEnvelopParam *)param {
    [self.queue addObject:param];
}

- (WeChatRedEnvelopParam *)dequeue {
    if (self.queue.count == 0 && !self.queue.firstObject) {
        return nil;
    }

    WeChatRedEnvelopParam *first = self.queue.firstObject;

    [self.queue removeObjectAtIndex:0];

    return first;
}

- (WeChatRedEnvelopParam *)peek {
    if (self.queue.count == 0) {
        return nil;
    }

    return self.queue.firstObject;
}

- (BOOL)isEmpty {
    return self.queue.count == 0;
}

@end

@interface WBReceiveRedEnvelopOperation ()

@property (assign, nonatomic, getter=isExecuting) BOOL executing;
@property (assign, nonatomic, getter=isFinished) BOOL finished;

@property (strong, nonatomic) WeChatRedEnvelopParam *redEnvelopParam;
@property (assign, nonatomic) unsigned int delaySeconds;

@end

@implementation WBReceiveRedEnvelopOperation

@synthesize executing = _executing;
@synthesize finished = _finished;

- (instancetype)initWithRedEnvelopParam:(WeChatRedEnvelopParam *)param delay:(unsigned int)delaySeconds {
    if (self = [super init]) {
        _redEnvelopParam = param;
        _delaySeconds = delaySeconds;
    }
    return self;
}

- (void)start {
    if (self.isCancelled) {
        self.finished = YES;
        self.executing = NO;
        return;
    }

    [self main];

    self.executing = YES;
    self.finished = NO;
}

- (void)main {

    [NSThread sleepForTimeInterval:self.delaySeconds/1000.0];
    WCRedEnvelopesLogicMgr *logicMgr = [[objc_getClass("MMServiceCenter") defaultCenter] getService:[objc_getClass("WCRedEnvelopesLogicMgr") class]];
    [logicMgr OpenRedEnvelopesRequest:[self.redEnvelopParam toParams]];

    self.finished = YES;
    self.executing = NO;
}

- (void)cancel {
    self.finished = YES;
    self.executing = NO;
}

- (void)setFinished:(BOOL)finished {
    [self willChangeValueForKey:@"isFinished"];
    _finished = finished;
    [self didChangeValueForKey:@"isFinished"];
}

- (void)setExecuting:(BOOL)executing {
    [self willChangeValueForKey:@"isExecuting"];
    _executing = executing;
    [self didChangeValueForKey:@"isExecuting"];
}

- (BOOL)isAsynchronous {
    return YES;
}

@end



@interface WBRedEnvelopTaskManager ()

@property (strong, nonatomic) NSOperationQueue *normalTaskQueue;
@property (strong, nonatomic) NSOperationQueue *serialTaskQueue;

@end

@implementation WBRedEnvelopTaskManager

+ (instancetype)sharedManager {
    static WBRedEnvelopTaskManager *taskManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        taskManager = [WBRedEnvelopTaskManager new];
    });
    return taskManager;
}

- (instancetype)init {
    if (self = [super init]) {
        _serialTaskQueue = [[NSOperationQueue alloc] init];
        _serialTaskQueue.maxConcurrentOperationCount = 1;

        _normalTaskQueue = [[NSOperationQueue alloc] init];
        _normalTaskQueue.maxConcurrentOperationCount = 5;
    }
    return self;
}

- (void)addNormalTask:(WBReceiveRedEnvelopOperation *)task {
    [self.normalTaskQueue addOperation:task];
}

- (void)addSerialTask:(WBReceiveRedEnvelopOperation *)task {
    [self.serialTaskQueue addOperation:task];
}

- (BOOL)serialQueueIsEmpty {
    return [self.serialTaskQueue operations].count == 0;
}

@end
