#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTConvert.h>
#import "StreamingManager.h"
#import <AVFoundation/AVFoundation.h>
#import "MediaPlayerWrapper-Swift.h"
#import <React/RCTLog.h>
#import <React/RCTConvert.h>
#import <React/RCTEventEmitter.h>

@class StreamingService;

@interface StreamingManager : RCTEventEmitter <RCTBridgeModule> {
  NSString * title;
  NSString * subTitle;
}
@property(nonatomic, strong) StreamingService * player;

@end

@implementation StreamingManager : RCTEventEmitter

RCT_EXPORT_MODULE();

-(id)init {
  static StreamingManager *sharedMyManager = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedMyManager =  [super init];
  });
  return sharedMyManager;
}

+ (id)sharedManager {
  static StreamingManager *sharedMyManager = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedMyManager =  [super init];
  });
  RCTLog(@"creating streaming manager once");
  return sharedMyManager;
}


-(void)connectNativeWithURL:(NSString *) url {
  if (!self->_player) {
    self->_player = [[StreamingService shared]init];
    [self->_player connectWithURLWithUrl:url];

    self->_player.metaDataDidChange = ^(NSArray<AVMetadataItem *> * metaData) {

      for (AVMetadataItem * metaItem in metaData) {
        if (metaItem.commonKey == AVMetadataCommonKeyTitle) {
          title = metaItem.value.description;

        } else if (metaItem.commonKey == AVMetadataCommonKeyArtist) {
          subTitle = metaItem.value.description;

        } else if([metaItem.commonKey.description isEqualToString: @"title"]){
          title = metaItem.value.description;
        }
      }
    };

    [self connectReceived];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerStatusChangedReceived:) name:@"CB_PLAYBACKSTATE" object:nil];

    [self addVolumeObserver2];
    RCTLog(@"connectNative");
  }
}

-(void) addVolumeObserver2 {
  [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(systemVolumeDidChange:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
}

- (NSArray<NSString *> *)supportedEvents {
  return @[@"CB_CONNECT", @"CB_PLAYBACKSTATE", @"CB_VOLUMECHANGED"];
}

- (void)connectReceived {
  [self sendEventWithName:@"CB_CONNECT" body:@{@"MESSAGE": @"onConnected"}];
}

- (void)playerStatusChangedReceived:(NSNotification *)notification {
  //PLAY 1
  //PAUSE 2

  NSNumber * status = notification.userInfo[@"status"];
  [self sendEventWithName:@"CB_PLAYBACKSTATE" body:@{@"STATE": status}];
}

-(void) systemVolumeDidChange:(NSNotification*)notification {

  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    float volume = AVAudioSession.sharedInstance.outputVolume;
    NSNumber * volumeNumber = [NSNumber numberWithFloat:volume];
    [self sendEventWithName:@"CB_VOLUMECHANGED" body:@{@"VOLUME": volumeNumber}];
  });
}

RCT_EXPORT_METHOD(connectWithURL:(NSString *) streamingURL) {
  [self connectNativeWithURL:streamingURL];
  RCTLog(@"connect");
}
RCT_EXPORT_METHOD(play:(NSString*)url) {
  [self->_player playWithUrl:url];
  RCTLog(@"play");
}
RCT_EXPORT_METHOD(pause) {
  [self->_player pause];
  RCTLog(@"pause");
}
RCT_EXPORT_METHOD(rewind) {
  [self->_player backward];
  RCTLog(@"rewind");
}
RCT_EXPORT_METHOD(forward) {
  [self->_player forward];
  RCTLog(@"forward");
}

RCT_EXPORT_METHOD(isPlaying:(RCTResponseSenderBlock)callback) {
  BOOL isPlaying = [self->_player isPlaying];
  NSNumber * status;
  if (isPlaying) {
    status = @1;
  } else {
    status = @2;
  }
  callback(@[status]);
}
RCT_EXPORT_METHOD(postNotification:(NSString*)songName:(NSString*)showName:(NSString*)imageUrl) {
  [[NSNotificationCenter defaultCenter] postNotificationName:@"lockScreen" object:@{@"Song":songName,@"Show":showName,@"image":imageUrl}];
}
RCT_EXPORT_METHOD(setVolume:(float)volumeLevel) {
  RCTLog(@"xcode set volume %f",volumeLevel);
  [self->_player setVolumeWithValue:volumeLevel];
}

RCT_EXPORT_METHOD(getVolume: (RCTResponseSenderBlock)callback) {
  float volume = [self->_player getVolume];
  NSNumber * volumeNumber = [NSNumber numberWithFloat:volume];
  callback(@[volumeNumber]);
}

@end
