package melody.offline.music.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.gyf.immersionbar.ktx.immersionBar
import melody.offline.music.R
import melody.offline.music.ads.AdPlacement
import melody.offline.music.ads.LolAdWrapper
import melody.offline.music.bean.Audio
import melody.offline.music.databinding.ActivityMainBinding
import melody.offline.music.fragment.HomeFragment
import melody.offline.music.fragment.ImportFragment
import melody.offline.music.media.LocalMediaControllerManager
import melody.offline.music.util.getAudioDurationFromAssets


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()

        LolAdWrapper.shared.loadAdIfNotCached(this, AdPlacement.INST_CUTTING_SONG)
        LolAdWrapper.shared.loadAdIfNotCached(this, AdPlacement.INST_DOWNLOAD)

        val currentPlayer = LocalMediaControllerManager.getController()
        if (melody.offline.music.App.currentPlayingAudio == null) {
            binding.playingStatusLayout.visibility = View.GONE
        } else {
            binding.playingStatusLayout.visibility = View.VISIBLE
            val currentAudio = melody.offline.music.App.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.app_logo)
            }

            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.importBtn.setOnClickListener {
            changeFragment(1)
            updateBtnState(1)
        }
        binding.playingStatusLayout.setOnClickListener {
            val currentAudio = melody.offline.music.App.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, PlayDetailsActivity::class.java);
            intent.putExtra(PlayDetailsActivity.KEY_DETAILS_AUDIO, audio)
            startActivity(intent)
        }

        binding.playBlackBtn.setOnClickListener {
            val currentPlayer = LocalMediaControllerManager.getController()
            if (currentPlayer != null) {
                if (currentPlayer.playbackState == Player.STATE_READY) {
                    if (currentPlayer.isPlaying) {
                        currentPlayer.pause()
                        updatePlayState(false)
                    } else {
                        currentPlayer.play()
                        updatePlayState(true)
                    }
                    updateProgressState()
                } else {
                    LocalMediaControllerManager.setupMedia(this@MainActivity, melody.offline.music.App.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.playing_black_icon)
        } else {
            binding.playStatusImg.setImageResource(R.drawable.play_black_icon)
        }
    }

    private fun initFragment() {
        mFragments.clear()
        mFragments.add(HomeFragment())
        mFragments.add(ImportFragment())
        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
                }
            )
            importImg.setImageResource(
                when (index) {
                    1 -> R.drawable.import_select_icon
                    else -> R.drawable.import_unselect_icon
                }
            )
        }
    }

    private fun updateProgressState() {
        val currentPlayer = LocalMediaControllerManager.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 = LocalMediaControllerManager.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()
    }
}