package com.offline.music.task.player.ui.activity

import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.View
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import androidx.media3.common.Player
import com.bumptech.glide.Glide
import com.offline.music.task.player.ProApp
import com.offline.music.task.player.R
import com.offline.music.task.player.databinding.ActivityMainBinding
import com.offline.music.task.player.db.bean.Audio
import com.offline.music.task.player.tools.util.getAudioDurationFromAssets
import com.offline.music.task.player.tools.media.MediaControllerManager
import com.offline.music.task.player.ui.fragment.HomeFragment
import com.offline.music.task.player.ui.fragment.MeFragment
import com.offline.music.task.player.ui.fragment.SettingsFragment

class MainActivity : BaseActivity() {
    private lateinit var binding: ActivityMainBinding
    private val mFragments: MutableList<Fragment> = ArrayList()
    private var currentIndex: Int = 0
    private var mCurrentFragment: Fragment? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        initView()
    }

    private fun initView() {
        initClick()
        initFragment()
    }

    override fun onResume() {
        super.onResume()
        val currentPlayer = MediaControllerManager.getController()

        if (ProApp.currentPlayingAudio == null) {
            binding.playingStatusLayout.visibility = View.GONE
        } else {
            binding.playingStatusLayout.visibility = View.VISIBLE
            val currentAudio = ProApp.currentPlayingAudio

            val maxProgress = try {
                getAudioDurationFromAssets(this, currentAudio?.file!!)
            } catch (e: Exception) {
                currentAudio?.duration
            }
            if (maxProgress != null) {
                binding.progressBar.setMaxProgress(maxProgress)
            }
            if (currentAudio?.image?.isNotEmpty() == true) {
                Glide.with(this)
                    .load("file:///android_asset/${currentAudio?.image}")
                    .into(binding.audioImg)
            } else {
                binding.audioImg.setImageResource(R.mipmap.default_list_img)
            }

            binding.name.text = currentAudio?.name
            binding.desc.text = currentAudio?.name
        }

        if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY) {
            val isPlaying = currentPlayer.isPlaying
            updatePlayState(isPlaying)
            if (isPlaying) {
                updateProgressState()
            }
        }
    }

    private fun initClick() {
        binding.homeBtn.setOnClickListener {
            changeFragment(0)
            updateBtnState(0)
        }
        binding.meBtn.setOnClickListener {
            changeFragment(1)
            updateBtnState(1)
        }

        binding.appSetting.setOnClickListener {
            changeFragment(2)
            updateBtnState(2)
        }

        binding.playingStatusLayout.setOnClickListener {
            val currentAudio = ProApp.currentPlayingAudio
            val duration = try {
                getAudioDurationFromAssets(
                    this, currentAudio?.file!!
                )
            } catch (e: Exception) {
                currentAudio?.duration!!
            }

            val audio = Audio(
                currentAudio?.name!!,
                currentAudio.file,
                currentAudio.image,
                duration,
                false
            )
            val intent = Intent(this, PlayerActivity::class.java);
            intent.putExtra(PlayerActivity.KEY_DETAILS_AUDIO, audio)
            startActivity(intent)
        }

        binding.playBlackBtn.setOnClickListener {
            val currentPlayer = MediaControllerManager.getController()
            if (currentPlayer != null) {
                if (currentPlayer.playbackState == Player.STATE_READY) {
                    if (currentPlayer.isPlaying) {
                        currentPlayer.pause()
                        updatePlayState(false)
                    } else {
                        currentPlayer.play()
                        updatePlayState(true)
                    }
                    updateProgressState()
                } else {
                    MediaControllerManager.setupMedia(this@MainActivity, ProApp.currentPlayingAudio!!,
                        object : Player.Listener {
                            override fun onPlayWhenReadyChanged(
                                playWhenReady: Boolean,
                                reason: Int
                            ) {
                                updatePlayState(playWhenReady)
                                updateProgressState()
                            }

                            override fun onPlaybackStateChanged(playbackState: Int) {
                                updateProgressState()
                            }
                        })
                }
            } else {
            }
        }
    }

    private fun updatePlayState(b: Boolean) {
        if (b) {
            binding.playStatusImg.setImageResource(R.drawable.main_playing_icon)
        } else {
            binding.playStatusImg.setImageResource(R.drawable.main_play_icon)
        }
    }

    private fun initFragment() {
        mFragments.clear()
        mFragments.add(HomeFragment())
        mFragments.add(MeFragment())
        mFragments.add(SettingsFragment())
        changeFragment(0)
        updateBtnState(0)
    }

    private fun changeFragment(index: Int) {
        currentIndex = index
        val ft: FragmentTransaction = supportFragmentManager.beginTransaction()
        if (null != mCurrentFragment) {
            ft.hide(mCurrentFragment!!)
        }
        var fragment = supportFragmentManager.findFragmentByTag(
            mFragments[currentIndex].javaClass.name
        )
        if (null == fragment) {
            fragment = mFragments[index]
        }
        mCurrentFragment = fragment

        if (!fragment.isAdded) {
            ft.add(R.id.frame_layout, fragment, fragment.javaClass.name)
        } else {
            ft.show(fragment)
        }
        ft.commit()
    }

    private fun updateBtnState(index: Int) {
        binding.apply {
            homeImg.setImageResource(
                when (index) {
                    0 -> R.drawable.home_select_icon
                    else -> R.drawable.home_unselect_icon
                }
            )
            meImg.setImageResource(
                when (index) {
                    1 -> R.drawable.me_select_icon
                    else -> R.drawable.me_unselect_icon
                }
            )
            homeSetting.setImageResource(
                when (index) {
                    2 -> R.drawable.settings_select_icon
                    else -> R.drawable.settings_unselect_icon
                }
            )
        }
    }

    private fun updateProgressState() {
        val currentPlayer = MediaControllerManager.getController()
        if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) {
            progressHandler.removeCallbacksAndMessages(null)
            updatePlayState(currentPlayer.isPlaying)
            progressHandler.sendEmptyMessage(1)
        } else {
            progressHandler.removeCallbacksAndMessages(null)
        }
    }

    private val progressHandler = object : Handler(Looper.myLooper()!!) {
        override fun handleMessage(msg: Message) {
            val currentPlayer = MediaControllerManager.getController()
            if (currentPlayer != null && currentPlayer.playbackState == Player.STATE_READY && currentPlayer.isPlaying) {
                val currentPosition = currentPlayer.currentPosition
                binding.progressBar.setProgress(currentPosition)
                sendEmptyMessageDelayed(1, 1000)
            }
        }
    }

    private var backPressedTime: Long = 0
    private val backToast: Toast by lazy {
        Toast.makeText(baseContext, "Press again to exit", Toast.LENGTH_SHORT)
    }

    override fun onBackPressed() {
        if (backPressedTime + 2000 > System.currentTimeMillis()) {
            super.onBackPressed()
            backToast.cancel()
            return
        } else {
            backToast.show()
        }
        backPressedTime = System.currentTimeMillis()
    }
}