package com.offline.music.playermp3.media3;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;


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

import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
import androidx.media3.session.MediaSession;
import androidx.media3.session.MediaSessionService;

import com.offline.music.playermp3.helper.CommonUtils;

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

    private SimpleCache playCache, downloadCache;

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

        DynamicMediaSourceFactory customMediaSourceFactory = new DynamicMediaSourceFactory(getCacheDataSourceFactory(this));
        ProgressiveMediaSource.Factory factory = new ProgressiveMediaSource.Factory(getUrlFactory());


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


        CacheDataSource.Factory cacheDataSourceFactory = getCacheDataSourceFactory(this);
        MediaSource.Factory mediaSourceFactory = new ProgressiveMediaSource.Factory(cacheDataSourceFactory);
        CacheDataSource dataSource = cacheDataSourceFactory.createDataSource();

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


    }

    // 创建带缓存的数据源工厂
    @OptIn(markerClass = UnstableApi.class)
    private CacheDataSource.Factory getCacheDataSourceFactory(Context context) {
        DefaultDataSource.Factory factory = new DefaultDataSource.Factory(this);
        playCache = MyPlayCacheManager.getInitPlayCache(context);
        CacheDataSource.Factory factory1 = new CacheDataSource.Factory().setCache(playCache)
                .setUpstreamDataSourceFactory(factory);
//                .setUpstreamDataSourceFactory(new DefaultHttpDataSource.Factory()
//                        .setConnectTimeoutMs(16000)
//                        .setReadTimeoutMs(8000)
//                        .setUserAgent("Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0"));
        downloadCache = MyDownloadService.getDownloadCache();
        return new CacheDataSource.Factory()
                .setCache(downloadCache)
                .setUpstreamDataSourceFactory(factory1)
                .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR)
                .setEventListener(new CacheDataSource.EventListener() {
                    @Override
                    public void onCachedBytesRead(long cacheSizeBytes, long cachedBytesRead) {
//                        CommonUtils.LogMsg("-----------缓存1 DownloadCache --" + cacheSizeBytes + "----cacheSizeBytes=" + cachedBytesRead);
                    }

                    @Override
                    public void onCacheIgnored(int reason) {
//                        CommonUtils.LogMsg("-----------缓存1忽略DownloadCache =" + reason);
                    }
                });
//                .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
    }


    @OptIn(markerClass = UnstableApi.class)
    private DataSource.Factory getUrlFactory() {
        long chunkLength = 512 * 1024L;
        return new ResolvingDataSource.Factory(getCacheDataSourceFactory(this), new ResolvingDataSource.Resolver() {


            @Override
            public DataSpec resolveDataSpec(DataSpec dataSpec)  {
                CommonUtils.LogMsg("--------resolveDataSpec  dataSpec.key=" + dataSpec.key);
                return dataSpec;

//                long length = 1L;
//                String videoId = dataSpec.key;
//                long position = dataSpec.position;
//                if (dataSpec.length >= 0) {
//                    length =  dataSpec.length;
//                 }
//
//                if (downloadCache.isCached(videoId,position,length)){
//                    CommonUtils.LogMsg("--------resolveDataSpec  downloadCache" );
//                    return dataSpec;
//                }else if(playCache.isCached(videoId,position,chunkLength)){
//                    CommonUtils.LogMsg("--------resolveDataSpec  playCache" );
//                    return dataSpec;
//                }else {
//                    CommonUtils.LogMsg("--------resolveDataSpec  uri" );
//                    return dataSpec;
//                }
            }

            @Override
            public Uri resolveReportedUri(Uri uri) {
                CommonUtils.LogMsg("--------resolveDataSpec  uri=" + uri);
                return ResolvingDataSource.Resolver.super.resolveReportedUri(uri);
            }
        });
    }


    @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();
    }
}
