//
//  XXGMQTTManager.m
//  XXGPlayKit
//
//  Created by apple on 2025/3/20.
//

#import "XXGMQTTManager.h"
#import "MQTTSessionManager.h"
#import "XXGMQTTConnectInfo.h"
#import "XXGNetworkList.h"
#import "NSObject+XXGModel.h"
#import "XXGPlayKitConfig.h"
#import "XXGMQTTTopicInfo.h"
#import "XXGMarqueeView.h"
#import "XXGWindowManager.h"
#import "XXGPlayKitCore.h"
#import "XXGAlertView.h"
#import "XXGFloatView.h"
#import "ZBObjectiveCBeaver.h"

@import StoreKit;

@interface XXGMQTTManager()<MQTTSessionManagerDelegate,XXGLiveBarrageDelegate>

@property (nonatomic, strong) XXGMQTTConnectInfo *xxpk_mqtt_connectInfo;

@property (strong, nonatomic) MQTTSessionManager *xxpk_manager;

@property (nonatomic, strong) NSMutableArray <XXGMarqueeView *>*xxpk_marqueeViewArray;

@end

@implementation XXGMQTTManager

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
}

+ (void)load {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willResignActiveNotification:) name:UIApplicationWillResignActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didBecomeActiveNotification:) name:UIApplicationDidBecomeActiveNotification object:nil];
}

/// 设备失活
+ (void)willResignActiveNotification:(NSNotification *)notification  {
    [XXGMQTTManager.shared xxpk_unsubscribeTopicsOfType:__data_core.xxpk_mqtt_exit];
}

/// 设备活跃
+ (void)didBecomeActiveNotification:(NSNotification *)notification  {
    [XXGMQTTManager.shared xxpk_subscribeTopics];
}

+ (instancetype)shared {
    static id shared = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [[super allocWithZone:NULL] init];
    });
    return shared;
}

- (void)xxpk_connect {
    [[XXGNetworkList xxpk_defaultNetwork] xxpk_networkMqtt:^(NSDictionary * _Nonnull responseObject) {
        XXGMQTTConnectInfo *info = [XXGMQTTConnectInfo xxpk_modelWithDict:responseObject[__data_core.xxpk_payload]];
        self.xxpk_mqtt_connectInfo = info;
        [self __xxpk_connectmqtt:info];
    }];
}

- (void)xxpk_disconnect {
    [self.xxpk_manager disconnectWithDisconnectHandler:nil];
}

- (void)xxpk_unsubscribeTopicsOfType:(NSString *)type {
    
    if (self.xxpk_manager.state != MQTTSessionManagerStateConnected) {
        return;
    }
    NSMutableDictionary *topicDic = [NSMutableDictionary new];
    for (NSDictionary *topic in self.xxpk_mqtt_connectInfo.xxpk_topics) {
        if (![topic[__data_core.xxpk_mqtt_unsubscribe] isEqualToString:type]) {
            topicDic[topic[__data_core.xxpk_mqtt_topic]] = topic[__data_core.xxpk_mqtt_qos];
        }
    }
    self.xxpk_manager.subscriptions = topicDic;
}

- (void)xxpk_subscribeTopics {
    if (self.xxpk_manager.state != MQTTSessionManagerStateConnected) {
        return;
    }
    NSMutableDictionary *topicDic = [NSMutableDictionary new];
    for (NSDictionary *topic in self.xxpk_mqtt_connectInfo.xxpk_topics) {
        topicDic[topic[__data_core.xxpk_mqtt_topic]] = topic[__data_core.xxpk_mqtt_qos];
    }
    self.xxpk_manager.subscriptions = topicDic;
}

- (void)__xxpk_connectmqtt:(XXGMQTTConnectInfo *)info {
    
    NSMutableDictionary *topicDic = [NSMutableDictionary new];
    for (NSDictionary *topic in info.xxpk_topics) {
        topicDic[topic[__data_core.xxpk_mqtt_topic]] = topic[__data_core.xxpk_mqtt_qos];
    }
    if (!self.xxpk_manager) {
        self.xxpk_manager = [[MQTTSessionManager alloc] initWithPersistence:MQTT_PERSISTENT
                                                         maxWindowSize:MQTT_MAX_WINDOW_SIZE
                                                           maxMessages:MQTT_MAX_MESSAGES
                                                               maxSize:MQTT_MAX_SIZE
                                            maxConnectionRetryInterval:64
                                                   connectInForeground:NO
                                                        streamSSLLevel:(NSString *)kCFStreamSocketSecurityLevelNegotiatedSSL
                                                                 queue:dispatch_get_main_queue()];
        self.xxpk_manager.delegate = self;
        self.xxpk_manager.subscriptions = topicDic;
        [self.xxpk_manager connectTo:info.xxpk_ip
                               port:[info.xxpk_port intValue]
                                tls:NO
                          keepalive:info.xxpk_keep_alive
                              clean:YES
                               auth:YES
                               user:info.xxpk_username
                               pass:info.xxpk_password
                               will:NO
                          willTopic:nil
                            willMsg:nil
                            willQos:MQTTQosLevelExactlyOnce
                     willRetainFlag:NO
                       withClientId:info.xxpk_client_id
                     securityPolicy:nil
                       certificates:nil
                      protocolLevel:MQTTProtocolVersion311
                     connectHandler:nil];
    } else {
        self.xxpk_manager.subscriptions = topicDic;
        [self.xxpk_manager updateSessionConfig:info.xxpk_ip
                                          port:[info.xxpk_port intValue]
                                          user:info.xxpk_username
                                          pass:info.xxpk_password
                                      clientId:info.xxpk_client_id
                                     keepalive:info.xxpk_keep_alive];
    }
}

// MARK: - MQTTSessionManagerDelegate
- (void)sessionManagerReconnect:(MQTTSessionManager *)sessionManager {
    [self xxpk_connect];
}
-  (void)handleMessage:(NSData *)data onTopic:(NSString *)topic retained:(BOOL)retained {
    NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
    XXGMQTTTopicInfo *topicInfo = [XXGMQTTTopicInfo xxpk_modelWithDict:jsonDic];
    NSString *type = jsonDic[__data_core.xxpk_mqtt_type];
    ZBLogInfo(__data_core.xxpk_log_mqtt_received,topic,type,jsonDic);
    
    if ([type isEqualToString:__data_core.xxpk_mqtt_type_redot]) {
        [XXGFloatView shared].xxpk_redotJson = jsonDic;
    }
    else if ([type isEqualToString:__data_core.xxpk_mqtt_type_marquee]) {
        [self __xxpk_insertMarqueeViewWithModel:topicInfo];
    }
    else if ([type isEqualToString:__data_core.xxpk_mqtt_type_alert]) {
        NSMutableArray *buttonTiles = [NSMutableArray new];
        for (NSDictionary *button in topicInfo.xxpk_alert_buttons) {
            [buttonTiles addObject:button[__data_core.xxpk_mqtt_label]];
        }
        [XXGAlertView xxpk_showAlertWithTitle:topicInfo.xxpk_title message:topicInfo.xxpk_message buttonTitles:buttonTiles completion:^(NSInteger buttonIndex) {
            NSDictionary *button = topicInfo.xxpk_alert_buttons[buttonIndex];
            NSString *action = button[__data_core.xxpk_mqtt_click][__data_core.xxpk_mqtt_action];
            if ([action isEqualToString:__data_core.xxpk_mqtt_exit]) {
                exit(0);
            }if ([action isEqualToString:__data_core.xxpk_mqtt_jump]) {
                [XXGPlayKitCore.shared xxpk_coreHandleOpenUrl:button[__data_core.xxpk_mqtt_click][__data_core.xxpk_mqtt_url]];
            }
        }];
    }
    else if ([type isEqualToString:__data_core.xxpk_mqtt_type_popup]) {
        [[XXGPlayKitCore shared] xxpk_showUIofPopup:jsonDic];
    }
    else if ([type isEqualToString:__data_core.xxpk_mqtt_type_ucenter]) {
        if ([topicInfo.xxpk_action isEqualToString:__data_core.xxpk_mqtt_open]) {
            [[XXGPlayKitCore shared] xxpk_showUIofUCenter:topicInfo.xxpk_url];
        }else {
            [[XXGPlayKitCore shared] xxpk_dissmissCurrentUI];
        }
    }
    else if ([type isEqualToString:__data_core.xxpk_mqtt_type_offline]) {
        [self xxpk_disconnect];
        if (topicInfo.xxpk_retry > 0) {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(topicInfo.xxpk_retry * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self xxpk_connect];
            });
        }
    }else if ([type isEqualToString:__data_core.xxpk_mqtt_type_apple_review]) {
        [SKStoreReviewController requestReview];
    }
}

// MARK: - XXGLiveBarrageDelegate
- (void)__xxpk_insertMarqueeViewWithModel:(XXGMQTTTopicInfo *)model {
    for (XXGMarqueeView *marqueeView in self.xxpk_marqueeViewArray) {
        if (model.xxpk_position == marqueeView.frame.origin.y) {
            [marqueeView insertMarqueeViewWithModel:model];
            [marqueeView start];
            return;
        }
    }
    CGRect fontRect = [model.xxpk_message boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObject:[UIFont systemFontOfSize:model.xxpk_style_text_font_size] forKey:NSFontAttributeName] context:nil];
    XXGMarqueeView *marqueeView = [[XXGMarqueeView alloc] init];
    CGFloat y = XXGWindowManager.shared.xxpk_firstWindow.safeAreaInsets.top + model.xxpk_position;
    marqueeView.frame = CGRectMake(0, y, [UIScreen mainScreen].bounds.size.width, fontRect.size.height+4);
    marqueeView.delegate = self;
    [XXGWindowManager.shared.xxpk_firstWindow addSubview:marqueeView];
    [marqueeView start];
    [marqueeView insertMarqueeViewWithModel:model];
    [self.xxpk_marqueeViewArray addObject:marqueeView];
}

#pragma mark - <XXGLiveBarrageDelegate>

- (void)xxpk_barrageView:(XXGLiveBarrage *)barrageView didSelectedCell:(XXGLiveBarrageCell *)cell
{
    XXGMQTTTopicInfo *marqueeModel = (XXGMQTTTopicInfo *)cell.model;
    if (marqueeModel.xxpk_click_url) {
        [XXGPlayKitCore.shared xxpk_coreHandleOpenUrl:marqueeModel.xxpk_click_url];
    }
}

- (void)xxpk_barrageViewCompletedCurrentAnimations:(XXGMarqueeView *)barrageView
{
    [barrageView removeFromSuperview];
    [self.xxpk_marqueeViewArray removeObject:barrageView];
    barrageView = nil;
}

@end
