package com.yidian.shenghuoquan.newscontent.audio

import android.media.MediaPlayer
import java.lang.ref.WeakReference



class AudioPlayerManager private constructor(): IAudioControl {
    companion object {
        val instance: AudioPlayerManager by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { AudioPlayerManager() }
        const val STATUS_START = 0
        const val STATUS_PAUSE = 1
        const val STATUS_STOP = 2

    }


    private var isAutoPlay = false
    private var singleLoop = false
    private var onPrepare: (() -> Unit)? = null
    private var prepareResult: ((Boolean, Long) -> Unit)? = null
    private var onError: (() -> Unit)? = null
    private var bufferUpdate: ((Int) -> Unit)? = null
    private var onComplete: (() -> Unit)? = null
    private var audioPlayer: MediaPlayer? = null
    private var audioView:WeakReference<IAudioView>?=null
    private val audioList = mutableListOf<String>()
    private var currentIndex = 0
    private var duration:Int = 0
    private var currentStatus = STATUS_STOP
    private val prepareListener = MediaPlayer.OnPreparedListener {
        onPrepare?.invoke()
        prepareResult?.invoke(true, it.duration.toLong())
    }
    private val errorListener = MediaPlayer.OnErrorListener { mr, what, extra ->
        onError?.invoke()
        return@OnErrorListener true
    }
    private val bufferListener = MediaPlayer.OnBufferingUpdateListener {mp,percent->
        bufferUpdate?.invoke(percent)
    }
    private val completeListener = MediaPlayer.OnCompletionListener {
       if (onComplete!=null){
           onComplete?.invoke()
       }else{
           if (isAutoPlay){
               next()
           }
       }
    }

    fun setAudioList(list:MutableList<String>,index:Int = 0){
        currentIndex = index
        audioList.clear()
        audioList.addAll(list)
    }
    fun prepareAsync (url: String?=null, result: ((Boolean, Long) -> Unit)?=null) {
        val realUrl =  if (url.isNullOrEmpty()) {
            if (currentIndex>=audioList.size) null else audioList[currentIndex]
        } else url
        if (realUrl.isNullOrEmpty()) {
            result?.invoke(false,0)
            return
        }
        prepareResult = result
        if (audioPlayer == null) {
            audioPlayer = MediaPlayer()
        }
        audioPlayer?.apply {
            setDataSource(realUrl)
            setOnPreparedListener(prepareListener)
            setOnErrorListener(errorListener)
            setOnBufferingUpdateListener(bufferListener)
            setOnCompletionListener(completeListener)
            prepareAsync()
        }
    }

    override fun bindAudioView(view: IAudioView) {
        audioView = WeakReference(view)
        view.bindAudioControl(this)
    }

    override fun start(progress: Int,user:Boolean) {
        if (audioPlayer==null || audioPlayer?.duration?:0==0) return
        if (user) isAutoPlay = true
        if (progress<0){
            audioPlayer?.start()
            return
        }
        val duration = (audioPlayer!!.duration *progress.toFloat()/100 +0.5f).toInt()
        audioPlayer?.seekTo(duration)
        audioPlayer?.start()

    }

    override fun pause() {
        audioPlayer?.pause()
    }

   override fun stop() {
        audioPlayer?.stop()
    }

    override fun seekTo(progress: Int) {
       val total =  audioPlayer?.duration?:0
        if (total == 0) return
        audioPlayer?.seekTo((total * progress.toFloat()/total).toInt())

    }
    override fun isPlaying() :Boolean {
        return audioPlayer!=null && audioPlayer!!.isPlaying
    }

    override fun next() {
      if (audioPlayer?.isPlaying==true){
          audioPlayer?.stop()
      }
        audioPlayer?.reset()
        currentIndex++
        if (currentIndex>=audioList.size){
            currentIndex--
            checkPrevAndNext(currentIndex)
            return
        }
        checkPrevAndNext(currentIndex)
        audioView?.get()?.setContent("第${currentIndex+1}首")
        prepareAsync{ result,_->
            if (result){
                audioView?.get()?.setPlayEnable(true)
                if (isAutoPlay) start(0,false)
            }
        }

    }

    override fun previous() {
        if (audioPlayer?.isPlaying==true){
            audioPlayer?.stop()
        }
        audioPlayer?.reset()
        currentIndex--
        if (currentIndex<0){
            currentIndex=0
            checkPrevAndNext(currentIndex)
            return
        }
        checkPrevAndNext(currentIndex)
        audioView?.get()?.setContent("第${currentIndex+1}首")
        if (currentIndex == 0){
            audioView?.get()?.setPrevEnable(false)
        }
        prepareAsync{ result,_->
            if (result){
                audioView?.get()?.setPlayEnable(true)
                if (isAutoPlay) start(0,false)
            }
        }

    }

    private fun checkPrevAndNext(index: Int){
        if (index == 0){
            audioView?.get()?.setPrevEnable(false)
        }
        if (index>=audioList.size){
            audioView?.get()?.setNextEnable(false)
        }
        if (index>0 && index<audioList.size-1){
            audioView?.get()?.setPrevEnable(true)
            audioView?.get()?.setNextEnable(true)
        }

    }

    override fun release() {
        audioView?.clear()
        audioView=null
        onPrepare=null
        onError=null
        bufferUpdate=null
        audioPlayer?.reset()
        audioPlayer?.release()
        audioPlayer = null
    }
    fun setOnPrepareListener(onPrepare: () -> Unit) {
        this.onPrepare = onPrepare
    }

    fun setOnErrorListener(onError: () -> Unit) {
        this.onError = onError
    }
    fun setOnBufferListener(bufferUpdate: (Int) -> Unit) {
        this.bufferUpdate = bufferUpdate
    }
    fun setOnCompleteListener(onComplete: () -> Unit) {
        this.onComplete = onComplete
    }

    /**
     * 在视频页面必须停止播放音频，释放资源。在这里需要记录当前的播放状态，播放进度
     */
    fun pauseForVideo() {


    }

    /**
     * 因视频暂停音频播放后的恢复操作
     */
    fun restartAudio(){

    }

    class AudioPauseStatus{
        var playStatus:Int = STATUS_STOP
        var duration = 0



    }


}