package com.hi.music.player.media3;

import android.content.ComponentName;
import android.net.Uri;

import androidx.annotation.Nullable;
import androidx.annotation.OptIn;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MediaMetadata;
import androidx.media3.common.PlaybackException;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.session.MediaController;
import androidx.media3.session.SessionToken;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import com.hi.music.player.MusicApplication;
import com.hi.music.player.api.MediaControllerListener;
import com.hi.music.player.api.MediaControllerStatusListener;
import com.hi.music.player.api.OnHasUrlAction;
import com.hi.music.player.api.onCheckDownload;
import com.hi.music.player.api.onPlayNextListener;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.helper.MyValue;
import com.hi.music.player.javabean.CustomerDownload;
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
import com.hi.music.player.javabean.response.ResponsePlayUrl;
import com.hi.music.player.network.RetrofitManager;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

public class MyMediaControllerManager {

    private static volatile MyMediaControllerManager myMediaControllerManagerInstance;

    private MediaController mediaController;

    private MediaControllerListener mListener;

    private VMApplication mVmApplication;


    //播放列表总数量
    private List<ResponsePlayListInfo> playList;

    public static MyMediaControllerManager getInstance() {
        if (myMediaControllerManagerInstance == null) {
            synchronized (RetrofitManager.class) {
                if (myMediaControllerManagerInstance == null) {
                    myMediaControllerManagerInstance = new MyMediaControllerManager();
                }
            }
        }
        return myMediaControllerManagerInstance;
    }

    public void init(MediaControllerStatusListener statusListener) {
        SessionToken sessionToken =
                new SessionToken(MusicApplication.myApplication, new ComponentName(MusicApplication.myApplication, PlaybackService.class));
        ListenableFuture<MediaController> controllerFuture =
                new MediaController.Builder(MusicApplication.myApplication, sessionToken).buildAsync();
        controllerFuture.addListener(() -> {
            // Call controllerFuture.get() to retrieve the MediaController.
            // MediaController implements the Player interface, so it can be
            // attached to the PlayerView UI component.
//            playerView.setPlayer(controllerFuture.get());
            try {
                mediaController = controllerFuture.get();
                statusListener.onMediaControllerComplete(true);
                CommonUtils.LogMsg("=-----mediaController+" + mediaController);
            } catch (ExecutionException | InterruptedException e) {
                CommonUtils.LogErrorMsg(e.getMessage());
                statusListener.onMediaControllerComplete(false);
            }
        }, MoreExecutors.directExecutor());


    }

    public void addListener(VMApplication vmApplication, MediaControllerListener listener) {
        mVmApplication = vmApplication;
        mListener = listener;
        mediaController.addListener(new Player.Listener() {
            @Override
            public void onPlayerError(PlaybackException error) {
                mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_ERROR);
                mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CODE_ERROR);
            }

            @Override
            public void onPlaylistMetadataChanged(MediaMetadata mediaMetadata) {

            }

            @Override
            public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
                //当前媒体项发生变化，切歌
                if (mediaItem == null) {
                    //第二次进入PlayActitivity ，调用resetPlayList（），这里为null
                    return;
                }
                mListener.onChangeMusic(mediaItem);
                mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CHANGE_MUSIC);
            }

            @Override
            public void onIsPlayingChanged(boolean isPlaying) {

                if (isPlaying) {
                    mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_PLAYING);
                    mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CODE_PLAYING);
                    // TODO: 2024/10/15  自动播放完成切歌到下一首播放没有触发这里请求下一首
                    checkUrl(false);

                } else {
                    // 播放器暂停或停止
                    mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_PAUSE);
                    mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CODE_PAUSE);
                }
            }

            @Override
            public void onPlaybackStateChanged(int playbackState) {
                mListener.onPlayStatus(playbackState);
                mVmApplication.setPlayStatus(playbackState);
            }

            @Override
            public void onPositionDiscontinuity(Player.PositionInfo oldPosition, Player.PositionInfo newPosition, int reason) {
                // 快进、快退等操作
//                CommonUtils.LogMsg("=-----快进、快退+" + newPosition.positionMs);
//                        mediaControllerListener.onPlayStatus(playbackState);
            }
        });
    }

    public void checkUrl(boolean playNextNow) {
        if (mediaController.hasNextMediaItem()) {
            int nextMediaItemIndex = mediaController.getNextMediaItemIndex();
            onCallRequestUrl(nextMediaItemIndex, playNextNow, new OnHasUrlAction() {
                @Override
                public void onHasUrl() {
                    CommonUtils.LogMsg("-------------有有效URl--播放检查下一首 位置=" + nextMediaItemIndex);
                }
            });
        }
        if (mediaController.hasPreviousMediaItem()) {
            int previousMediaItemIndex = mediaController.getPreviousMediaItemIndex();
            onCallRequestUrl(previousMediaItemIndex, false, new OnHasUrlAction() {
                @Override
                public void onHasUrl() {
                    CommonUtils.LogMsg("-------------有有效URl--播放检查上一首 位置=" + previousMediaItemIndex);
                }
            });
        }
    }

    public MediaController getMediaController() {
        return mediaController;
    }

    /**
     * 针对已经下载过的数据，从download构造出MediaItem 直接替换
     * @param index
     * @param mediaItem
     */
    public void replaceMediaItem(int index, MediaItem mediaItem) {
        mediaController.replaceMediaItem(index, mediaItem);
    }

    public long getContentPos() {
        if (mediaController == null) return 0;
        return mediaController.getContentPosition();
    }

    public long getBufferPos() {
        if (mediaController == null) return 0;
        return mediaController.getBufferedPosition();
    }

    public MediaItem getCurMediaItem() {
        return mediaController.getCurrentMediaItem();
    }

    public Boolean getIsPlaying() {
        return mediaController.isPlaying();
    }

    public int getCurIndex() {
        return mediaController.getCurrentMediaItemIndex();
    }

    /**
     * //0 不循环、1 单曲循环、2 列表循环、
     *
     * @param mode
     */
    public void setMode(int mode) {
        switch (mode) {
            case 0:
                mediaController.setRepeatMode(Player.REPEAT_MODE_OFF);
                break;
            case 1:
                mediaController.setRepeatMode(Player.REPEAT_MODE_ONE);
                break;
            case 2:
                mediaController.setRepeatMode(Player.REPEAT_MODE_ALL);
                break;
        }

    }

    public int getRepeatMode() {
        return mediaController.getRepeatMode();

    }

    public String getCurVideoId() {
        MediaItem currentMediaItem = mediaController.getCurrentMediaItem();
        if (currentMediaItem != null) {
            return currentMediaItem.mediaId;
        } else {
            return null;
        }


    }

    /**
     * 更新播放列表中的音频url
     *
     * @param playUrl
     */
    @OptIn(markerClass = UnstableApi.class)
    public void UpdateAudioUrl(ResponsePlayUrl playUrl, int index) {
        for (int i = 0; i < mediaController.getMediaItemCount(); i++) {
            MediaItem mediaItemAt = mediaController.getMediaItemAt(i);
            if (mediaItemAt.mediaId.equals(playUrl.getVideoId())) {

                MediaItem.Builder builder = mediaItemAt.buildUpon();
                builder.setMediaId(playUrl.getVideoId());
                builder.setUri(playUrl.getVideoUrlMedium());
//                builder.setCustomCacheKey(playUrl.getVideoUrlMedium());
                //针对于，已经从分类合集列表页面进入播放页面的数据(只有小的封面图)
                if (mediaItemAt.mediaMetadata.artworkUri == null) {
                    MediaMetadata.Builder builder1 = mediaItemAt.mediaMetadata.buildUpon();
                    builder1.setArtworkUri(Uri.parse(playUrl.getBigCovert()));
                    builder.setMediaMetadata(builder1.build());
                }

                CharSequence title = mediaController.getMediaItemAt(i).mediaMetadata.title;
                CommonUtils.LogMsg("-------------更新播放列表中的音频--id=" + playUrl.getVideoId());
                mediaController.replaceMediaItem(i, builder.build());
                break;
            }
        }
    }

    public void setPlayList(List<ResponsePlayListInfo> playList) {
        this.playList = playList;
        addMusicPlayList(playList);
    }

    public List<ResponsePlayListInfo> getPlayList() {
        return playList;
    }

    public void resetPlayList() {
        mediaController.clearMediaItems();
    }


    /**
     * 添加播放列表（不带音频url）
     * 注意没有setUri的不会被实际添加到mediaController(mediaController.getMediaItemCount())
     * 这里setUri 一个占位
     *
     * @param listInfo
     */
    @OptIn(markerClass = UnstableApi.class)
    public void addMusicPlayList(List<ResponsePlayListInfo> listInfo) {
        playList = listInfo;
        for (int i = 0; i < listInfo.size(); i++) {
            ResponsePlayListInfo playInfo = listInfo.get(i);

            MediaItem.Builder builder = new MediaItem.Builder();
            String videoId = playInfo.getVideoId();
            //唯一标识符
            builder.setMediaId(videoId);
            builder.setUri("-------test-----");
            builder.setCustomCacheKey(videoId);
            MediaMetadata.Builder MediaMetadata_builder = new MediaMetadata.Builder();

            MediaMetadata_builder.setArtist(playInfo.getSingerName());
            MediaMetadata_builder.setDescription(playInfo.getDuration());
            MediaMetadata_builder.setDurationMs(playInfo.getDurationMs());
            if (playInfo.getCovert() != null && !playInfo.getCovert().isEmpty())
                MediaMetadata_builder.setArtworkUri(Uri.parse(playInfo.getCovert()));
            MediaMetadata_builder.setTitle(playInfo.getSongTitle());

            CommonUtils.LogMsg("----------添加播放列表  i=" + i + "---" + playInfo.getSingerName() + "-------VideoId=" + videoId + "---playInfo.getDuration()=" + playInfo.getDuration());
//        MediaMetadata_builder.setRecordingYear(Integer.parseInt(playInfo.getYear()));
            builder.setMediaMetadata(MediaMetadata_builder.build());
            mediaController.addMediaItem(builder.build());

        }

    }


    public void addMusicPlayList(MediaItem mediaItem) {
        mediaController.addMediaItem(mediaItem);
    }

    public void play() {
        if (!mediaController.isPlaying()) {
            CommonUtils.LogMsg("-----------prepare");
            mediaController.prepare();
            mediaController.play();
        }

    }

    public void pause() {
        if (mediaController.isPlaying())
            mediaController.pause();
    }

    public void stop() {
        if (mediaController.isPlaying())
            mediaController.stop();
    }

    public void playNext(onPlayNextListener listener) {
        if (mediaController.hasNextMediaItem()) {
            int nextMediaItemIndex = mediaController.getNextMediaItemIndex();

            onCallRequestUrl(nextMediaItemIndex, true, new OnHasUrlAction() {
                @Override
                public void onHasUrl() {
                    mediaController.seekToNextMediaItem();
                    mediaController.play();
                }
            });
        } else {
            listener.onPlayNext(false);
        }
    }

    public void playPrevious() {
        if (mediaController.hasPreviousMediaItem()) {

            int previousMediaItemIndex = mediaController.getPreviousMediaItemIndex();
            onCallRequestUrl(previousMediaItemIndex, true, new OnHasUrlAction() {
                @Override
                public void onHasUrl() {
                    mediaController.seekToPreviousMediaItem();
                    mediaController.play();
                }
            });

        } else {
            mediaController.seekTo(0);
            mediaController.play();
        }
    }


    /**
     * 播放指定播放列表位置的歌曲
     *
     * @param index
     */
    public void playPositionMusic(int index) {
        if (index >= mediaController.getMediaItemCount()) {
            CommonUtils.LogErrorMsg("-------------数组越界");
            return;
        }

        stop();
        mediaController.seekTo(index, 0);
        onCallRequestUrl(index, true, new OnHasUrlAction() {
            @Override
            public void onHasUrl() {
                mediaController.play();
                CommonUtils.LogMsg("-------------有有效URl--播放指定播放列表位置的歌曲 index=" + index);
            }
        });

    }

    @OptIn(markerClass = UnstableApi.class)
    private void onCallRequestUrl(int index, boolean playNow, OnHasUrlAction action) {
        MediaItem mediaItemAt = mediaController.getMediaItemAt(index);
        boolean b = CommonUtils.hasValidUri(mediaItemAt);
        if (!b) {
            //查看
            MyDownloadService.queryIsDownload(mediaItemAt.mediaId, new onCheckDownload() {
                @Override
                public void onHasDownload(CustomerDownload customerDownload) {
                    if (customerDownload.isDownload()) {
                        MediaItem mediaItem = CommonUtils.downloadToMediaItem(customerDownload.getDownloadData());
                        mediaController.replaceMediaItem(index, mediaItem);
                        CommonUtils.LogMsg("-------------请求URl 已经下载过  index" + index + "---playNow=" + playNow);
                    } else {
                        CommonUtils.LogMsg("-------------请求URl index" + index + "---playNow=" + playNow);
                        mListener.onRequestNextUri(mediaItemAt.mediaId, index, playNow);
                    }

                }
            });

        } else {
            action.onHasUrl();
        }
    }
}
