package kr.co.vividnext.sodalive.mypage.alarm

import android.content.Context
import android.media.AudioManager
import android.media.MediaPlayer
import android.os.Build
import android.os.Bundle
import android.view.WindowManager
import androidx.activity.OnBackPressedCallback
import androidx.lifecycle.Observer
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailViewModel
import kr.co.vividnext.sodalive.base.BaseActivity
import kr.co.vividnext.sodalive.common.Constants
import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.databinding.ActivityAlarmBinding
import kr.co.vividnext.sodalive.mypage.alarm.db.Alarm
import kr.co.vividnext.sodalive.mypage.alarm.db.AlarmDatabase
import org.koin.android.ext.android.inject
import java.text.SimpleDateFormat
import java.util.Locale

class AlarmActivity : BaseActivity<ActivityAlarmBinding>(
    ActivityAlarmBinding::inflate
) {

    private val contentViewModel: AudioContentDetailViewModel by inject()

    private lateinit var mediaPlayer: MediaPlayer
    private lateinit var loadingDialog: LoadingDialog

    private lateinit var audioManager: AudioManager
    private var originalVolume: Int = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            setTurnScreenOn(true)
            setShowWhenLocked(true)
        } else {
            window.addFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                    or WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                    or WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
            )
        }

        super.onCreate(savedInstanceState)

        initAudioManagerAndSaveOriginalVolume()
        bindData()
        getAlarm()
    }

    private fun getAlarm() {
        val alarmId = intent.getIntExtra(Constants.EXTRA_ALARM_ID, -1)
        val alarmDao = AlarmDatabase.getDatabase(applicationContext).alarmDao()
        val alarmLiveData = alarmDao.getAlarmById(alarmId)

        val observer = object : Observer<Alarm> {
            override fun onChanged(value: Alarm) {
                getContent(value.contentId)
                setAlarmData(value)
                alarmLiveData.removeObserver(this)
            }
        }

        CoroutineScope(Dispatchers.Main).launch {
            withContext(Dispatchers.Main) {
                alarmLiveData.observeForever(observer)
            }
        }
    }

    private fun initAudioManagerAndSaveOriginalVolume() {
        audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
        originalVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
    }

    private fun setVolume(volume: Int) {
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0)
    }

    private fun setAlarmData(alarm: Alarm) {
        binding.tvTitle.text = alarm.title
        binding.tvTime.text = SimpleDateFormat("hh:mm", Locale.getDefault())
            .format(alarm.time)
        binding.tvDate.text = SimpleDateFormat("MM월 dd일", Locale.getDefault())
            .format(alarm.time)
        setVolume(alarm.volume)
    }

    private fun getContent(contentId: Long) {
        contentViewModel.getAudioContentDetail(contentId) {}
    }

    private fun bindData() {
        contentViewModel.isLoading.observe(this) {
            if (it) {
                loadingDialog.show(screenWidth, "")
            } else {
                loadingDialog.dismiss()
            }
        }

        contentViewModel.audioContentLiveData.observe(this) {
            initMediaPlayer(it.contentUrl)
        }
    }

    override fun setupView() {
        loadingDialog = LoadingDialog(this, layoutInflater)
        binding.ivStopAlarm.setOnClickListener { finish() }

        onBackPressedDispatcher.addCallback(
            this,
            object : OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                }
            }
        )
    }

    private fun initMediaPlayer(alarmUrl: String) {
        mediaPlayer = MediaPlayer()
        mediaPlayer.isLooping = true
        mediaPlayer.setDataSource(alarmUrl)
        mediaPlayer.prepareAsync()
        mediaPlayer.setOnPreparedListener { mp -> mp.start() }
    }

    override fun onDestroy() {
        setVolume(originalVolume)
        if (mediaPlayer.isPlaying) {
            mediaPlayer.stop()
        }
        mediaPlayer.release()

        super.onDestroy()
    }
}
