package com.volcengine.reactnative.veplayer;

import android.util.Log;

import com.ss.ttvideoengine.PreloaderVidItem;
import com.ss.ttvideoengine.PreloaderVidSubtitleItem;
import com.ss.ttvideoengine.PreloaderVidSubtitleItemFetchListener;
import com.ss.ttvideoengine.PreloaderVideoModelItem;
import com.ss.ttvideoengine.Resolution;
import com.ss.ttvideoengine.SubDesInfoModel;
import com.ss.ttvideoengine.SubModelProvider;
import com.ss.ttvideoengine.TTVideoEngine;
import com.ss.ttvideoengine.abr.TTVideoABRConfig;
import com.ss.ttvideoengine.model.IVideoModel;
import com.ss.ttvideoengine.model.VideoModel;
import com.ss.ttvideoengine.model.VideoInfo;
import com.ss.ttvideoengine.selector.BestResolution;
import com.ss.ttvideoengine.source.VidPlayAuthTokenSource;
import com.ss.ttvideoengine.source.VideoModelSource;
import com.ss.ttvideoengine.strategy.StrategyManager;
import com.ss.ttvideoengine.strategy.preload.PreloadTaskFactory;
import com.ss.ttvideoengine.utils.Error;
import com.ss.ttvideoengine.abr.TTVideoABRStartupConfig;
import com.ss.ttvideoengine.abr.TTVideoABRStrategy;

import java.util.List;


public class PreloadTaskFactoryImpl {
    private static final String TAG = "PreloadTaskFactoryImpl";
    
    // Singleton instance
    private static volatile PreloadTaskFactoryImpl sInstance;
    
    private Integer mLanguageId;
    private Resolution mResolution;
    private static TTVideoABRConfig mPreloadABRConfig;
    
    private PreloadTaskFactoryImpl() {
        // Private constructor for singleton
    }
    
    /**
     * Get singleton instance
     */
    public static synchronized PreloadTaskFactoryImpl getInstance() {
        if (sInstance == null) {
            sInstance = new PreloadTaskFactoryImpl();
        }
        return sInstance;
    }
    
    public void setDefaultSubLanguageId(Integer languageId) {
        mLanguageId = languageId;
    }
    
    public Integer getDefaultSubLanguageId() {
      return mLanguageId;
    }
    
    public void setDefaultResolution(Resolution resolution) {
        mResolution = resolution;
    }

    public Resolution getDefaultResolution() {
      return mResolution;
    }
    
    /**
     * Set preload ABR config. Supports both TTVideoABRConfig and TTVideoABRStartupConfig.
     * @param config ABR config (can be TTVideoABRConfig or TTVideoABRStartupConfig)
     */
    public void setPreloadABRConfig(TTVideoABRConfig config) {
      mPreloadABRConfig = config;
    }
    
    /**
     * Set preload ABR startup config (for startup-specific ABR configuration).
     * @param config ABR startup config
     */
    public void setPreloadABRConfig(TTVideoABRStartupConfig config) {
      mPreloadABRConfig = config;
    }
    
    public TTVideoABRConfig getPreloadABRConfig() {
      return mPreloadABRConfig;
    }
    
    public void setPreloadTaskFactory() {
        StrategyManager.instance().setPreloadTaskFactory(new PreloadTaskFactory() {
            @Override
            public PreloaderVidSubtitleItem createSubtitleVidItem(VidPlayAuthTokenSource vidSource, long preloadSize) {
                final PreloaderVidSubtitleItem item = PreloadTaskFactory.super.createSubtitleVidItem(vidSource, preloadSize);
                item.setFetchEndListener(new PreloaderVidSubtitleItemFetchListener() {

                    @Override
                    public void onGetPlayInfoResult(VideoModel videoModel, Error error) {
                        if (videoModel == null) return;
  
                        if (error != null) return;
  
                        Resolution defaultResolution = getDefaultResolution();
                        if (defaultResolution == null) {
                              Log.w(TAG, "Default resolution not set, using default resolution");
                              Resolution resolutionHigh = Resolution.High;
                              Resolution res = TTVideoEngine.findDefaultResolution(videoModel, resolutionHigh);
                              final VideoInfo videoInfo = videoModel.getVideoInfo(res, false);
                              if (videoInfo != null) {
                                  item.setResolution(videoInfo.getResolution());
                              }
                          } else {
                          item.setResolution(defaultResolution);
                        }
                    }

                    @Override
                    public void onGetSubtitleInfoResult(SubDesInfoModel subDesInfoModel, Error error) {
                        if (subDesInfoModel == null) return;
                        
                        if (error != null) return; 

                        final List<SubModelProvider> subInfos = subDesInfoModel.getSubModelList();
                        if (subInfos == null || subInfos.isEmpty()) return;

                        if (getDefaultSubLanguageId() == null) {
                            Log.w(TAG, "default subtitle language_id not set, using first subtitle");
                            Integer subtitleId = subInfos.get(0).getSubId();
                            if (subtitleId != null) {
                                item.setSubtitleId(subtitleId);
                            }
                            return;
                        }
                      
                        for (SubModelProvider subInfo : subInfos) {
                          if (subInfo.getLanguageId() == getDefaultSubLanguageId()) {
                            Log.d(TAG, "preload subtitleInfo: " + subInfo.toString());
                            item.setSubtitleId(subInfo.getSubId());
                            return;
                          }
                        }
                    }
                });
                return item;
            }
            
            @Override
            public PreloaderVidItem createVidItem(VidPlayAuthTokenSource source, long preloadSize) {
                final PreloaderVidItem item = PreloadTaskFactory.super.createVidItem(source, preloadSize);
                // 逻辑同自定义预加载 VidPlayAuthTokenSource
                item.setFetchEndListener((videoModel, error) -> {
                    if (videoModel == null) {
                        Log.d(TAG, "VideoModel is null in createVidItem");
                        return;
                    } 
                    if (error != null) {
                        Log.d(TAG, "Error in createVidItem: " + error.description);
                        return;
                    }
                    Resolution defaultResolution = getDefaultResolution();
                    if (defaultResolution != null) {
                      if (defaultResolution == Resolution.Auto && mPreloadABRConfig != null) {
                        item.mResolution = TTVideoABRStrategy.preloadSelect(videoModel, mPreloadABRConfig);
                        Log.d(TAG, "PreloadTaskFactory vid item use auto resolution");
                      } else {
                        item.mResolution = defaultResolution;
                      }
                    } else {
                      Log.w(TAG, "Default resolution not set, using default resolution");
                      Resolution resolutionHigh = Resolution.High;
                      Resolution res = TTVideoEngine.findDefaultResolution(videoModel, resolutionHigh);
                      final VideoInfo videoInfo = videoModel.getVideoInfo(res, false);
                      if (videoInfo != null) {
                          item.mResolution = videoInfo.getResolution();
                      }
                    }
                });
                return item;
            }
        
            @Override
            public PreloaderVideoModelItem createVideoModelItem(VideoModelSource source, long preloadSize) {
                final PreloaderVideoModelItem item = PreloadTaskFactory.super.createVideoModelItem(source, preloadSize);
                // VideoModelSource 已经包含了 VideoModel，可以直接使用 ABR 策略选择清晰度
                IVideoModel videoModel = source.videoModel();
                if (videoModel != null) {
                  Resolution defaultResolution = getDefaultResolution();
                  if (defaultResolution != null) {
                    if (defaultResolution == Resolution.Auto && mPreloadABRConfig != null) {
                      item.mResolution = TTVideoABRStrategy.preloadSelect(videoModel, mPreloadABRConfig);
                      Log.d(TAG, "PreloadTaskFactory video model item use auto resolution");
                    } else {
                      item.mResolution = defaultResolution;
                    }
                  } else {
                    Log.w(TAG, "Default resolution not set, using default resolution nearest");
                    Resolution resolutionHigh = Resolution.High;
                    Resolution res = BestResolution.findDefaultResolution(videoModel, resolutionHigh);
                    final VideoInfo videoInfo = videoModel.getVideoInfo(res, false);
                    if (videoInfo != null) {
                      item.mResolution = videoInfo.getResolution();
                    }
                  }
                } else {
                    Log.w(TAG, "VideoModel is null in VideoModelSource");
                }
                return item;
            }
        });
    }
}
