//
//  PreloadLoaderImpl.m
//

#import "PreloadLoaderImpl.h"
#import <CommonCrypto/CommonDigest.h>
#import <TTSDKFramework/TTSDKFramework.h>

@interface PreloadLoaderImpl ()
@property(nonatomic, weak) id<PreloadLoaderListener> listener;
// 使用强引用保存 listener，防止被释放
@property(nonatomic, strong) id<PreloadLoaderListener> strongListener;
@end

@implementation PreloadLoaderImpl

// 强制引用协议，确保协议被注册到运行时系统
// 这样 NSProtocolFromString(@"PreloadLoaderListener") 才能获取到协议
+ (void)load {
  // 显式引用协议，强制注册到运行时
  Protocol *protocol = @protocol(PreloadLoaderListener);
  (void)protocol; // 避免未使用变量的警告
}

- (instancetype)init {
  self = [super init];
  return self;
}

- (void)preloadURLSource:(TTVideoEngineUrlSource *)source
             preloadSize:(NSInteger)preloadSize {
  if (!source) {
    return;
  }

  if (preloadSize <= 0) {
    preloadSize = 800 * 1024;
  }

  TTVideoEnginePreloaderURLItem *preloadItem = nil;

  if ([TTVideoEnginePreloaderURLItem
          respondsToSelector:@selector(urlItemWithVideoSource:preloadSize:)]) {
    preloadItem =
        [TTVideoEnginePreloaderURLItem urlItemWithVideoSource:source
                                                  preloadSize:preloadSize];
  }

  if (!preloadItem) {
    return;
  }

  __weak typeof(self) weakSelf = self;
  if ([preloadItem respondsToSelector:@selector(setPreloadDidStart:)]) {
    preloadItem.preloadDidStart = ^(NSDictionary *info) {
      __strong typeof(weakSelf) strongSelf = weakSelf;
      // 调用 listener
      if (strongSelf.listener &&
          [strongSelf.listener respondsToSelector:@selector(onStart:)]) {
        [strongSelf.listener onStart:info];
      }
    };
  }

  if ([preloadItem respondsToSelector:@selector(setPreloadEnd:)]) {
    preloadItem.preloadEnd =
        ^(TTVideoEngineLocalServerTaskInfo *info, NSError *error) {
          __strong typeof(weakSelf) strongSelf = weakSelf;
          [strongSelf handlePreloadEnd:info error:error];
        };
  }

  if ([preloadItem respondsToSelector:@selector(setPreloadCanceled:)]) {
    preloadItem.preloadCanceled = ^{
      __strong typeof(weakSelf) strongSelf = weakSelf;
      // 调用 listener
      if (strongSelf.listener &&
          [strongSelf.listener respondsToSelector:@selector(onCancel)]) {
        [strongSelf.listener onCancel];
      }
    };
  }

  // 添加到预加载队列
  [TTVideoEngine ls_addTaskWithURLItem:preloadItem];
}

- (void)preloadVidSource:(TTVideoEngineVidSource *)source
             preloadSize:(NSInteger)preloadSize {
  if (!source) {
    return;
  }

  // 设置默认预加载大小
  if (preloadSize <= 0) {
    preloadSize = 800 * 1024;
  }

  TTVideoEnginePreloaderVidItem *preloadItem = nil;

  if ([TTVideoEnginePreloaderVidItem
          respondsToSelector:@selector(vidItemWithVideoSource:preloadSize:)]) {
    preloadItem =
        [TTVideoEnginePreloaderVidItem vidItemWithVideoSource:source
                                                  preloadSize:preloadSize];
  }

  if (!preloadItem) {
    return;
  }

  // 设置回调
  __weak typeof(self) weakSelf = self;
  if ([preloadItem respondsToSelector:@selector(setPreloadDidStart:)]) {
    preloadItem.preloadDidStart = ^(NSDictionary *info) {
      __strong typeof(weakSelf) strongSelf = weakSelf;
      // 调用 listener
      if (strongSelf.listener &&
          [strongSelf.listener respondsToSelector:@selector(onStart:)]) {
        [strongSelf.listener onStart:info];
      }
    };
  }

  if ([preloadItem respondsToSelector:@selector(setPreloadEnd:)]) {
    preloadItem.preloadEnd =
        ^(TTVideoEngineLocalServerTaskInfo *info, NSError *error) {
          __strong typeof(weakSelf) strongSelf = weakSelf;
          [strongSelf handlePreloadEnd:info error:error];
        };
  }

  if ([preloadItem respondsToSelector:@selector(setPreloadCanceled:)]) {
    preloadItem.preloadCanceled = ^{
      __strong typeof(weakSelf) strongSelf = weakSelf;
      // 调用 listener
      if (strongSelf.listener &&
          [strongSelf.listener respondsToSelector:@selector(onCancel)]) {
        [strongSelf.listener onCancel];
      }
    };
  }

  [TTVideoEngine ls_addTaskWithVidItem:preloadItem];
}

- (void)preloadVideoModelSource:(TTVideoEngineVideoModelSource *)source
                    preloadSize:(NSInteger)preloadSize {
  if (!source) {
    return;
  }

  if (preloadSize <= 0) {
    preloadSize = 800 * 1024;
  }

  TTVideoEnginePreloaderVideoModelItem *preloadItem =
      [TTVideoEnginePreloaderVideoModelItem
          videoModelItemWithVideoSource:source
                            preloadSize:preloadSize
                                 params:nil];

  if (!preloadItem) {
    return;
  }

  __weak typeof(self) weakSelf = self;
  if ([preloadItem respondsToSelector:@selector(setPreloadDidStart:)]) {
    preloadItem.preloadDidStart = ^(NSDictionary *info) {
      __strong typeof(weakSelf) strongSelf = weakSelf;
      // 调用 listener
      if (strongSelf.listener &&
          [strongSelf.listener respondsToSelector:@selector(onStart:)]) {
        [strongSelf.listener onStart:info];
      }
    };
  }

  if ([preloadItem respondsToSelector:@selector(setPreloadEnd:)]) {
    preloadItem.preloadEnd =
        ^(TTVideoEngineLocalServerTaskInfo *info, NSError *error) {
          __strong typeof(weakSelf) strongSelf = weakSelf;
          [strongSelf handlePreloadEnd:info error:error];
        };
  }

  if ([preloadItem respondsToSelector:@selector(setPreloadCanceled:)]) {
    preloadItem.preloadCanceled = ^{
      __strong typeof(weakSelf) strongSelf = weakSelf;
      // 调用 listener
      if (strongSelf.listener &&
          [strongSelf.listener respondsToSelector:@selector(onCancel)]) {
        [strongSelf.listener onCancel];
      }
    };
  }

  [TTVideoEngine ls_addTaskWithVideoModelItem:preloadItem];
}

- (void)setListener:(id<PreloadLoaderListener>)listener {
  // 防止将 self 设置为 listener，避免循环引用和无限调用
  if (listener == self) {
    return;
  }
  // 保存强引用，防止 listener 被释放
  // weak 引用用于避免循环引用，strong 引用用于保持对象存活
  // 当设置新的 listener 时，旧的 strongListener 会自动释放
  self.strongListener = listener;
  // 使用 weak 引用，避免循环引用
  _listener = listener;
}

/**
 * 从 TTVideoEngineLocalServerTaskInfo 构建数据字典
 * 参考 TTVideoEnginePreloaderVidItem+EventSink.m 的实现
 */
- (NSMutableDictionary *)buildDataFromTaskInfo:
    (TTVideoEngineLocalServerTaskInfo *)info {
  NSMutableDictionary *data = [NSMutableDictionary dictionary];
  if (info) {
    if ([info respondsToSelector:@selector(key)] && info.key &&
        info.key.length > 0) {
      [data setValue:info.key forKey:@"key"];
    }
    if ([info respondsToSelector:@selector(videoId)] && info.videoId &&
        info.videoId.length > 0) {
      [data setValue:info.videoId forKey:@"vid"];
    }
    if ([info respondsToSelector:@selector(resolution)]) {
      [data setValue:@(info.resolution) forKey:@"resolution"];
    }
    if ([info respondsToSelector:@selector(localFilePath)] &&
        info.localFilePath && info.localFilePath.length > 0) {
      [data setValue:info.localFilePath forKey:@"localFilePath"];
    }
    if ([info respondsToSelector:@selector(mediaSize)]) {
      [data setValue:@(info.mediaSize) forKey:@"mediaSize"];
    }
    if ([info respondsToSelector:@selector(cacheSizeFromZero)]) {
      [data setValue:@(info.cacheSizeFromZero) forKey:@"cacheSizeFromZero"];
    }
    if ([info respondsToSelector:@selector(decryptionKey)] &&
        info.decryptionKey && info.decryptionKey.length > 0) {
      [data setValue:info.decryptionKey forKey:@"decryptionKey"];
    }
    if ([info respondsToSelector:@selector(preloadSize)]) {
      [data setValue:@(info.preloadSize) forKey:@"preloadSize"];
    }
    if ([info respondsToSelector:@selector(taskType)]) {
      [data setValue:@(info.taskType) forKey:@"taskType"];
    }
  }
  return data;
}

/**
 * 处理预加载结束的回调
 * 统一处理 listener 回调
 */
- (void)handlePreloadEnd:(TTVideoEngineLocalServerTaskInfo *_Nullable)info
                   error:(NSError *_Nullable)error {
  BOOL success = (error == nil);

  // 调用 listener
  if (self.listener) {
    if (success) {
      if ([self.listener respondsToSelector:@selector(onSuccess:)]) {
        NSMutableDictionary *data = [self buildDataFromTaskInfo:info];
        [self.listener onSuccess:data];
      }
    } else {
      if ([self.listener respondsToSelector:@selector(onFail:)]) {
        [self.listener onFail:error];
      }
    }
  }
}

@end
