package melody.offline.music.fragment

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.gyf.immersionbar.ktx.immersionBar
import melody.offline.music.databinding.FragmentMoHomeBinding
import melody.offline.music.innertube.Innertube
import melody.offline.music.innertube.models.MusicCarouselShelfRenderer
import melody.offline.music.innertube.requests.homePage
import melody.offline.music.innertube.requests.homePageMore
import melody.offline.music.util.LogTag.LogD
import melody.offline.music.view.MusicResponsiveListView
import melody.offline.music.view.MusicTowRowListView
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.isActive
import kotlinx.coroutines.selects.select
import melody.offline.music.ads.AnalysisAdState
import melody.offline.music.util.AnalysisUtil
import org.json.JSONObject

class MoHomeFragment : MoBaseFragment<FragmentMoHomeBinding>() {

    private val requests: Channel<Request> = Channel(Channel.UNLIMITED)

    enum class Request {
        TryAgain,
    }

    override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentMoHomeBinding
        get() = FragmentMoHomeBinding::inflate

    override suspend fun onViewCreated() {
        initView()
        initData()
        onReceive()
    }

    private fun initImmersionBar() {
        immersionBar {
            statusBarDarkFont(false)
            statusBarView(binding.view)
        }
    }

    private suspend fun onReceive() {
        while (isActive) {
            select<Unit> {
                requests.onReceive {
                    when (it) {
                        Request.TryAgain -> {
                            initData()
                        }
                    }
                }
                events.onReceive {
                    when (it) {
                        Event.FragmentOnResume -> {
                            fragmentOnResume()
                        }
                    }
                }
            }
        }
    }

    private fun initView() {
        binding.tryAgainBtn.setOnClickListener {
            requests.trySend(Request.TryAgain)
        }
    }

    private suspend fun initData() {
        showLoadingUi()
        Innertube.homePage(appStore.myVisitorData)?.onSuccess {
            showDataUi()
            if (it.homePage.isNotEmpty()) {
                AnalysisUtil.logEvent(AnalysisUtil.HOME_B_MODULE_SHOW_SUCCESS_ACTION)
                for (home: Innertube.HomePage in it.homePage) {
                    for (content: MusicCarouselShelfRenderer.Content in home.contents) {
                        if (content.musicResponsiveListItemRenderer != null) {
                            binding.contentLayout.addView(
                                MusicResponsiveListView(
                                    requireActivity(),
                                    home
                                )
                            )
                            break
                        }
                        if (content.musicTwoRowItemRenderer != null) {
                            binding.contentLayout.addView(
                                MusicTowRowListView(
                                    requireActivity(),
                                    home
                                )
                            )
                            break
                        }
                    }
                }
                initHomeDataMore(it)
            } else {
                LogD(TAG, "homePage size 0")
                showNoContentUi("homePage size 0")
            }
        }?.onFailure {
            LogD(TAG, "homePage onFailure->${it}")
            showNoContentUi(it.message.toString())
        }
    }

    private suspend fun initHomeDataMore(baseHomePage: Innertube.BaseHomePage) {
        if (baseHomePage.cToken?.isNotEmpty() == true) {
            Innertube.homePageMore(baseHomePage)?.onSuccess {
                for (home: Innertube.HomePage in it.homePage) {
                    for (content: MusicCarouselShelfRenderer.Content in home.contents) {
                        if (content.musicResponsiveListItemRenderer != null) {
                            val musicResponsiveListView =
                                MusicResponsiveListView(requireActivity(), home)
                            binding.contentLayout.addView(musicResponsiveListView)
                            break
                        }
                        if (content.musicTwoRowItemRenderer != null) {
                            binding.contentLayout.addView(
                                MusicTowRowListView(
                                    requireActivity(),
                                    home
                                )
                            )
                            break
                        }
                    }
                }
                initHomeDataMore(it)
            }?.onFailure {
                LogD(TAG, "initHomeDataMore onFailure ->${it}")
            }
        }
    }

    private fun fragmentOnResume() {
        refreshAdapters()
    }

    private fun refreshAdapters() {//刷新home的单曲ui
        for (i in 0 until binding.contentLayout.childCount) {
            val child = binding.contentLayout.getChildAt(i)
            if (child is MusicResponsiveListView) {
                child.updateAdapter()
            }
        }
    }

    override fun onResume() {
        super.onResume()
        initImmersionBar()
        AnalysisUtil.logEvent(AnalysisUtil.HOME_B_PV)
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if (!hidden) {
            initImmersionBar()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
    }

    private fun showDataUi() {
        binding.loadingLayout.visibility = View.GONE
        binding.noContentLayout.visibility = View.GONE
    }

    private fun showLoadingUi() {
        binding.loadingLayout.visibility = View.VISIBLE
        binding.noContentLayout.visibility = View.GONE
    }

    private fun showNoContentUi(string: String) {
        val jsonObject = JSONObject()
        jsonObject.put("fail", string)
        val map = mutableMapOf(Pair(AnalysisUtil.PARAM_VALUE, jsonObject.toString()))
        AnalysisUtil.logEvent(AnalysisUtil.HOME_B_MODULE_SHOW_FAIL_ACTION, map)

        binding.loadingLayout.visibility = View.GONE
        binding.noContentLayout.visibility = View.VISIBLE
    }

}