#import "TaskAuto.h"
#import "ThreadSelfManager.h"
#include <stdlib.h>

@implementation TaskAuto

@synthesize bridge = _bridge;
NSMutableDictionary *threads;

RCT_EXPORT_MODULE()

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

// Example method
// See // https://reactnative.dev/docs/native-modules-ios
RCT_REMAP_METHOD(multiply,
                 multiplyWithA:(nonnull NSNumber*)a withB:(nonnull NSNumber*)b
                 withResolver:(RCTPromiseResolveBlock)resolve
                 withRejecter:(RCTPromiseRejectBlock)reject)
{
  NSNumber *result = @([a floatValue] * [b floatValue]);

  resolve(result);
}

//Task
RCT_REMAP_METHOD(startThread,
                 name: (NSString *)name
                 resolver:(RCTPromiseResolveBlock)resolve
                 rejecter:(RCTPromiseRejectBlock)reject)
{
    if (threads == nil) {
        threads = [[NSMutableDictionary alloc] init];
      }

      int threadId = arc4random();

      NSURL *threadURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:name];
      NSLog(@"starting Thread %@", [threadURL absoluteString]);


       RCTBridge *threadBridge = [[RCTBridge alloc] initWithBundleURL:threadURL
                                                moduleProvider:nil
                                                 launchOptions:nil];

      ThreadSelfManager *threadSelf = [threadBridge moduleForName:@"ThreadSelfManager"];
      [threadSelf setThreadId:threadId];
      [threadSelf setParentBridge:self.bridge];


      [threads setObject:threadBridge forKey:[NSNumber numberWithInt:threadId]];
      resolve([NSNumber numberWithInt:threadId]);
}
RCT_EXPORT_METHOD(stopThread:(int)threadId)
{
  if (threads == nil) {
    NSLog(@"Empty list of threads. abort stopping thread with id %i", threadId);
    return;
  }

  RCTBridge *threadBridge = threads[[NSNumber numberWithInt:threadId]];
  if (threadBridge == nil) {
    NSLog(@"Thread is NIl. abort stopping thread with id %i", threadId);
    return;
  }

  [threadBridge invalidate];
  [threads removeObjectForKey:[NSNumber numberWithInt:threadId]];
}

RCT_EXPORT_METHOD(postThreadMessage: (int)threadId message:(NSString *)message)
{
  if (threads == nil) {
    NSLog(@"Empty list of threads. abort posting to thread with id %i", threadId);
    return;
  }

  RCTBridge *threadBridge = threads[[NSNumber numberWithInt:threadId]];
  if (threadBridge == nil) {
    NSLog(@"Thread is NIl. abort posting to thread with id %i", threadId);
    return;
  }

  //[threadBridge.eventDispatcher sendAppEventWithName:@"ThreadMessage" body:message];
  [self sendEventWithName:@"ThreadMessage" body:message];
  // [threadBridge.eventDispatcher sendAppEventWithName:@"ThreadMessage" body:message];
  
}

- (void)invalidate {
  if (threads == nil) {
    return;
  }

  for (NSNumber *threadId in threads) {
    RCTBridge *threadBridge = threads[threadId];
    [threadBridge invalidate];
  }

  [threads removeAllObjects];
  threads = nil;
  [super invalidate];
}

@end
