package com.yidianling.muse.service

import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.graphics.PixelFormat
import android.media.MediaPlayer
import android.os.Build
import android.util.DisplayMetrics
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.view.WindowManager
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.LifecycleService
import com.bumptech.glide.Glide
import com.ydl.ydlcommon.data.http.ThrowableConsumer
import com.yidianling.home.http.MuseHttp
import com.yidianling.muse.R
import com.yidianling.muse.activity.PlayMeditationActivity
import com.yidianling.muse.bean.MeditationPlayModuleBean
import com.yidianling.muse.event.MeditationFloatEvent
import com.yidianling.muse.helper.FloatViewTouchListener
import com.yidianling.muse.helper.MediaPlayerManager
import de.greenrobot.event.EventBus
import io.feeeei.circleseekbar.CircleSeekBar
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import java.util.*
import kotlin.math.roundToInt

class MeditationWindowService : LifecycleService() {

    private lateinit var mWindowManager: WindowManager
    private var floatRootView: View? = null

    private var ivClose: ImageView? = null
    private var ivCover: ImageView? = null
    private var tvTitle: TextView? = null
    private var ivProgress: CircleSeekBar? = null
    private var ivPlayOrPause: ImageView? = null

    private var mMediaPlayer: MediaPlayer? = null

    private var mTimer = Timer()

    private var mCurrentMeditation: MeditationPlayModuleBean.MeditationDetail? = null

    private var windowIsShow = false

    override fun onCreate() {
        super.onCreate()
        EventBus.getDefault().register(this)
    }

    private fun showWindow() {
        mWindowManager = getSystemService(WINDOW_SERVICE) as WindowManager
        val outMetrics = DisplayMetrics()
        mWindowManager.defaultDisplay.getMetrics(outMetrics)
        var layoutParams = WindowManager.LayoutParams().apply {
            type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            } else {
                WindowManager.LayoutParams.TYPE_PHONE
            }
            flags =
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

            format = PixelFormat.RGBA_8888

            width = outMetrics.widthPixels - dp2px(32F)
            height = WRAP_CONTENT

            gravity = Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM
        }

        floatRootView =
            LayoutInflater.from(this).inflate(R.layout.layout_meditation_play_float_view, null)

        ivClose = floatRootView?.findViewById(R.id.iv_close)
        ivCover = floatRootView?.findViewById(R.id.iv_cover)
        tvTitle = floatRootView?.findViewById(R.id.tv_title)
        ivProgress = floatRootView?.findViewById(R.id.progress_bar)
        ivPlayOrPause = floatRootView?.findViewById(R.id.iv_play_status)

        floatRootView?.setOnTouchListener(FloatViewTouchListener(layoutParams, mWindowManager))



        mWindowManager.addView(floatRootView, layoutParams)

        windowIsShow = true
    }

    fun onEventMainThread(event: MeditationFloatEvent) {
        if (!event.show) {
            hideFloatWindow()
        }
        if (event.show && event.meditationDetail != null) {
            if (!windowIsShow) {
                showWindow()
            }
            updateFloatView(event.meditationDetail)
        }
    }

    private fun updateFloatView(meditation: MeditationPlayModuleBean.MeditationDetail) {

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

        floatRootView?.setOnClickListener {
            val intent = Intent(this, PlayMeditationActivity::class.java)
            intent.putExtra("MEDIA_ID", meditation.mediaId)
            intent.putExtra("MEDITATION_ID", meditation.meditationId)
            intent.putExtra("MEDITATION_TYPE", meditation.mediaType)
            intent.putExtra("MEDIA_COVER_URL", meditation.coverImageUrl)
            intent.flags = FLAG_ACTIVITY_NEW_TASK
            startActivity(intent)
        }

        if (mMediaPlayer?.isPlaying == true) {

            ivPlayOrPause?.setImageResource(R.drawable.icon_meditation_float_play)
        } else {
            ivPlayOrPause?.setImageResource(R.drawable.icon_meditation_float_pause)
        }

        ivProgress?.maxProcess = mMediaPlayer?.duration ?: 0
        ivProgress?.curProcess = mMediaPlayer?.currentPosition ?: 0

        Glide.with(floatRootView!!)
            .load(meditation.coverImageUrl)
            .into(ivCover!!)

        tvTitle?.text = meditation.title

        ivPlayOrPause?.setOnClickListener {
            if (mMediaPlayer?.isPlaying == true) {
                MediaPlayerManager.getInstance(this)?.pause()
                if (meditation.meditationId != null && meditation.mediaId != null) {
                    MuseHttp.getInstance().postMeditationPlayRecord(
                        meditationId = meditation.meditationId!!.toInt(),
                        isQuit = 1, mediaId = meditation.mediaId!!,
                        playTime = (ivProgress?.curProcess?.div(1000.00))?.roundToInt() ?: 0,
                        isComplete = 0
                    )
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe({

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

                                }
                            }
                        })
                }
            } else {
                MediaPlayerManager.getInstance(this)?.play()
            }
            if (mMediaPlayer?.isPlaying == true) {
                ivPlayOrPause?.setImageResource(R.drawable.icon_meditation_float_play)
            } else {
                ivPlayOrPause?.setImageResource(R.drawable.icon_meditation_float_pause)
            }
        }

        mTimer.schedule(object : TimerTask() {
            override fun run() {
                ivProgress?.curProcess = mMediaPlayer?.currentPosition ?: 0
            }
        }, 0, 50)

        mMediaPlayer?.setOnCompletionListener {
            postPlayRecord(
                0, (ivProgress?.curProcess?.div(1000.00))?.roundToInt() ?: 0,
                1,
                meditation.meditationId.toInt(),
                meditation.mediaId ?: 0L
            )
        }

        ivClose?.setOnClickListener {
            postPlayRecord(
                1, (ivProgress?.curProcess?.div(1000.00))?.roundToInt() ?: 0,
                0,
                meditation.meditationId.toInt(),
                meditation.mediaId ?: 0L
            )
            MediaPlayerManager.getInstance(this)?.stop()
            hideFloatWindow()
        }

    }

    private fun hideFloatWindow() {
        if (floatRootView != null && floatRootView?.windowToken != null) {
            if (mWindowManager != null) {
                windowIsShow = false
                mTimer.cancel()
                mWindowManager.removeViewImmediate(floatRootView)
            }
        }
    }

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

    private fun dp2px(dp: Float): Int {
        val scale = resources.displayMetrics.density
        return (dp * scale + 0.5f).toInt()
    }

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

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

                    }
                }
            })
    }

}