package com.hi.music.player.media3;

import android.app.Notification;
import android.content.Context;
import android.util.Pair;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.database.StandaloneDatabaseProvider;
import androidx.media3.datasource.DefaultHttpDataSource;
import androidx.media3.datasource.cache.SimpleCache;
import androidx.media3.exoplayer.offline.Download;
import androidx.media3.exoplayer.offline.DownloadCursor;
import androidx.media3.exoplayer.offline.DownloadIndex;
import androidx.media3.exoplayer.offline.DownloadManager;
import androidx.media3.exoplayer.offline.DownloadNotificationHelper;
import androidx.media3.exoplayer.offline.DownloadService;
import androidx.media3.exoplayer.scheduler.Scheduler;

import com.hi.music.player.R;
import com.hi.music.player.api.onCheckDownload;
import com.hi.music.player.helper.CommonUtils;
import com.hi.music.player.javabean.CustomerDownload;
import com.hi.music.player.ui.activity.viewmodel.VMApplication;

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

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;


@UnstableApi
public class MyDownloadService extends DownloadService {
    private static final int FOREGROUND_NOTIFICATION_ID = 1;
    private static final String CHANNEL_ID = "download_song_channel_id";

    private static DownloadManager mDownloadManager;

    private static SimpleCache downloadCache;

    public MyDownloadService() {
        super(FOREGROUND_NOTIFICATION_ID,
                DEFAULT_FOREGROUND_NOTIFICATION_UPDATE_INTERVAL,
                CHANNEL_ID, // 通知渠道 ID
                R.string.app_name, // 通知渠道名称
                0
        );
    }

    public static SimpleCache getDownloadCache() {
        return downloadCache;
    }

    public static void init(Context context, StandaloneDatabaseProvider databaseProvider) {
        if (mDownloadManager == null) {
            downloadCache = MyDownloadCacheManager.getMyCache(databaseProvider);
            DefaultHttpDataSource.Factory factory = new DefaultHttpDataSource.Factory();
            Executor downloadExecutor = Runnable::run;

            mDownloadManager = new DownloadManager(
                    context,
                    databaseProvider, // 数据库提供者
                    downloadCache,
                    factory, // 数据源工厂
                    downloadExecutor // 线程池
            );

            mDownloadManager.setMaxParallelDownloads(3); // 设置最大并行下载数

        }
    }

    public static synchronized DownloadManager getMyDownloadManager() {

        return mDownloadManager;
    }

    public static void addDownloadListener(VMApplication vmApplication) {
        mDownloadManager.addListener(new DownloadManager.Listener() {
            @Override
            public void onDownloadChanged(@NonNull DownloadManager downloadManager, Download download, @Nullable Exception finalException) {
                String id = download.request.id;


                if (download.state == Download.STATE_COMPLETED) {
                    // 下载完成
                    vmApplication.setDownloadChange(new Pair<>(true, download));
                    CommonUtils.LogMsg("----------------下载完成  id=" + id + "--thread=" + Thread.currentThread().getName());
                    updateDownloadUi(vmApplication);

                } else if (download.state == Download.STATE_FAILED) {
                    // 下载失败
                    CommonUtils.LogMsg("----------------下载失败  id=" + id + "---finalException=" + finalException.getMessage());

                    vmApplication.setDownloadChange(new Pair<>(false, download));
                }


            }

            @Override
            public void onDownloadRemoved(DownloadManager downloadManager, Download download) {
                String id = download.request.id;
                CommonUtils.LogMsg("----------------onDownloadRemoved  id=" + id);
            }
        });
    }


    public static void queryIsDownload(String videoId, onCheckDownload listener) {
        Disposable subscribe = Observable.fromCallable(() -> {
                    // 不允许返回null，所以采用CustomerDownload类包装
                    DownloadIndex downloadIndex = mDownloadManager.getDownloadIndex();
                    Download download = downloadIndex.getDownload(videoId);

                    return new CustomerDownload(download, download != null);

                }).subscribeOn(Schedulers.io())

                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(listener::onHasDownload);
    }


    /**
     * 下载完成的数量增加
     *
     * @param vmApplication
     */
    @UnstableApi
    public static void updateDownloadUi(VMApplication vmApplication) {
        Disposable subscribe = Observable.fromCallable(() -> {
                    // 第一部分操作：在IO线程
                    DownloadIndex downloadIndex = mDownloadManager.getDownloadIndex();
                    DownloadCursor downloads = downloadIndex.getDownloads(Download.STATE_COMPLETED);

                    return downloads;
                })
                .subscribeOn(Schedulers.io())
//                                .observeOn(Schedulers.computation())  // 切换到计算线程
//                                .map(result -> {
//                                    // 第二部分操作：在computation线程
//                                    return result + " -> Step 2 completed";
//                                })
                .observeOn(AndroidSchedulers.mainThread())  // 切换到主线程
                .subscribe(finalResult -> {
                    // 最终结果处理：在主线程
                    Download curDownload = null;
//                    int count = finalResult.getCount();
//                    if (finalResult.moveToLast()) {
//                        curDownload = finalResult.getDownload();
//                    }
                    List<Download> downloadList = new ArrayList<>();
                    while (finalResult.moveToNext()) {
                        Download download = finalResult.getDownload();
                        downloadList.add(download);
                    }


                    CommonUtils.LogMsg("----------------下载总数量 -count=" + downloadList.size());
                    vmApplication.setDownloadData(downloadList);

                });
    }

    @NonNull
    @Override
    protected DownloadManager getDownloadManager() {
        return getMyDownloadManager();
    }


    @Nullable
    @Override
    protected Scheduler getScheduler() {
        // 返回 null 表示不需要使用调度器
        return null;
    }

    @Override
    protected Notification getForegroundNotification(List<Download> downloads, int notMetRequirements) {
        // 构建用于显示下载进度的通知
        return buildNotification(downloads, notMetRequirements);
    }

    private Notification buildNotification(
            List<Download> downloads, int notMetRequirements) {

        return new DownloadNotificationHelper(this, CHANNEL_ID)
                .buildProgressNotification(this, R.drawable.ic_download, null, null, downloads, notMetRequirements);
    }


}
