package com.bomostory.sceneeditmodule.utils

import com.bomostory.sceneeditmodule.basicdata.Scene
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicLong

class MoviePlayer {
    interface OnMoviePlayListener {
        fun onMoviePlayViewUpdate(x: Int)
        fun onMoviePlayTimeUpdate(time: Long)
        fun onMoviePlayComplete()
    }

    companion object {
        const val INTERVAL_PERIOD: Long = 1
    }

    var scene: Scene? = null
    var musicPlayer = MusicPlayer()

    var moviePlayListener: OnMoviePlayListener? = null
    private val lastTick = AtomicLong(0L)
    private var disposable: Disposable? = null

    fun addMusic(path: String) {
        musicPlayer.add(path)
    }

    fun removeMusic(path: String){
        musicPlayer.remove(path)
    }

    fun init() {
        disposable?.apply {
            if (!isDisposed) {
                dispose()
            }
        }
        moviePlayListener?.onMoviePlayViewUpdate(0)
        moviePlayListener?.onMoviePlayTimeUpdate(0)
        lastTick.set(0)
        musicPlayer.stop()
    }

    fun play() {
        Observable.interval(INTERVAL_PERIOD, TimeUnit.MILLISECONDS)
                .map {
                    lastTick.getAndIncrement()
                }
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(object : Observer<Long> {
                    override fun onComplete() {
                        init()
                        moviePlayListener?.onMoviePlayComplete()
                    }

                    override fun onError(e: Throwable) {
                    }

                    override fun onSubscribe(d: Disposable) {
                        disposable = d

                        if (lastTick.get() == 0L) {
                            musicPlayer.play()
                        } else {
                            musicPlayer.start()
                        }
                    }

                    override fun onNext(t: Long) {
                        scene?.let {
                            it.record?.let {
                                for (track in it.tracks) {
                                    if (track.time == t) {
                                        moviePlayListener?.onMoviePlayViewUpdate(track.positionX)
                                    }
                                }

                                moviePlayListener?.onMoviePlayTimeUpdate(t)

                                if (t > (it.period / INTERVAL_PERIOD)) {
                                    disposable?.dispose()
                                    onComplete()
                                }
                            }
                        }
                    }
                })
    }

    fun pause() {
        disposable?.dispose()
        musicPlayer.pause()
    }

    fun seekTo(mSec: Int?) {
        mSec?.let {
            lastTick.set(it.toLong())
            musicPlayer.seekTo(it)
        }
    }
}