package com.player.musicoo.activity

import android.annotation.SuppressLint
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.gyf.immersionbar.ktx.immersionBar
import com.player.musicoo.adapter.SingerMoreSongAdapter
import com.player.musicoo.databinding.ActivitySearchMoreBinding
import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.models.bodies.BrowseBody
import com.player.musicoo.innertube.models.bodies.ContinuationBody
import com.player.musicoo.innertube.requests.moSingerDetailsMoreLoadMorePage
import com.player.musicoo.innertube.requests.moSingerDetailsMorePage
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.isActive
import kotlinx.coroutines.selects.select

class MoSingerMoreSongActivity : MoBaseActivity() {
    private val requests: Channel<Request> = Channel(Channel.UNLIMITED)

    enum class Request {
        TryAgain,
        MoreData,
    }

    companion object {
        const val SINGER_MORE_SONG_BROWSE_ID = "singer_more_song_browse_id"
        const val SINGER_MORE_SONG_PARAMS = "singer_more_song_params"
        const val SINGER_MORE_TYPE = "singer_more_type"
    }

    private lateinit var binding: ActivitySearchMoreBinding
    private var browseId: String? = null
    private var params: String? = null
    private var type: String? = null
    private var list: MutableList<Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults> =
        mutableListOf()
    private var currentContinuation: String? = null
    private var adapter: SingerMoreSongAdapter? = null

    override suspend fun main() {
        binding = ActivitySearchMoreBinding.inflate(layoutInflater)
        setContentView(binding.root)
        browseId = intent.getStringExtra(SINGER_MORE_SONG_BROWSE_ID)
        params = intent.getStringExtra(SINGER_MORE_SONG_PARAMS)
        type = intent.getStringExtra(SINGER_MORE_TYPE)
        if (browseId.isNullOrEmpty() || params.isNullOrEmpty()) {
            return
        }
        initImmersionBar()
        initView()
        initAdapter()
        initData(browseId!!, params!!)
        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(browseId!!, params!!)
                        }

                        Request.MoreData -> {
                            if (!currentContinuation.isNullOrEmpty()) {
                                initDataMore(currentContinuation!!)
                            }else{
                                binding.refreshLayout.finishLoadMoreWithNoMoreData()
                            }
                        }
                    }
                }
            }
        }
    }

    private fun initView() {
        binding.backBtn.setOnClickListener {
            finish()
        }
        binding.tryAgainBtn.setOnClickListener {
            requests.trySend(Request.TryAgain)
        }
        binding.refreshLayout.setEnableRefresh(false)
        binding.refreshLayout.setEnableLoadMore(true)
        binding.refreshLayout.setOnLoadMoreListener {
            requests.trySend(Request.MoreData)
        }
    }

    private fun initAdapter() {
        adapter = SingerMoreSongAdapter(this, list, type)
        if (type == "MUSIC_PAGE_TYPE_ARTIST_DISCOGRAPHY") {
            binding.rv.layoutManager = GridLayoutManager(this, 2)
        } else {
            binding.rv.layoutManager =
                LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
        }
        binding.rv.adapter = adapter
    }

    private suspend fun initData(browseId: String, params: String) {
        showLoadingUi()
        Innertube.moSingerDetailsMorePage(BrowseBody(browseId = browseId, params = params))
            ?.onSuccess { result ->
                showDataUi()
                val title = result.title
                if (title.isNullOrEmpty()) {
                    binding.title.visibility = View.GONE
                } else {
                    binding.title.visibility = View.VISIBLE
                    binding.title.text = title
                }
                currentContinuation = result.continuation
                list.clear()
                list.addAll(result.songList)

            }?.onFailure {
                showNoContentUi()
            }
    }

    @SuppressLint("NotifyDataSetChanged")
    private suspend fun initDataMore(continuation: String) {
        Innertube.moSingerDetailsMoreLoadMorePage(ContinuationBody(continuation = continuation))
            ?.onSuccess { result ->
                currentContinuation = result.continuation
                if (currentContinuation.isNullOrEmpty()) {
                    binding.refreshLayout.finishLoadMoreWithNoMoreData()
                }
                if (result.songList.isNotEmpty()) {
                    list.addAll(result.songList)
                    if (!isFinishing) {
                        adapter?.notifyDataSetChanged()
                        binding.refreshLayout.finishLoadMore(true)
                    }
                } else {
                    binding.refreshLayout.finishLoadMoreWithNoMoreData()
                }
            }?.onFailure {
                binding.refreshLayout.finishLoadMoreWithNoMoreData()
            }
    }


    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() {
        binding.loadingLayout.visibility = View.GONE
        binding.noContentLayout.visibility = View.VISIBLE
    }
}