package com.gh.gamecenter.mygame

import android.content.Context
import android.util.SparseArray
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.databind.BindingAdapters
import com.gh.common.exposure.IExposable
import com.gh.common.pop.CancelReservePop
import com.gh.common.pop.ReserveAllSelectPop
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.ReservationHelper
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.callback.CancelListener
import com.gh.gamecenter.common.constant.ItemViewType
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.ItemFollowedGameBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.game.GameAndPosition
import com.lightgame.view.CheckableImageView

class MyReservationAdapter(context: Context, var mViewModel: MyReservationViewModel) : ListAdapter<GameEntity>(context),
    IExposable {

    private var pageState: MyReservationFragment.ReservePageState = MyReservationFragment.ReservePageState.Normal
    private val isEditing: Boolean
        get() = pageState != MyReservationFragment.ReservePageState.Normal

    private val mEntrance = "(我的预约)"
    private val mExposureEventSparseArray: SparseArray<ExposureEvent> = SparseArray()
    private val selectedGames = mutableSetOf<GameEntity>()

    private val allSelectPop by lazy {
        ReserveAllSelectPop.create(mContext, object : ReserveAllSelectPop.OnReserveAllSelectListener {
            override fun selectAll(isChecked: Boolean): Int {
                selectedGames.clear()
                if (isChecked) {
                    if (pageState == MyReservationFragment.ReservePageState.EnableAutoDownload) {
                        mEntityList
                            .filter {
                                it.wifiAutoDownloadEnable && !it.wifiAutoDownload
                            }
                            .let(selectedGames::addAll)
                    } else {
                        mEntityList.let(selectedGames::addAll)
                    }

                }
                notifyItemRangeChanged(0, mEntityList.size)
                return selectedGames.size
            }

            override fun submit() {
                doSubmit()

            }
        })
    }

    private fun doSubmit() {
        if (pageState == MyReservationFragment.ReservePageState.EnableAutoDownload) {
            allSelectPop.dismiss()
            mViewModel.enableAutoDownload(true, selectedGames.toSet())
            mViewModel.changeReserveStatus(MyReservationFragment.ReservePageState.Normal)
        } else {
            showCancelReservationInBatchDialog(selectedGames.toSet())
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            ItemViewType.GAME_NORMAL -> {
                MyFollowedGameViewHolder(
                    ItemFollowedGameBinding.bind(
                        mLayoutInflater.inflate(
                            R.layout.item_followed_game,
                            parent,
                            false
                        )
                    )
                )
            }

            else -> {
                FooterViewHolder(mLayoutInflater.inflate(com.gh.gamecenter.common.R.layout.refresh_footerview, parent, false))
            }
        }
    }

    override fun getItemViewType(position: Int): Int {
        if (position == itemCount - 1) {
            return ItemViewType.ITEM_FOOTER
        }
        return ItemViewType.GAME_NORMAL
    }

    override fun getItemCount(): Int {
        return if (mEntityList == null || mEntityList.isEmpty()) return 0 else mEntityList.size + 1
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is MyFollowedGameViewHolder -> {
                val gameEntity = mEntityList[position]
                val path = "预约Tab"
                val newPath = "预约Tab_新"

                holder.binding.run {
                    root.background = com.gh.gamecenter.common.R.drawable.reuse_listview_item_style.toDrawable(root.context)
                    listOf(forumTv, trendsTv, commentsTv).forEach {
                        it.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(mContext))
                    }
                    gameItemIncluded.run {
                        root.background = null
                        gameKaifuType.setBackgroundColor(com.gh.gamecenter.common.R.color.primary_theme.toColor(root.context))
                        gameName.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(root.context))
                        gameDes.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(root.context))
                        recommendStarPref.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(root.context))

                        gameIconView.displayGameIcon(gameEntity)
                        gameRating.textSize = if (gameEntity.commentCount > 3) 12F else 10F
                        BindingAdapters.setGameName(gameName, gameEntity, false)
                        BindingAdapters.setGameTags(labelList, gameEntity, "")
                        gameRating.setDrawableStart(
                            if (gameEntity.commentCount > 3) com.gh.gamecenter.feature.R.drawable.game_horizontal_rating.toDrawable(mContext) else null
                        )
                        gameRating.setPadding(0, 0, if (gameEntity.commentCount > 3) 8F.dip2px() else 0, 0)
                        gameRating.text = if (gameEntity.commentCount > 3) {
                            if (gameEntity.star == 10.0F) "10" else gameEntity.star.toString()
                        } else ""
                        gameRating.setTextColor(
                            if (gameEntity.commentCount > 3) com.gh.gamecenter.common.R.color.text_theme.toColor(mContext) else com.gh.gamecenter.common.R.color.primary_theme.toColor(
                                mContext
                            )
                        )
                        gameDes.text = gameEntity.decoratedDes
                        recommendStar.rating = gameEntity.recommendStar.toFloat()
                        GameItemViewHolder.initGameSubtitleAndAdLabel(gameEntity, gameSubtitleTv)
                        tvAutoDownloadTips.goneIf(!gameEntity.wifiAutoDownload)
                        ivEdit.goneIf(isEditing)
                        if (isEditing) {
                            selectIv.goneIf(false)
                            updateSelectedStatus(selectIv, gameEntity)
                            cardContainer.updateLayoutParams {
                                if (this is MarginLayoutParams) {
                                    marginStart = 120F.dip2px()
                                }
                            }
                        } else {
                            selectIv.goneIf(true)
                            cardContainer.updateLayoutParams {
                                if (this is MarginLayoutParams) {
                                    marginStart = 92F.dip2px()
                                }
                            }
                        }
                    }
                }

                holder.initServerType(gameEntity)
                holder.initShortcut(gameEntity, mEntrance, path, newPath)

                val exposureEvent = ExposureEvent.createEvent(
                    gameEntity,
                    listOf(ExposureSource("我的游戏", "预约"))
                )
                mExposureEventSparseArray.append(position, exposureEvent)

                val gameItemBinding = holder.binding.gameItemIncluded
                DownloadItemUtils.updateItemWithReserveStatus(
                    GameViewHolder(holder.binding.gameItemIncluded.root).apply {
                        gameDownloadBtn = gameItemBinding.downloadBtn
                        gameDes = gameItemBinding.gameDes
                        gameDownloadTips = gameItemBinding.downloadTipsLottie
                        multiVersionDownloadTv = gameItemBinding.multiVersionDownloadTv
                        gameRating = gameItemBinding.gameRating
                        recommendContainer = gameItemBinding.recommendContainer
                        recommendIv = gameItemBinding.recommendIv
                        recommendTv = gameItemBinding.recommendTv
                        recommendStarInfo = gameItemBinding.recommendStarInfo
                    },
                    gameEntity
                )

                holder.itemView.setOnClickListener {
                    MtaHelper.onEvent("我的光环", path, "点击其他位置")
                    MtaHelper.onEvent("我的光环", newPath, "点击其他位置")
                    MtaHelper.onEvent("我的光环_新", path, "点击其他位置")
                    NewFlatLogUtils.logMyGameReserveTabGameCardClick(
                        "游戏详情",
                        gameEntity.id,
                        gameEntity.name ?: ""
                    )
                    if (pageState == MyReservationFragment.ReservePageState.Normal) {
                        GameDetailActivity.startGameDetailActivity(mContext, gameEntity.id, mEntrance, exposureEvent)
                    } else {
                        val isEnableSelect = pageState == MyReservationFragment.ReservePageState.CancelReserve
                                || (gameEntity.wifiAutoDownloadEnable && !gameEntity.wifiAutoDownload)
                        if (isEnableSelect) { // 可勾选状态
                            val ivSelect = holder.binding.gameItemIncluded.selectIv
                            if (ivSelect.isEnabled) {
                                ivSelect.toggle()
                                if (ivSelect.isChecked) {
                                    selectedGames.add(gameEntity)
                                } else {
                                    selectedGames.remove(gameEntity)
                                }
                                updateSelectedStatus(ivSelect, gameEntity)
                                allSelectPop.updateSelectedCount(selectedGames.size)
                            }
                        } else {  // 不可勾选状态，弹出相应的提示
                            val toastResId = if (gameEntity.wifiAutoDownload) {
                                // 已经开启wifi自动下载
                                R.string.has_enabled_for_auto_download_in_wifi
                            } else {
                                R.string.not_support_auto_download_in_wifi
                            }
                            ToastUtils.showToast(toastResId.toResString())
                        }

                    }

                }

                if ("appointment" == gameEntity.reserveStatus) {
                    holder.binding.gameItemIncluded.downloadBtn.setOnClickListener {
                        showCancelReservationDialog(gameEntity)
                    }
                } else {
                    DownloadItemUtils.setOnClickListener(
                        mContext,
                        holder.binding.gameItemIncluded.downloadBtn,
                        gameEntity,
                        position,
                        this,
                        mEntrance,
                        location = StringUtils.buildString(mEntrance, ":", gameEntity.name),
                        traceEvent = exposureEvent
                    )
                }
                initDownloadButtonOffset(holder.binding)

                holder.binding.gameItemIncluded.ivEdit.setOnClickListener {
                    CancelReservePop.create(
                        gameEntity,
                        mContext,
                        object : CancelReservePop.OnCancelReserveListener {
                            override fun enableAutoDownload(isEnable: Boolean) {
                                mViewModel.enableAutoDownload(isEnable, setOf(gameEntity))
                            }

                            override fun cancelReserve() {
                                showCancelReservationDialog(gameEntity)
                            }

                        }).showAsDropDown(holder.binding.gameItemIncluded.ivEdit)
                }
            }

            is FooterViewHolder -> {
                holder.initItemPadding()
                holder.initFooterViewHolder(mViewModel, mIsLoading, mIsNetworkError, mIsOver)
            }
        }
    }

    private fun updateSelectedStatus(selectIv: CheckableImageView, gameEntity: GameEntity) {
        if (pageState == MyReservationFragment.ReservePageState.CancelReserve) {
            selectIv.isChecked = selectedGames.any { gameEntity.id == it.id }
            val isChecked = selectedGames.any { gameEntity.id == it.id }
            if (isChecked) {
                selectIv.setImageResource(com.gh.gamecenter.common.R.drawable.ic_selector_selected)
            } else {
                selectIv.setImageResource(com.gh.gamecenter.common.R.drawable.ic_selector_default)
            }
        } else {   // 批量开启wifi自动下载
            when {
                !gameEntity.wifiAutoDownloadEnable -> { // 此游戏不支持wifi自动下载，不可勾选状态
                    selectIv.setImageResource(com.gh.gamecenter.common.R.drawable.ic_selector_unable)
                }

                gameEntity.wifiAutoDownload -> {// 已经开启了wifi自动下载，勾选-不可编辑状态
                    selectIv.setImageResource(com.gh.gamecenter.common.R.drawable.ic_selector_selected_unable)
                }

                else -> {    // 默认状态，可勾选
                    selectIv.setImageDrawable(DrawableView.getCheckSelectorDrawable(mContext))
                    selectIv.isChecked = selectedGames.any { gameEntity.id == it.id }
                }
            }

        }
    }

    fun notifyItemAndRemoveDownload(status: EBDownloadStatus) {
        val data = getGameEntityByPackage(status.packageName)
        for (gameAndPosition in data) {
            if (gameAndPosition.entity != null && gameAndPosition.entity.name == status.name) {
                gameAndPosition.entity.getEntryMap().remove(status.platform)
            }
            notifyItemChanged(gameAndPosition.position)
        }
    }

    fun getGameEntityByPackage(packageName: String): List<GameAndPosition> {
        val positionList = ArrayList<GameAndPosition>()
        val positionMap = mViewModel.positionAndPackageMap
        for (key in positionMap.keys) {
            if (key.contains(packageName)) {
                val position = positionMap[key]!!
                val game = entityList?.safelyGetInRelease(position)
                if (game != null) {
                    positionList.add(GameAndPosition(game, position))
                }
            }
        }
        return positionList
    }

    private fun initDownloadButtonOffset(binding: ItemFollowedGameBinding) {
        (binding.gameItemIncluded.downloadBtn.layoutParams as ViewGroup.MarginLayoutParams).apply {
            topMargin = DisplayUtils.dip2px(9F)
        }
    }

    private fun showCancelReservationDialog(game: GameEntity) {
        NewFlatLogUtils.logMyGameReserveTabGameCardClick("按钮", game.id, game.name ?: "")
        ReservationHelper.showCancelReservationDialog(mContext, game, {
            NewFlatLogUtils.logMyGameCancelReserveDialogClick("确定取消", game.id, game.name ?: "")
            mViewModel.cancelReservation(game)
        }, object : CancelListener {
            override fun onCancel() {
                NewFlatLogUtils.logMyGameCancelReserveDialogClick("关闭弹窗", game.id, game.name ?: "")
            }
        })
    }

    private fun showCancelReservationInBatchDialog(games: Set<GameEntity>) {
        // 批量删除，埋点在外部上报
        games.forEach {
            SensorsBridge.trackCancelAppointmentDialogShow(it.id, it.name ?: "", it.categoryChinese)
        }
        ReservationHelper.showCancelReservationDialog(mContext, null, {
            games.forEach {
                SensorsBridge.trackCancelAppointmentDialogClick(it.id, it.name ?: "", it.categoryChinese, "确定取消")
            }
            mViewModel.cancelReserveInBatch(games)
            if (allSelectPop.isShowing) {
                allSelectPop.dismiss()
            }
            mViewModel.changeReserveStatus(MyReservationFragment.ReservePageState.Normal)
        }, object : CancelListener {
            override fun onCancel() {
                games.forEach {
                    SensorsBridge.trackCancelAppointmentDialogClick(
                        it.id,
                        it.name ?: "",
                        it.categoryChinese,
                        "暂不取消"
                    )
                }
            }
        }, dialogCancelCallback = {
            games.forEach {
                SensorsBridge.trackCancelAppointmentDialogClick(it.id, it.name ?: "", it.categoryChinese, "关闭弹窗")
            }
        })
    }

    override fun getEventByPosition(pos: Int): ExposureEvent = mExposureEventSparseArray.get(pos)

    override fun getEventListByPosition(pos: Int) = null

    fun changeStatus(status: MyReservationFragment.ReservePageState) {
        if (pageState != status) {
            selectedGames.clear()
            pageState = status
            notifyItemRangeChanged(0, itemCount)

            if (status == MyReservationFragment.ReservePageState.Normal) {
                allSelectPop.dismiss()
            } else {
                allSelectPop.show(status, mContext)

            }
        }
    }

    fun updatePopupWindow() {
        with(allSelectPop.binding) {
            cbAll.setButtonDrawable(R.drawable.selector_kaifu_report)
            cbAll.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(mContext))
            tvNumber.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(mContext))
            tvNumber.background = com.gh.gamecenter.common.R.drawable.bg_common_button_fill_gradient_blue.toDrawable(mContext)
            tvSubmit.setTextColor(com.gh.gamecenter.common.R.color.text_aw_primary.toColor(mContext))
            root.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(mContext))
            vLine.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_divider.toColor(mContext))
        }
    }

}