
#import "RNReactNativeImClient.h"
#import <Export/Export.h>
#import <React/RCTEventDispatcher.h>
@interface RNReactNativeImClient() <ExportReadyStateCallback,ExportRequestStatusCallback,ExportHandler>

@end
@implementation RNReactNativeImClient{
    ExportClient *client;
    RCTPromiseResolveBlock resolve;
    RCTPromiseRejectBlock reject;
}
@synthesize bridge = _bridge;
- (dispatch_queue_t)methodQueue
{
    return dispatch_get_main_queue();
}



RCT_EXPORT_MODULE()

RCT_EXPORT_METHOD(connect : (NSString *) server Port: (NSString *) portString
                                       successHandler:(RCTPromiseResolveBlock ) resolve
                                           failHandle:(RCTPromiseRejectBlock) reject
                  )
{
    long port = [portString longLongValue];
    self->resolve = resolve;
    self->reject =reject;
    if(client == nil )
    {
        
        self->client = [[ExportClient alloc] init:server port:port readyStateCallback:(self)];
        
    }
    
    
    [self->client addMessageListener:@"/v1/message/listener" callback:self];
}
RCT_EXPORT_METHOD(setRequestProperty :(NSString *) key andValue:(NSString *) value)
{
        NSLog(@"key is %@ ,value is %@",key,value);
      [self->client setRequestProperty:key value:value];
    
}

RCT_EXPORT_METHOD(setResponseProperty:(NSString *) key andValue:(NSString *) value)
{
    [self->client setResponseProperty:key value:value];
}
RCT_EXPORT_METHOD(asyncSend :(NSDictionary *) options success:(RCTPromiseResolveBlock) resolve
                                                         fail :(RCTPromiseRejectBlock) reject)
{
    self->resolve = resolve;
    self->reject = reject;
    NSString *operator = [options objectForKey:@"operator"];
//    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:[options objectForKey:@"params"], @"params", nil];
//    NSDictionary *tempParams=(NSDictionary *)[NSJSONSerialization JSONObjectWithData:[params objectForKey:@"params"]  options:NSJSONReadingMutableContainers error:nil];
//    NSData *p = [NSJSONSerialization dataWithJSONObject:tempParams options:NSJSONWritingPrettyPrinted error:nil];
    
    [self->client asyncSend:operator param:[[options objectForKey:@"params"] dataUsingEncoding:NSUTF8StringEncoding] callback:self error:nil];
}
                              


- (void)onClose {
    NSLog(@"connection close!");
    NSLog(@"%s", __func__);
    self->reject(@"connection close!",@"closed",nil);
}

- (void)onError:(NSString *)err {
    NSLog(@"connect err:::%@",err);
    self->reject(@"connection close!",err,nil);
}

- (void)onOpen {
    NSLog(@"connect open :::");
    ^(){
       [self->client ping:3 param:nil callback:self error:nil];
    };
    
    self->resolve(@"open");
}

- (void)onEnd {
    
}

- (void)onError:(long)status message:(NSString *)message {
    NSLog(message);
}

- (void)onStart {
    
}

- (void)onSuccess:(NSData *)header body:(NSData *)body {
//
    NSDictionary *bodyDic = (NSDictionary *)[NSJSONSerialization JSONObjectWithData:body options:NSJSONReadingMutableContainers error:nil];
    NSMutableDictionary *res  = [NSMutableDictionary dictionaryWithCapacity:10];
    if(bodyDic !=nil){
         [res setObject:bodyDic forKey:@"params"];
    }else{
        [res setObject:@"success" forKey:@"params"];
    }
    NSString *string = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
    NSLog(@"send success: %@",string);
    if(bodyDic!=nil){
         self->resolve(res);
    }
   
}
- (NSArray<NSString *> *)supportedEvents
{
    return @[@"onMessage"];
}
- (void)handle:(NSData *)header body:(NSData *)body {
    
    NSDictionary *bodyDic = (NSDictionary *)[NSJSONSerialization JSONObjectWithData:body options:NSJSONReadingMutableContainers error:nil];
    NSLog(@"receive message : %@", bodyDic);
    NSMutableDictionary *res = [NSMutableDictionary dictionaryWithCapacity:10];
    NSData * jsonData = [NSJSONSerialization  dataWithJSONObject:bodyDic options:0 error:nil];
    NSString *bodyStr =[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    [res setObject:bodyStr forKey:@"params"];
    
    
    [self.bridge.eventDispatcher  sendAppEventWithName :@"onMessage" body:res];
    
}

@end
  
