package melody.offline.music.activity

import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.annotation.OptIn
import androidx.appcompat.app.AlertDialog
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.offline.Download
import androidx.recyclerview.widget.LinearLayoutManager
import com.gyf.immersionbar.ktx.immersionBar
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.isActive
import kotlinx.coroutines.selects.select
import melody.offline.music.App
import melody.offline.music.R
import melody.offline.music.adapter.OfflineSongsAdapter
import melody.offline.music.ads.AdPlacement
import melody.offline.music.ads.LolAdWrapper
import melody.offline.music.bean.FavoriteBean
import melody.offline.music.bean.OfflineBean
import melody.offline.music.bean.PlaylistItem
import melody.offline.music.databinding.ActivityOfflineSongsBinding
import melody.offline.music.util.AnalysisUtil
import melody.offline.music.util.LogTag
import melody.offline.music.view.ListMoreBottomSheetDialog
import org.json.JSONObject

@OptIn(UnstableApi::class)
class MoOfflineSongsActivity : MoBaseActivity(), ListMoreBottomSheetDialog.ListMoreViewListener,
    ListMoreBottomSheetDialog.UpdateAdapterListener {
    private val requests: Channel<Request> = Channel(Channel.UNLIMITED)

    sealed class Request {
        data object TryAgain : Request()
        data class OnFavorites(val bean: PlaylistItem) : Request()
        data class OnDownloadRemove(val bean: PlaylistItem) : Request()
        data class UpdateFavorite(val bean: PlaylistItem) : Request()
        data class OnAddPlaylist(val bean: PlaylistItem) : Request()
        data class OnUpdateCurrentListItem(val bean: PlaylistItem) : Request()
    }

    private lateinit var binding: ActivityOfflineSongsBinding
    private var adapter: OfflineSongsAdapter? = null

    private var myList: MutableList<PlaylistItem> = mutableListOf()
    private var moreDialog: ListMoreBottomSheetDialog? = null
    private var currentPosition = -1

    override suspend fun main() {
        binding = ActivityOfflineSongsBinding.inflate(layoutInflater)
        setContentView(binding.root)
        LolAdWrapper.shared.showAdTiming(this, AdPlacement.INST_ME_PAGE_LIST)
        initImmersionBar()
        initView()
        initAdapter()
        LolAdWrapper.shared.loadAdIfNotCached(this, AdPlacement.INST_ME_PAGE_LIST)
        initData()
        onReceive()
    }

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

    @SuppressLint("NotifyDataSetChanged")
    private suspend fun onReceive() {
        while (isActive) {
            select<Unit> {
                requests.onReceive {
                    when (it) {
                        Request.TryAgain -> {
                            initData()
                        }

                        is Request.OnFavorites -> {
                            val jsonObject = JSONObject()
                            jsonObject.put(
                                "song_title", it.bean.title
                            )
                            val songMap = mutableMapOf(
                                Pair(
                                    AnalysisUtil.PARAM_VALUE, jsonObject.toString()
                                )
                            )
                            val currentFavoriteBean =
                                App.appFavoriteDBManager.getFavoriteBeanByID(it.bean.videoId)
                            if (currentFavoriteBean != null) {//先获取数据库是否有这条数据
                                currentFavoriteBean.isFavorite = !currentFavoriteBean.isFavorite
                                App.appFavoriteDBManager.updateFavoriteBean(currentFavoriteBean)
                                if (currentFavoriteBean.isFavorite) {
                                    AnalysisUtil.logEvent(
                                        AnalysisUtil.PLAYER_B_LOVE_CLICK, songMap
                                    )
                                } else {
                                    AnalysisUtil.logEvent(
                                        AnalysisUtil.PLAYER_B_UN_LOVE_CLICK, songMap
                                    )
                                }
                            } else {

                                insertFavoriteData(OfflineBean(
                                    videoId = it.bean.videoId,
                                    title = it.bean.title,
                                    name = it.bean.name,
                                    thumbnail = it.bean.thumbnail,
                                    bytesDownloaded = it.bean.bytesDownloaded,
                                    size = it.bean.size,
                                    isOffline = it.bean.isOffline,
                                    isFavorite = it.bean.isFavorite
                                ))
                                AnalysisUtil.logEvent(AnalysisUtil.PLAYER_B_LOVE_CLICK, songMap)
                            }
                            requests.trySend(Request.UpdateFavorite(it.bean))
                        }

                        is Request.UpdateFavorite -> {
                            val currentFavoriteBean = App.appFavoriteDBManager.getFavoriteBeanByID(it.bean.videoId)
                            if (currentFavoriteBean != null) {
                                updateFavoriteUi(currentFavoriteBean.isFavorite)
                            } else {
                                updateFavoriteUi(false)
                            }

                            requests.trySend(Request.OnUpdateCurrentListItem(it.bean))
                        }

                        is Request.OnDownloadRemove -> {
                            val currentOfflineBean =
                                App.appOfflineDBManager.getOfflineBeanByID(it.bean.videoId)
                            if (currentOfflineBean != null) {
                                App.appOfflineDBManager.deleteOfflineBean(currentOfflineBean)
                            }

                            if (currentPosition >= 0) {
                                myList.remove(myList[currentPosition])
                            }
                            adapter?.notifyDataSetChanged()
                            moreDialog?.dismiss()

                            requests.trySend(Request.OnUpdateCurrentListItem(it.bean))
                        }

                        is Request.OnAddPlaylist -> {
                            showAddPlaylistBottomDialog(
                                FavoriteBean(
                                    videoId = it.bean.videoId,
                                    title = it.bean.title,
                                    name = it.bean.name,
                                    thumbnail = it.bean.thumbnail,
                                    isFavorite = it.bean.isFavorite
                                )
                            )
                        }

                        is Request.OnUpdateCurrentListItem -> {
                            updateCurrentItem(it.bean.videoId)
                        }
                    }
                }
                events.onReceive {
                    when (it) {
                        Event.ActivityOnResume -> {
                            activityOnResume()
                        }

                        Event.AutomaticallySwitchSongs -> {
                            if (adapter != null) {
                                adapter?.notifyDataSetChanged()
                            }
                        }

                        else -> {}
                    }
                }
            }
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun activityOnResume() {
        addMusicPlayerViewToLayout(binding.playMusicLayout)

        if (adapter != null) {
            adapter?.notifyDataSetChanged()
        }

        LolAdWrapper.shared.loadAdShowNativeAd(
            this,
            AdPlacement.NATIVE_ME_PAGE_LIST,
            binding.frameAd,
            R.layout.ad_layout_admob_banner,
            R.layout.ad_layout_max_banner
        )
    }

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

    private fun initAdapter() {
        adapter = OfflineSongsAdapter(this, myList)
        adapter?.setOnMoreClickListener(object : OfflineSongsAdapter.OnMoreClickListener {
            override fun onMoreClick(position: Int) {
                currentPosition = position
                moreDialog = ListMoreBottomSheetDialog(
                    this@MoOfflineSongsActivity,
                    myList[position],
                    this@MoOfflineSongsActivity,
                    this@MoOfflineSongsActivity
                )
                moreDialog?.setListMoreViewListener(this@MoOfflineSongsActivity)
                moreDialog?.show()
            }
        })
        binding.rv.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
        binding.rv.adapter = adapter
    }

    @SuppressLint("NotifyDataSetChanged")
    private suspend fun initData() {
        showLoadingUi()
        val offlineBeans = App.appOfflineDBManager.getAllOfflineBeans()
        if (offlineBeans.isNotEmpty()) {
            myList.clear()
            offlineBeans.forEach { offlineBean ->
                val favoriteItem = App.appFavoriteDBManager.getFavoriteBeanByID(offlineBean.videoId)
                if (offlineBean.bytesDownloaded?.let { bytes -> bytes > 0 } == true) {
                    myList.add(
                        PlaylistItem(
                            videoId = offlineBean.videoId,
                            title = offlineBean.title,
                            name = offlineBean.name,
                            thumbnail = offlineBean.thumbnail,
                            isOffline = offlineBean.isOffline,
                            isFavorite = favoriteItem?.isFavorite ?: false,
                            bytesDownloaded = offlineBean.bytesDownloaded,
                            size = offlineBean.size
                        )
                    )

                }
            }
            if (myList.size > 0) {
                showDataUi()
            } else {
                showNoContentUi()
            }
        } else {
            showNoContentUi()
        }

        if (adapter != null) {
            adapter?.notifyDataSetChanged()
        }
    }

    private fun updateFavoriteUi(b: Boolean) {
        if (moreDialog != null) {
            moreDialog?.updateFavoriteUi(b)
        }
    }

    private suspend fun updateCurrentItem(id: String) {
        //更新当前界面的数据集合
        myList.forEach { item ->
            if (item.videoId == id) {
                val favoriteBean = App.appFavoriteDBManager.getFavoriteBeanByID(item.videoId)
                val offlineBean = App.appOfflineDBManager.getOfflineBeanByID(item.videoId)
                item.isFavorite = favoriteBean?.isFavorite ?: false
                item.isOffline = offlineBean?.isOffline ?: false
                item.bytesDownloaded = offlineBean?.bytesDownloaded
                item.size = offlineBean?.size
            }
        }
        myList.forEach { item ->
            if (item.videoId == id) {
                LogTag.LogD(TAG, "updateCurrentItem -> $item")
            }
        }
    }

    override fun onFavoritesClicked(playlistItem: PlaylistItem) {
        requests.trySend(Request.OnFavorites(playlistItem))
    }

    override fun onDownloadClicked(playlistItem: PlaylistItem) {
        //下载列表只有删除，删除后更新adapter
        showRemoveDownloadDialogHint(playlistItem)
    }

    override fun onAddToPlaylistClicked(playlistItem: PlaylistItem) {
        requests.trySend(Request.OnAddPlaylist(playlistItem))
    }

    override fun onUpdateAdapterListener(download: Download, playlistItem: PlaylistItem) {

    }

    private fun showRemoveDownloadDialogHint(bean: PlaylistItem) {
        val inflater = LayoutInflater.from(this)
        val dialogView = inflater.inflate(R.layout.dialog_hint, null)
        val okBtn = dialogView.findViewById<TextView>(R.id.dialog_ok_btn)
        val cancelBtn = dialogView.findViewById<TextView>(R.id.dialog_cancel_btn)
        val dialogBuilder = AlertDialog.Builder(this).setView(dialogView)
        val dialog = dialogBuilder.create()
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog.show()
        okBtn.setOnClickListener {
            dialog.dismiss()
            requests.trySend(Request.OnDownloadRemove(bean))
        }
        cancelBtn.setOnClickListener {
            dialog.dismiss()
        }
    }

    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
    }
}