//  RCTMPosLookupProxy.m
//  Created by JCLEE on 2021/07/20.

#import <React/RCTLog.h>
#import "RCTMPosLookupProxy.h"
@import frameworkMPosSDK;

@interface RCTMPosLookupProxy()
@property MPosLookup* lookup;
@end

@implementation RCTMPosLookupProxy
{
    bool hasListeners;
}

+ (BOOL)requiresMainQueueSetup {
    return NO;
}

- (id)init{
    if((self=[super init])){
        _lookup = [MPosLookup new];
    }
    return self;
}

- (NSArray<NSString*>*)supportedEvents {
    return @[@"NetworkDeviceDiscoverEvent", @"BLEDeviceDiscoverEvent"];
}

RCT_EXPORT_METHOD(getBluetoothDevices:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    if(hasListeners){
        // Only send events if anyone is listening.
        [self sendEventWithName:@"EventReminder" body:@8];
    }
    NSArray<MPosDeviceInfo*>* list = [self.lookup getBluetoothDevices];
    if(![list count]){
        RCTLogInfo(@"NO_BT_DEVICES");
        reject(@"FAIL", @"NO_BT_DEVICES", nil);
        return;
    }
    
    //RCTLogInfo(@"Bixolon SDK Version: %@", [[RNBixolonBgateLibs new] getMPosLibVersion]);
    RCTLogInfo(@"bluetooth device count: %ld", (long)[list count]);
    NSString* jsonString = [self convertJSONString:list];
    resolve(jsonString);
}

RCT_EXPORT_METHOD(getNetworkDevices:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    NSArray<MPosDeviceInfo*>* list = [self.lookup getNetworkDevices];
    if(![list count]){
        RCTLogInfo(@"NO_NETWORK_DEVICES");
        reject(@"FAIL", @"NO_NETWORK_DEVICES", nil);
        return;
    }
    RCTLogInfo(@"network device count: %ld", (long)[list count]);
    NSString* jsonString = [self convertJSONString:list];
    resolve(jsonString);
}

RCT_EXPORT_METHOD(getBLEDevices:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    NSArray<MPosDeviceInfo*>* list = [self.lookup getBLEDevices];
    if(![list count]){
        RCTLogInfo(@"NO_BLE_DEVICES");
        reject(@"FAIL", @"NO_BLE_DEVICES", nil);
        return;
    }
    RCTLogInfo(@"ble device count: %ld", (long)[list count]);
    NSString* jsonString = [self convertJSONString:list];
    resolve(jsonString);
}

RCT_EXPORT_METHOD(getUSBDevices:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    if (hasListeners) {
        // Only send events if anyone is listening.
        [self sendEventWithName:@"EventReminder" body:@16];
    }

    NSArray<MPosDeviceInfo*>* list = [self.lookup getUSBDevices];

    if (![list count]) {
        RCTLogInfo(@"NO_USB_DEVICES");
        reject(@"FAIL", @"NO_USB_DEVICES", nil);
        return;
    }
    
    RCTLogInfo(@"USB Device count: %ld", (long)[list count]);
    
    NSString* jsonString = [self convertJSONString:list];

    resolve(jsonString);
}

- (NSString*) convertJSONString:(NSArray<MPosDeviceInfo*>*) list {
    if (![list count]) {
        return @"";
    }
    
    NSString* deviceInfoInJSON = @"";

    for (MPosDeviceInfo* item in list) {
        deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: @"{\"interfacetype\": "];
        deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: [NSString stringWithFormat:@"%ld", (long)item.interfaceType]];

        if(![item.name length]) {
            item.name = @"";
        }

        deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: @","];
        deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: @"\"devicename\": "];
        deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: @"\""];

        if (![item.name length]) {
            if (item.interfaceType == MPOS_INTERFACE_WIFI || item.interfaceType == MPOS_INTERFACE_ETHERNET) {
                deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: item.address];
            }
        } else {
            deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: item.name];
        }

        deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: @"\","];

        deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: @"\"address\": "];
        deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: @"\""];

        switch (item.interfaceType) {
            case MPOS_INTERFACE_WIFI:
            case MPOS_INTERFACE_ETHERNET:
                deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: item.address];
                deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: @":"];
                deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: [item.portNumber stringValue]];
                break;
            case MPOS_INTERFACE_BLE:
            case MPOS_INTERFACE_BLUETOOTH:
                deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: item.macAddress];
                break;
            case MPOS_INTERFACE_USB:
                deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: item.serialNumber];
                break;
        }

        deviceInfoInJSON = [deviceInfoInJSON stringByAppendingString: @"\"},"];
    }
    
    if ([deviceInfoInJSON length]) {
        deviceInfoInJSON = [deviceInfoInJSON substringToIndex:[deviceInfoInJSON length] - 1];

        NSString* stringWithBracket = @"[";

        stringWithBracket = [stringWithBracket stringByAppendingString: deviceInfoInJSON];
        stringWithBracket = [stringWithBracket stringByAppendingString: @"]"];
        
        deviceInfoInJSON = stringWithBracket;
    }

    RCTLogInfo(@"deviceInfoInJSON: %@", deviceInfoInJSON);

    return deviceInfoInJSON;
}

RCT_EXPORT_MODULE();

@end
