#import "VeLivePlayerMultiObserver.h"
#import <TTSDKFramework/TVLManager.h>

@interface VeLivePlayerMultiObserver ()
@property(nonatomic, strong) NSMutableDictionary *observerDict;
@property(nonatomic, strong) dispatch_queue_t observerQueue;
@property(nonatomic, strong) TVLManager *player;
@end

@implementation VeLivePlayerMultiObserver

// 单例实现
+ (instancetype)sharedInstance {
  static VeLivePlayerMultiObserver *instance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    instance = [[self alloc] init];
  });
  return instance;
}

+ (instancetype)getInstance {
  return [self sharedInstance];
}

// 初始化方法
- (instancetype)init {
  self = [super init];
  if (self) {
    _observerDict = [NSMutableDictionary dictionary];
    _observerQueue = dispatch_queue_create("com.velive.player.multiobserver",
                                           DISPATCH_QUEUE_SERIAL);
  }
  return self;
}

- (void)setupPlayer:(TVLManager *)player {
  if (self.player) {
    [self clearObservers];
  }
  self.player = player;
  [player setObserver:self];
}

// 添加观察者到字典中
- (void)addObserver:(NSString *)observerId
           observer:(id<VeLivePlayerObserver>)observer {
  if (!observer || !observerId) {
    return;
  }

  dispatch_sync(self.observerQueue, ^{
    [self.observerDict setObject:observer forKey:observerId];
  });
}

// 从字典中移除观察者
- (void)removeObserver:(NSString *)observerId {
  if (!observerId) {
    return;
  }

  dispatch_sync(self.observerQueue, ^{
    [self.observerDict removeObjectForKey:observerId];
  });
}

// 获取所有观察者
- (NSArray *)getObservers {
  __block NSArray *result = nil;
  dispatch_sync(self.observerQueue, ^{
    result = [self.observerDict allValues];
  });
  return result;
}

// 清空所有观察者
- (void)clearObservers {
  dispatch_sync(self.observerQueue, ^{
    [self.observerDict removeAllObjects];
  });
}

#pragma mark - VeLivePlayerObserver 方法实现

// 直接实现所有 VeLivePlayerObserver 协议方法，而不是依赖消息转发

- (void)onError:(TVLManager *)player error:(VeLivePlayerError *)error {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onError:error:)]) {
      [observer onError:player error:error];
    }
  }
}

- (void)onFirstVideoFrameRender:(TVLManager *)player
                   isFirstFrame:(BOOL)isFirstFrame {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onFirstVideoFrameRender:
                                                          isFirstFrame:)]) {
      [observer onFirstVideoFrameRender:player isFirstFrame:isFirstFrame];
    }
  }
}

- (void)onFirstAudioFrameRender:(TVLManager *)player
                   isFirstFrame:(BOOL)isFirstFrame {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onFirstAudioFrameRender:
                                                          isFirstFrame:)]) {
      [observer onFirstAudioFrameRender:player isFirstFrame:isFirstFrame];
    }
  }
}

- (void)onStallStart:(TVLManager *)player {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onStallStart:)]) {
      [observer onStallStart:player];
    }
  }
}

- (void)onStallEnd:(TVLManager *)player {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onStallEnd:)]) {
      [observer onStallEnd:player];
    }
  }
}

- (void)onVideoRenderStall:(TVLManager *)player stallTime:(int64_t)stallTime {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onVideoRenderStall:
                                                        stallTime:)]) {
      [observer onVideoRenderStall:player stallTime:stallTime];
    }
  }
}

- (void)onAudioRenderStall:(TVLManager *)player stallTime:(int64_t)stallTime {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onAudioRenderStall:
                                                        stallTime:)]) {
      [observer onAudioRenderStall:player stallTime:stallTime];
    }
  }
}

- (void)onResolutionSwitch:(TVLManager *)player
                resolution:(VeLivePlayerResolution)resolution
                     error:(VeLivePlayerError *)error
                    reason:(VeLivePlayerResolutionSwitchReason)reason {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector
                  (onResolutionSwitch:resolution:error:reason:)]) {
      [observer onResolutionSwitch:player
                        resolution:resolution
                             error:error
                            reason:reason];
    }
  }
}

- (void)onVideoSizeChanged:(TVLManager *)player
                     width:(int)width
                    height:(int)height {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onVideoSizeChanged:
                                                            width:height:)]) {
      [observer onVideoSizeChanged:player width:width height:height];
    }
  }
}

- (void)onReceiveSeiMessage:(TVLManager *)player message:(NSString *)message {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onReceiveSeiMessage:message:)]) {
      [observer onReceiveSeiMessage:player message:message];
    }
  }
}

- (void)onMainBackupSwitch:(TVLManager *)player
                streamType:(VeLivePlayerStreamType)streamType
                     error:(VeLivePlayerError *)error {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onMainBackupSwitch:
                                                       streamType:error:)]) {
      [observer onMainBackupSwitch:player streamType:streamType error:error];
    }
  }
}

- (void)onPlayerStatusUpdate:(TVLManager *)player
                      status:(VeLivePlayerStatus)status {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onPlayerStatusUpdate:status:)]) {
      [observer onPlayerStatusUpdate:player status:status];
    }
  }
}

- (void)onStatistics:(TVLManager *)player
          statistics:(VeLivePlayerStatistics *)statistics {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onStatistics:statistics:)]) {
      [observer onStatistics:player statistics:statistics];
    }
  }
}

- (void)onSnapshotComplete:(TVLManager *)player image:(UIImage *)image {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onSnapshotComplete:image:)]) {
      [observer onSnapshotComplete:player image:image];
    }
  }
}

- (void)onRenderVideoFrame:(TVLManager *)player
                videoFrame:(VeLivePlayerVideoFrame *)videoFrame {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onRenderVideoFrame:
                                                       videoFrame:)]) {
      // 跳过 rn-observer，只转发给其他观察者（如 pip-observer）
      NSString *observerId = nil;
      for (NSString *key in self.observerDict) {
        if ([self.observerDict objectForKey:key] == observer) {
          observerId = key;
          break;
        }
      }

      // 如果观察者ID包含 "rn"，则跳过帧处理
      if (observerId && [observerId containsString:@"rn"]) {
        continue;
      }

      [observer onRenderVideoFrame:player videoFrame:videoFrame];
    }
  }
}

- (void)onRenderAudioFrame:(TVLManager *)player
                audioFrame:(VeLivePlayerAudioFrame *)audioFrame {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector(onRenderAudioFrame:
                                                       audioFrame:)]) {
      // 跳过 rn-observer，只转发给其他观察者
      NSString *observerId = nil;
      for (NSString *key in self.observerDict) {
        if ([self.observerDict objectForKey:key] == observer) {
          observerId = key;
          break;
        }
      }

      // 如果观察者ID包含 "rn"，则跳过帧处理
      if (observerId && [observerId containsString:@"rn"]) {
        continue;
      }

      [observer onRenderAudioFrame:player audioFrame:audioFrame];
    }
  }
}

- (void)onStreamFailedOpenSuperResolution:(TVLManager *)player
                                    error:(VeLivePlayerError *)error {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector
                  (onStreamFailedOpenSuperResolution:error:)]) {
      [observer onStreamFailedOpenSuperResolution:player error:error];
    }
  }
}

- (NSData *)getDrmResourceLoaderCertificateData:(TVLManager *)player {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer respondsToSelector:@selector
                  (getDrmResourceLoaderCertificateData:)]) {
      NSData *data = [observer getDrmResourceLoaderCertificateData:player];
      if (data) {
        return data;
      }
    }
  }
  return nil;
}

- (NSString *)getDrmResourceLoaderLicenseUrl:(TVLManager *)player {
  NSArray *observers = [self getObservers];
  for (id<VeLivePlayerObserver> observer in observers) {
    if ([observer
            respondsToSelector:@selector(getDrmResourceLoaderLicenseUrl:)]) {
      NSString *url = [observer getDrmResourceLoaderLicenseUrl:player];
      if (url) {
        return url;
      }
    }
  }
  return nil;
}

@end
