package com.yidianling.muse.activity

import android.content.Intent
import android.media.MediaPlayer
import android.os.Bundle
import android.view.View
import android.widget.SeekBar
import com.alibaba.android.arouter.facade.annotation.Route
import com.bumptech.glide.Glide
import com.ydl.webview.H5Params
import com.ydl.webview.NewH5Activity
import com.ydl.ydlcommon.base.BaseActivity
import com.ydl.ydlcommon.bean.StatusBarOptions
import com.ydl.ydlcommon.data.http.ThrowableConsumer
import com.ydl.ydlcommon.event.MeditationEvent
import com.ydl.ydlcommon.utils.StatusBarUtils.Companion.setTransparentForImageView
import com.ydl.ydlcommon.utils.StatusBarUtils.Companion.statusBarLightMode
import com.ydl.ydlcommon.utils.Utils
import com.ydl.ydlcommon.utils.remind.ToastHelper.Companion.show
import com.yidianling.home.http.MuseHttp
import com.yidianling.muse.R
import com.yidianling.muse.helper.MediaPlayerManager
import com.yidianling.muse.utils.MediaPlayerTimeUtil
import com.yidianling.muse.widget.QuitMeditationDialog
import com.yidianling.muse.widget.ShareMeditationDialog
import de.greenrobot.event.EventBus
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_play_meditation.*
import kotlinx.android.synthetic.main.activity_play_meditation.iv_close
import kotlinx.android.synthetic.main.activity_play_meditation.tv_title
import kotlinx.android.synthetic.main.layout_meditation_play_float_view.*
import kotlinx.android.synthetic.main.player_control_view.*
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt


@Route(path = "/muse/play")
class PlayMeditationActivity : BaseActivity() {

    private var meditationId: Long? = null
    private var meditationType: Int? = null
    private var mediaId: Long? = null
    private var mediaUrl = ""
    private var mediaCoverUrl = ""

    private var businessType = 0

    private var mediaListLink: String? = null

    private val newPath =
        "http://file.diyring.cc/UserRingWorksFile/0/50284096.mp3"

    private var shareTitle = ""
    private var shareUrl = ""
    private var shareContent = ""
    private var shareImageUrl = ""

    private var collected = false
    private var isPlaying = false

    private var shareDialog: ShareMeditationDialog? = null
    private var quitDialog: QuitMeditationDialog? = null

    private var mTimer = Timer()
    private var mMediaPlayer: MediaPlayer? = null

    private var duration = 0

    private var isSeekbarChanging = false

    private var mDisposable: Disposable? = null
    private var mObservable: Observable<Long>? = null
    private var mObserver: Observer<Long>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        setTransparentForImageView(this, null)
        statusBarLightMode(this)
        super.onCreate(savedInstanceState)

        mMediaPlayer = MediaPlayerManager.getInstance(this)?.getMediaPlayer()

        EventBus.getDefault().register(this)

        mediaId = intent?.getLongExtra("MEDIA_ID", 0L)
        meditationId = intent?.getLongExtra("MEDITATION_ID", 0L)
        meditationType = intent?.getIntExtra("MEDITATION_TYPE", 0)
        mediaUrl = intent?.getStringExtra("MEDIA_URL") ?: ""
        mediaCoverUrl = intent?.getStringExtra("MEDIA_COVER_URL") ?: ""

        initView()
        getData()
    }

    override fun initDataAndEvent() {

    }

    private fun getData() {
        updateUIByMeditationType()
        if (meditationType == null || (mediaId == null && meditationType != 0)) {
            return
        }

//        声音详情
        if (meditationType == 0) {
            MuseHttp.getInstance().getPureMusicPlayDetail(
                meditionType = meditationType!!,
                meditationId = meditationId!!
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(Consumer {
                    if (it.code.equals("200") && it.data != null) {
                        val module = it.data
                        val currentMediaId = module.mediaId
                        mediaListLink = module.playDetailUrl
                        module.mediaList?.forEach { meditationPlayBean ->
                            if (meditationPlayBean.mediaId == currentMediaId) {
                                mediaId = module?.mediaId ?: 0L
                                val title = meditationPlayBean.title ?: "未知标题"
                                val desc = meditationPlayBean.desc ?: ""

                                val mediaUrl = meditationPlayBean.mediaUrl

                                val currentPosition = meditationPlayBean.broadcastTime

                                businessType = meditationPlayBean.businessType

                                val status = meditationPlayBean.status

                                collected = status == 1

                                tv_title.text = title
                                tv_content.text = desc

                                shareTitle = title
                                shareContent = desc
                                shareUrl = mediaUrl

                                iv_collect.setImageResource(
                                    if (status == 0) {
                                        R.drawable.icon_play_meditation_collect
                                    } else {
                                        R.drawable.icon_meditation_collected
                                    }
                                )

                                initMediaPlayer(mediaUrl, currentPosition)
                            }
                        }
                    }
                }, object : ThrowableConsumer() {
                    override fun accept(msg: String) {
                        show(msg)
                    }
                })
        } else if (meditationType == 1) {
            MuseHttp.getInstance().getMeditationPlayDetail(
                meditionType = 1,
                mediaId = mediaId!!,
                meditationId = meditationId!!
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(Consumer {

                    if (it.code.equals("200") && it.data != null) {

                        val module = it.data
                        val currentMediaId = module.mediaId
                        module.mediaList?.forEach { meditationPlayBean ->
                            if (meditationPlayBean.mediaId == currentMediaId) {
                                mediaId = module?.mediaId ?: 0L
                                val title = meditationPlayBean.title
                                val desc = meditationPlayBean.desc ?: ""

                                val bgImageUrl = meditationPlayBean.coverImageUrl

                                Glide.with(this)
                                    .load(bgImageUrl)
                                    .into(iv_bg)

                                val mediaUrl = meditationPlayBean.mediaUrl

                                val currentPosition = meditationPlayBean.broadcastTime

                                businessType = meditationPlayBean.businessType

                                val status = meditationPlayBean.status

                                collected = status == 1

                                tv_title.text = title
                                tv_content.text = desc

                                shareTitle = title
                                shareContent = desc
                                shareUrl = mediaUrl

                                iv_collect.setImageResource(
                                    if (status == 0) {
                                        R.drawable.icon_play_meditation_collect
                                    } else {
                                        R.drawable.icon_meditation_collected
                                    }
                                )

                                initMediaPlayer(mediaUrl, currentPosition)
                            }
                        }
                    }
                }, object : ThrowableConsumer() {
                    override fun accept(msg: String) {
                        show(msg)
                    }
                })
        }
    }

    private fun updateUIByMeditationType() {
//        声音类型
        if (meditationType == 0) {
            exo_rew.visibility = View.GONE
            exo_ffwd.visibility = View.GONE
            exo_prev.visibility = View.GONE
            exo_next.visibility = View.GONE
            iv_time_off.visibility = View.GONE
            tv_time_off.visibility = View.GONE

            ll_pure_music_time_off.visibility = View.VISIBLE
            iv_pure_music_list.visibility = View.VISIBLE

        } else {
            exo_rew.visibility = View.VISIBLE
            exo_ffwd.visibility = View.VISIBLE
            exo_prev.visibility = View.VISIBLE
            exo_next.visibility = View.VISIBLE
            iv_time_off.visibility = View.VISIBLE
            tv_time_off.visibility = View.VISIBLE

            ll_pure_music_time_off.visibility = View.GONE
            iv_pure_music_list.visibility = View.GONE
        }

        initClickListener()

    }

    private fun initClickListener() {
        iv_pure_music_list.setOnClickListener {
            if (Utils.isFastClick()) {
                //防止连击
                return@setOnClickListener
            }
            if (!mediaListLink.isNullOrBlank()) {
                NewH5Activity.start(this, H5Params(mediaListLink!!, null))
            }
        }

        iv_collect.setOnClickListener {
            if (meditationId == null || mediaId == null) return@setOnClickListener
            MuseHttp.getInstance().collectMeditation(
                meditationId = meditationId!!,
                mediaId = mediaId!!,
                status = if (collected) 0 else 1, businessType = businessType
            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ result ->
                    if (result != null && result.code == "200") {
                        collected = !collected
                        if (collected) {
                            show("收藏成功！")
                            iv_collect.setImageResource(R.drawable.icon_meditation_collected)
                        } else {
                            show("取消收藏！")
                            iv_collect.setImageResource(R.drawable.icon_play_meditation_collect)
                        }
                    } else {
                        show("操作失败！")
                    }
                }, {
                    object : ThrowableConsumer() {
                        override fun accept(msg: String) {
                            show(msg)
                        }
                    }
                })
        }
    }

    override fun layoutResId(): Int {
        return R.layout.activity_play_meditation
    }

    override fun getStatusViewOptions(): StatusBarOptions {
        return StatusBarOptions(true, false)
    }

    private fun initView() {

        shareImageUrl = mediaCoverUrl

        Glide.with(this)
            .load(mediaCoverUrl)
            .into(iv_bg)

        iv_close.setOnClickListener {
            if (quitDialog == null) {
                quitDialog = QuitMeditationDialog.newInstance()
            }
            if (quitDialog != null && quitDialog?.isAdded == false) {
                quitDialog?.setListener(object : QuitMeditationDialog.ClickListener {
                    override fun quit() {
                        stopPlay()
                        if (meditationId != null && mediaId != null) {
                            MuseHttp.getInstance().postMeditationPlayRecord(
                                meditationId = meditationId!!.toInt(),
                                isQuit = 1, mediaId = mediaId!!,
                                playTime = (seekbar_play_progress.progress / 1000.00).roundToInt(),
                                isComplete = 0
                            )
                                .subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribe({
                                    finish()
                                }, {
                                    object : ThrowableConsumer() {
                                        override fun accept(msg: String) {
                                            finish()
                                        }
                                    }
                                })
                        } else {
                            finish()
                        }
                    }
                })
                quitDialog?.show(supportFragmentManager, QuitMeditationDialog.TAG)
            }
        }

        iv_back.setOnClickListener {
            finish()
        }

        iv_share.setOnClickListener {
            if (shareDialog == null) {
                shareDialog = ShareMeditationDialog
                    .newInstance(
                        shareTitle = shareTitle,
                        shareContent = shareContent,
                        shareUrl = shareUrl,
                        shareImageUrl = shareImageUrl)
            }
            if (shareDialog != null && shareDialog?.isAdded == false) {
                shareDialog?.show(supportFragmentManager, ShareMeditationDialog.TAG)
            }

        }

        iv_time_off.setOnClickListener {
            startActivityForResult(
                Intent(this, MeditationTimeOffActivity::class.java),
                request_code
            )
        }

        ll_pure_music_time_off.setOnClickListener {
            startActivityForResult(
                Intent(this, MeditationTimeOffActivity::class.java),
                request_code
            )
        }

        exo_play.setOnClickListener {
            if (isPlaying) {
                mMediaPlayer?.pause()
                if (meditationId == null || mediaId == null) return@setOnClickListener
                postPlayRecord(
                    isQuit = 0,
                    playTime = (seekbar_play_progress.progress / 1000.00).roundToInt(),
                    isComplete = 0
                )
            } else {
                val duration = mMediaPlayer?.duration

                MediaPlayerManager.getInstance(this@PlayMeditationActivity)?.play()

                if (duration != null) {
                    seekbar_play_progress.max = duration
                }
                mTimer.schedule(object : TimerTask() {
                    override fun run() {
                        if (!isSeekbarChanging) {
                            seekbar_play_progress.progress = MediaPlayerManager
                                .getInstance(this@PlayMeditationActivity)
                                ?.getMediaPlayer()?.currentPosition ?: 0
                        }
                    }
                }, 0, 50)

            }
            isPlaying = !isPlaying
            if (isPlaying) {
                exo_play.setImageResource(R.drawable.icon_pause_play)
            } else {
                exo_play.setImageResource(R.drawable.icon_pause_meditation)
            }

        }

        exo_prev.setOnClickListener {
            if (meditationId == null || mediaId == null) return@setOnClickListener
            postPlayRecord(isQuit = 0, playTime = 0, isComplete = 0)

            MediaPlayerManager.getInstance(this)?.setAudioPath(newPath)
            isPlaying = if (MediaPlayerManager
                    .getInstance(this@PlayMeditationActivity)?.getMediaPlayer()?.isPlaying == true
            ) {
                exo_play.setImageResource(R.drawable.icon_pause_play)
                if (duration != null) {
                    seekbar_play_progress.max = duration
                }
                mTimer.schedule(object : TimerTask() {
                    override fun run() {
                        seekbar_play_progress.progress = MediaPlayerManager
                            .getInstance(this@PlayMeditationActivity)
                            ?.getMediaPlayer()?.currentPosition ?: 0
                    }
                }, 0, 50)
                true
            } else {
                exo_play.setImageResource(R.drawable.icon_pause_meditation)
                false
            }
        }

        exo_next.setOnClickListener {
            if (meditationId == null || mediaId == null) return@setOnClickListener
            postPlayRecord(isQuit = 0, playTime = 0, isComplete = 0)

            MediaPlayerManager.getInstance(this)?.setAudioPath(newPath)
            isPlaying = if (MediaPlayerManager
                    .getInstance(this@PlayMeditationActivity)?.getMediaPlayer()?.isPlaying == true
            ) {
                exo_play.setImageResource(R.drawable.icon_pause_play)
                if (duration != null) {
                    seekbar_play_progress.max = duration
                }
                mTimer.schedule(object : TimerTask() {
                    override fun run() {
                        if (!isSeekbarChanging) {
                            seekbar_play_progress.progress = MediaPlayerManager
                                .getInstance(this@PlayMeditationActivity)
                                ?.getMediaPlayer()?.currentPosition ?: 0
                        }
                    }
                }, 0, 50)
                true
            } else {
                exo_play.setImageResource(R.drawable.icon_pause_meditation)
                false
            }
        }

        exo_rew.setOnClickListener {
            val currentPosition = MediaPlayerManager
                .getInstance(this@PlayMeditationActivity)?.getMediaPlayer()?.currentPosition
            val seekPosition = 0.coerceAtLeast(currentPosition?.minus(15000) ?: 0)
            MediaPlayerManager.getInstance(this@PlayMeditationActivity)?.getMediaPlayer()
                ?.seekTo(seekPosition)

        }

        exo_ffwd.setOnClickListener {

            val currentPosition = MediaPlayerManager
                .getInstance(this@PlayMeditationActivity)?.getMediaPlayer()?.currentPosition
            val seekPosition = duration.coerceAtMost(currentPosition?.plus(15000) ?: 0)
            MediaPlayerManager
                .getInstance(this@PlayMeditationActivity)?.getMediaPlayer()?.seekTo(seekPosition)

        }

        seekbar_play_progress.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                if (mMediaPlayer != null) {
                    val totalDuration = mMediaPlayer!!.duration / 1000
                    val position = mMediaPlayer!!.currentPosition
                    exo_position.text = MediaPlayerTimeUtil.calculateTime(position / 1000)
                    exo_duration.text = MediaPlayerTimeUtil.calculateTime(totalDuration)
                }

            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {
                isSeekbarChanging = true
            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
                isSeekbarChanging = false
                seekBar?.progress?.let {
                    MediaPlayerManager.getInstance(this@PlayMeditationActivity)?.seekTo(
                        it
                    )
                    if (mMediaPlayer != null) {
                        exo_position.text = MediaPlayerTimeUtil.calculateTime(
                            mMediaPlayer!!.currentPosition / 1000
                        )
                    }

                }
            }

        })

        mMediaPlayer?.setOnCompletionListener {
            isPlaying = if (it.isPlaying) {
                exo_play.setImageResource(R.drawable.icon_pause_play)
                true
            } else {
                exo_play.setImageResource(R.drawable.icon_pause_meditation)
                false
            }
            if (mMediaPlayer?.isPlaying == true){
                mMediaPlayer?.pause()
            }
        }

    }

    private fun postPlayRecord(isQuit: Int, playTime: Int, isComplete: Int) {
        MuseHttp.getInstance().postMeditationPlayRecord(
            meditationId = meditationId!!.toInt(),
            isQuit = isQuit, mediaId = mediaId!!,
            playTime = playTime,
            isComplete = isComplete
        )
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({

            }, {
                object : ThrowableConsumer() {
                    override fun accept(msg: String) {

                    }
                }
            })
    }

    private fun initMediaPlayer(path: String, current: Int) {

        if (MediaPlayerManager.getInstance(this)?.getAudioPath() != null
            && MediaPlayerManager.getInstance(this)?.getAudioPath() == path
        ) {
            MediaPlayerManager.getInstance(this)?.play()

            if (mMediaPlayer?.isPlaying == true) {
                exo_play.setImageResource(R.drawable.icon_pause_play)
                true
            } else {
                exo_play.setImageResource(R.drawable.icon_pause_meditation)
                false
            }

            val currentPosition = mMediaPlayer?.currentPosition
            duration = mMediaPlayer?.duration ?: 0
            if (current > 0) {
                mMediaPlayer?.seekTo(current * 1000)
                seekbar_play_progress.max = duration
                seekbar_play_progress.progress = current
                exo_position.text = MediaPlayerTimeUtil.calculateTime(current)
            } else if (currentPosition != null) {
                seekbar_play_progress.max = duration
                seekbar_play_progress.progress = current
                exo_position.text = MediaPlayerTimeUtil.calculateTime(currentPosition / 1000)
            }
            exo_duration.text = MediaPlayerTimeUtil.calculateTime(duration / 1000)

            seekbar_play_progress.max = duration
            mTimer.schedule(object : TimerTask() {
                override fun run() {
                    if (!isSeekbarChanging) {
                        seekbar_play_progress.progress = mMediaPlayer?.currentPosition ?: 0
                    }
                }
            }, 0, 50)

        } else {
            MediaPlayerManager.getInstance(this)?.setAudioPath(path)
            MediaPlayerManager.getInstance(this)
                ?.setOnPreparedListener(object : MediaPlayerManager.OnMediaPlayerManagerListener {
                    override fun onPrepared(mediaPlayer: MediaPlayer) {
                        MediaPlayerManager.getInstance(this@PlayMeditationActivity)?.play()

                        if (mMediaPlayer?.isPlaying == true) {
                            exo_play.setImageResource(R.drawable.icon_pause_play)
                        } else {
                            exo_play.setImageResource(R.drawable.icon_pause_meditation)
                        }

                        val currentPosition = mMediaPlayer?.currentPosition
                        duration = mMediaPlayer?.duration ?: 0
                        if (current > 0) {
                            mMediaPlayer?.seekTo(current * 1000)
                            seekbar_play_progress.max = duration
                            seekbar_play_progress.progress = current
                            exo_position.text = MediaPlayerTimeUtil.calculateTime(current)
                        } else if (currentPosition != null) {
                            seekbar_play_progress.max = duration
                            seekbar_play_progress.progress = current
                            exo_position.text =
                                MediaPlayerTimeUtil.calculateTime(currentPosition / 1000)
                        }
                        exo_duration.text = MediaPlayerTimeUtil.calculateTime(duration / 1000)

                        mTimer.schedule(object : TimerTask() {
                            override fun run() {
                                if (!isSeekbarChanging) {
                                    seekbar_play_progress.progress = mMediaPlayer?.currentPosition ?: 0
                                }
                            }
                        }, 0, 50)

                    }
                })
        }

    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK && request_code == requestCode) {
            val minute = data?.extras?.getInt("TIME_OFF_MINUTE", 0)
            if (minute != null && minute > 0) {
                if (meditationType == 0) {
                    tv_time_off_pure_music.visibility = View.VISIBLE
                    tv_time_off.visibility = View.GONE
                    mDisposable?.dispose()

                    initRxTimeOff((minute * 60 * 1000).toLong(), 0)
                } else {
                    tv_time_off_pure_music.visibility = View.GONE
                    tv_time_off.visibility = View.VISIBLE
                    mDisposable?.dispose()

                    initRxTimeOff((minute * 60 * 1000).toLong(), 1)
                }
            } else {
                mDisposable?.dispose()
                tv_time_off.visibility = View.GONE
                tv_time_off_pure_music.visibility = View.GONE
            }
        }
    }

    private fun initRxTimeOff(time: Long, meditationType: Int) {
        mObservable = Observable.interval(0, 1, TimeUnit.SECONDS)
            .take(time / 1000 + 1)
            .map { t -> time - t * 1000 }
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())

        mObserver = object : Observer<Long> {
            override fun onSubscribe(d: Disposable) {
                mDisposable = d
            }

            override fun onNext(t: Long) {
                if (meditationType == 0) {
                    tv_time_off_pure_music.text = MediaPlayerTimeUtil.formatTimeOff(t)
                } else {
                    tv_time_off.text = MediaPlayerTimeUtil.formatTimeOff(t)
                }
            }

            override fun onError(e: Throwable) {

            }

            override fun onComplete() {
                if (mMediaPlayer?.isPlaying == true) {
                    mMediaPlayer?.stop()
                    exo_play.setImageResource(R.drawable.icon_pause_meditation)
                }
                if (meditationType == 0) {
                    tv_time_off_pure_music.text = ""
                } else {
                    tv_time_off.text = ""
                }
            }
        }

        if (mObserver != null && mObserver is Observer<Long>) {
            mObservable?.subscribe(mObserver as Observer<Long>)
        }

        if (mDisposable?.isDisposed == true && mObserver != null && mObserver is Observer<Long>) {
            mObservable?.subscribe(mObserver as Observer<Long>)
        }

    }

    fun onEventMainThread(event: MeditationEvent) {
        if (event != null) {
            Glide.with(this)
                .load(event.mediaCoverUrl)
                .into(iv_bg)

            tv_title.text = event.title
            tv_content.text = event.desc

            shareTitle = event.title
            shareContent = event.desc
            shareUrl = event.mediaUrl
            shareImageUrl = event.mediaCoverUrl

            val status = event.status
            iv_collect.setImageResource(
                if (status == 0) {
                    R.drawable.icon_play_meditation_collect
                } else {
                    R.drawable.icon_meditation_collected
                }
            )

            if (event.mediaUrl == MediaPlayerManager.getInstance(this)?.getAudioPath()) {
                return
            }

            initMediaPlayer(event.mediaUrl, 0)


        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }

        mDisposable?.dispose()
        mTimer.cancel()
    }

    private fun stopPlay() {

    }

    companion object {
        const val request_code = 0x0001
    }

}