package com.hi.music.player.media3;

import android.content.Intent;


import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.database.DatabaseProvider;
import androidx.media3.database.ExoDatabaseProvider;
import androidx.media3.database.StandaloneDatabaseProvider;
import androidx.media3.datasource.DataSource;
import androidx.media3.datasource.DataSpec;
import androidx.media3.datasource.DefaultDataSource;
import androidx.media3.datasource.DefaultDataSourceFactory;
import androidx.media3.datasource.DefaultHttpDataSource;
import androidx.media3.datasource.ResolvingDataSource;
import androidx.media3.datasource.cache.CacheDataSource;
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor;
import androidx.media3.datasource.cache.SimpleCache;
import androidx.media3.exoplayer.DefaultLoadControl;
import androidx.media3.exoplayer.ExoPlayer;

import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
import androidx.media3.extractor.ExtractorsFactory;
import androidx.media3.extractor.mkv.MatroskaExtractor;
import androidx.media3.session.MediaSession;
import androidx.media3.session.MediaSessionService;

import com.hi.music.player.MusicApplication;
import com.hi.music.player.helper.CommonUtils;

import java.io.File;
import java.io.IOException;

public class PlaybackService extends MediaSessionService {
    private MediaSession mediaSession = null;
    private ExoPlayer player;

    @OptIn(markerClass = UnstableApi.class)
    @Override
    public void onCreate() {
        super.onCreate();

        // 1. 初始化缓存
        File cacheDir = new File(getCacheDir(), "media_cache");
        long maxCacheSize = 100 * 1024 * 1024;  // 缓存大小 100MB
        StandaloneDatabaseProvider databaseProvider = new  StandaloneDatabaseProvider(this);
        SimpleCache cache = new SimpleCache(cacheDir, new LeastRecentlyUsedCacheEvictor(maxCacheSize), databaseProvider);



        DefaultHttpDataSource.Factory httpDataSourceFactory = new DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true);
// 这里的DefaultDataSource同时支持本地和HTTP请求的资源，自动实现检测 （The DefaultDataSource supports both local and Http sources. It automatically detects which one to use.）
//        DefaultDataSource.Factory defaultDataSourceFactory = new DefaultDataSourceFactory(MusicApplication.myApplication, httpDataSourceFactory);
        DefaultDataSource.Factory upstreamFactory = new DefaultDataSource.Factory(this);

        DynamicMediaSourceFactory customMediaSourceFactory = new DynamicMediaSourceFactory(upstreamFactory,cache);
//        DynamicMediaSourceFactory customMediaSourceFactory = new DynamicMediaSourceFactory(new DefaultMediaSourceFactory(new DefaultHttpDataSource.Factory()),cache);

        DefaultMediaSourceFactory defaultMediaSourceFactory1 = new DefaultMediaSourceFactory(getUrlFactory());


        // 创建 DefaultLoadControl，配置缓冲参数
        DefaultLoadControl loadControl = new DefaultLoadControl.Builder()
                .setBufferDurationsMs(10000,  // minBufferMs: 播放前的最小缓冲时间（毫秒）
                        60000,  // maxBufferMs: 最大缓冲时间（毫秒）
                        10000,  // bufferForPlaybackMs: 播放时的目标缓冲时间（毫秒）
                        5000)   // bufferForPlaybackAfterRebufferMs: 重新缓冲后的缓冲时间（毫秒)
                .build();





        player = new ExoPlayer.Builder(this)
                .setMediaSourceFactory(customMediaSourceFactory)
//                .setLoadControl(loadControl)
                .build();
        mediaSession = new MediaSession.Builder(this, player)
                .build();

//        player = new ExoPlayer.Builder(this)
//                .setWakeMode(C.WAKE_MODE_LOCAL)
////                .setMediaSourceFactory(mediaSourceFactory)
//                .setAudioAttributes(audioAttributes, true).build();
//
//        mediaSession = new MediaSession.Builder(this, player)
//                .setId(getString(R.string.app_name) + "_MusicId")
//                .setCallback(new MediaSession.Callback() {
//                    @Override
//                    public ListenableFuture<List<MediaItem>> onAddMediaItems(MediaSession mediaSession, MediaSession.ControllerInfo controller, List<MediaItem> mediaItems) {
//
//                        CommonUtils.LogMsg("--------实际添加的媒体项="+player.getMediaItemCount());
////                        player.addMediaItems(mediaItems);
//
//                        return MediaSession.Callback.super.onAddMediaItems(mediaSession, controller, mediaItems);
//                    }
//                })
//                .build();


    }

    @OptIn(markerClass = UnstableApi.class)
    private DataSource.Factory getUrlFactory() {
        CommonUtils.LogMsg("--------getUrlFactory");
        return new ResolvingDataSource.Factory(getCacheDataSource(), new ResolvingDataSource.Resolver() {
            @Override
            public DataSpec resolveDataSpec(DataSpec dataSpec) {

                CommonUtils.LogMsg("--------resolveDataSpec=" + dataSpec.key);
                return null;
            }
        });
    }


    @OptIn(markerClass = UnstableApi.class)
    private CacheDataSource.Factory getCacheDataSource() {
        // 1. 创建缓存对象
        SimpleCache simpleCache = new SimpleCache(
                new File(MusicApplication.myApplication.getCacheDir(), "media3_cache"), // 设置缓存目录
                new LeastRecentlyUsedCacheEvictor(100 * 1024 * 1024), // 设置最大缓存大小（例如 100MB）
                new StandaloneDatabaseProvider(MusicApplication.myApplication));

        // 2. 创建 DataSource.Factory，用于加载媒体资源
        DataSource.Factory dataSourceFactory = new DefaultDataSource.Factory(MusicApplication.myApplication);

        // 3. 创建 CacheDataSource.Factory，包含缓存功能
        return new CacheDataSource.Factory()
                .setCache(simpleCache)
                .setUpstreamDataSourceFactory(dataSourceFactory) // 用于从网络加载的工厂
                .setCacheWriteDataSinkFactory(null); // 默认写入缓存
    }

    @Nullable
    @Override
    public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
        return mediaSession;
    }

    @Override
    public void onTaskRemoved(@Nullable Intent rootIntent) {
        Player player = mediaSession.getPlayer();
        if (!player.getPlayWhenReady()
                || player.getMediaItemCount() == 0
                || player.getPlaybackState() == Player.STATE_ENDED) {
            // Stop the service if not playing, continue playing in the background
            // otherwise.
            stopSelf();
        }
    }

    @Override
    public void onDestroy() {
        mediaSession.getPlayer().release();
        mediaSession.release();
        mediaSession = null;
        super.onDestroy();
    }
}
