//
//  VePlayerHelper.m
//  react-native-veplayer
//
//  Created by ByteDance on 2025/3/12.
//  Copyright © 2025 ByteDance. All rights reserved.
//

#import "BareVideo/BareVideoInfo.h"
#import "pictureInpicture/PictureInPictureManager.h"
#import <AVFoundation/AVFoundation.h>
#import <Foundation/Foundation.h>
#import <TTSDKFramework/TTSDKFramework.h>

@interface VeDefaultABRDelegate : NSObject <TTVideoEngineABRDelegate>
@property(nonatomic, assign) TTVideoEngineResolutionType wifiMax;
@property(nonatomic, assign) TTVideoEngineResolutionType mobileMax;
- (instancetype)initWithWifi:(TTVideoEngineResolutionType)wifi
                      mobile:(TTVideoEngineResolutionType)mobile;
@end

@implementation VeDefaultABRDelegate
- (instancetype)initWithWifi:(TTVideoEngineResolutionType)wifi
                      mobile:(TTVideoEngineResolutionType)mobile {
  if (self = [super init]) {
    _wifiMax = wifi;
    _mobileMax = mobile;
  }
  return self;
}

#pragma mark-- TTVideoEngineABRDelegate (Parameter Configuration)
- (TTVideoEngineStrategyABRConfig *)videoEngineAbrConfig:
    (TTVideoEngine *)videoEngine {
  TTVideoEngineStrategyABRConfig *abrConfig =
      [[TTVideoEngineStrategyABRConfig alloc] init];
  abrConfig.wifiMaxResolution = self.wifiMax;
  abrConfig.mobileMaxResolution = self.mobileMax;
  return abrConfig;
}
@end

@implementation VePlayerHelper : NSObject

static NSMapTable<NSString *, TTVideoEngine *> *playerMap;

+ (void)initialize {
  if (self == [VePlayerHelper class]) {
    playerMap = [NSMapTable strongToWeakObjectsMapTable];
  }
}

+ (void)enableSimulatorDebug:(TTVideoEngine *)videoEngine {
#if TARGET_OS_IPHONE && TARGET_OS_SIMULATOR
  if (!videoEngine) {
    return;
  }

  [videoEngine setOptionForKey:VEKKeyPlayerIsSimulator_BOOL value:@(YES)];
//   [videoEngine setOptionForKey:VEKKeyViewRenderEngine_ENUM
//                          value:@(TTVideoEngineRenderEngineOpenGLES)];
#endif
}

// 设置音频会话是否激活，即支持iOS静音模式有声音播放
+ (void)setActiveAudioSession:(BOOL)active {
#if TARGET_OS_IOS
  if (active) {
    [[AVAudioSession sharedInstance]
          setActive:YES
        withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
              error:nil];
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
                                           error:nil];
  } else {
    [[AVAudioSession sharedInstance]
        setCategory:AVAudioSessionCategorySoloAmbient
              error:nil];
    [[AVAudioSession sharedInstance]
          setActive:NO
        withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
              error:nil];
  }
#endif
}

+ (nullable TTVideoEngine *)getPlayer:(NSString *)key {
  if (!key) {
    return nil;
  }
  return [playerMap objectForKey:key];
}

+ (void)setPlayer:(TTVideoEngine *)player forKey:(NSString *)key {
  if (!key || !player) {
    return;
  }
  [playerMap setObject:player forKey:key];
}

+ (void)removePlayer:(NSString *)key {
  if (!key) {
    return;
  }
  [playerMap removeObjectForKey:key];
}

+ (nullable TTVideoEngineVideoModelSource *)
    createVideoModelSource:(NSArray<NSDictionary *> *)infoList
                       vid:(NSString *)vid
                resolution:(nullable NSNumber *)resolution {
  if (!infoList || infoList.count == 0 || !vid) {
    return nil;
  }

  NSMutableArray<BareVideoInfo *> *videoInfoList = [NSMutableArray array];

  // 遍历JSON数组，创建BareVideoInfo对象
  for (NSDictionary *info in infoList) {
    BareVideoInfo *videoInfo = [[BareVideoInfo alloc] init];

    // 从JSON中提取必要字段
    videoInfo.mainPlayUrl = info[@"mainPlayUrl"];
    videoInfo.definition = info[@"definition"];
    videoInfo.fileType = info[@"fileType"];
    videoInfo.codec = info[@"codec"];
    videoInfo.bitrate = [info[@"bitrate"] integerValue];
    videoInfo.md5 = info[@"md5"];
    videoInfo.format = info[@"format"];

    // 验证必要字段是否存在
    if (!videoInfo.mainPlayUrl || !videoInfo.definition ||
        !videoInfo.fileType || !videoInfo.codec || !videoInfo.md5) {
      NSLog(@"VePlayerHelper: Missing required fields in video info");
      continue;
    }

    [videoInfoList addObject:videoInfo];
  }

  if (videoInfoList.count == 0) {
    NSLog(@"VePlayerHelper: No valid video info found");
    return nil;
  }

  // 创建BareVideoModel
  BareVideoModel *videoModel = [[BareVideoModel alloc] init];
  videoModel.vid = vid;
  videoModel.enableAdaptive = YES; // 启用自适应切换
  videoModel.playInfoList = [videoInfoList copy];

  // 生成Engine内部使用的VideoModel类型
  TTVideoEngineModel *innerVideoModel = [videoModel engineVideoModel];

  // 构造统一播放源
  TTVideoEngineResolutionType resolutionType =
      resolution ? (TTVideoEngineResolutionType)[resolution integerValue]
                 : TTVideoEngineResolutionTypeHD;

  TTVideoEngineVideoModelSource *source =
      [[TTVideoEngineVideoModelSource alloc] initWithVid:vid
                                              resolution:resolutionType];
  source.videoModel = innerVideoModel;

  return source;
}

+ (void)setEnvBeforeStart {
  // use mdl2
  [[TTVideoEngine ls_localServerConfigure]
      setOptionForKey:@(VEMDLKeyIsEnableMDL2_BOOL)
                value:@YES];
}

+ (void)initStartupAutoSelectStrategy {
  // 1. use default config
  [TTVideoEngineStrategyAutoSelectConfig globalInitWithSDKDefaultConfig];

  // 2. enable log report
  [TTVideoEngine setGlobalForKey:VEGSKeyEngineSelectResultReport_BOOL
                           value:@(YES)];

  // 3. enable preload auto select
  [TTVideoEngine ls_localServerConfigure].isEnablePreloadAutoSelect = YES;
}

+ (void)initABRStrategy:(TTVideoEngineResolutionType)defaultABRResolution {
  /// 1. enable bandwidth detection module
  [TTVideoEngine setGlobalForKey:VEGSKeyAlgoOptionEnableModuleBandwidth
                           value:@(YES)];

  /// 2. set default resolution
  if (defaultABRResolution) {
    [TTVideoEngineStrategyABRAlgoConfig shareInstance].defaultResolution =
        defaultABRResolution;
  } else {
    [TTVideoEngineStrategyABRAlgoConfig shareInstance].defaultResolution =
        TTVideoEngineResolutionTypeHD;
  }
}

+ (void)setABRDelegate:(TTVideoEngine *)player
      wifiMaxResolution:(TTVideoEngineResolutionType)wifiMaxResolution
    mobileMaxResolution:(TTVideoEngineResolutionType)mobileMaxResolution {
  if (!player) {
    return;
  }
  player.abrDelegate =
      [[VeDefaultABRDelegate alloc] initWithWifi:wifiMaxResolution
                                          mobile:mobileMaxResolution];
}

+ (void)EnableHLSProxy {
  [TTVideoEngine.ls_localServerConfigure
      setOptionForKey:@(VEKKeyHLSProxyProtocolEnable_BOOL)
                value:@(YES)];
}

+ (void)safeCloseEngine:(TTVideoEngine *)engine stopPip:(BOOL)stopPip {
    if (!engine) return;

    void (^cleanup)(void) = ^{
        // Step 1: 先解绑 PiP — 移除 AVKit 对 AVSampleBufferDisplayLayer 的 KVO 观察
        // 必须同步执行，这正是 destroyPictureInPicture 的 dispatch_async 导致 crash 的根因
        if (stopPip) {
            PictureInPictureManager *pipManager = [PictureInPictureManager getInstance];
            [pipManager destroyPictureInPictureSync];
        }

        // Step 2: 清空所有 delegate，防止 engine 销毁期间回调到已释放的 JS 侧对象
        engine.delegate = nil;
        engine.resolutionDelegate = nil;

        // Step 3: 最后才销毁 native engine
        [engine close];
    };

    // 确保在主线程同步执行（AVKit KVO 在主线程触发，清理也必须在主线程）
    if ([NSThread isMainThread]) {
        cleanup();
    } else {
        dispatch_sync(dispatch_get_main_queue(), cleanup);
    }
}

@end
