package com.gh.gamecenter.servers

import android.content.Context
import android.text.TextUtils
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.databind.BindingAdapters
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureEvent.Companion.createEvent
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.common.exposure.IExposable
import com.gh.common.util.*
import com.gh.gamecenter.common.view.DrawableView.getServerDrawableBySource
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.adapter.viewholder.GameTestViewHolder
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.toDrawable
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureConstants
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.lightgame.adapter.BaseRecyclerAdapter
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList

class GameServersContentAdapter(
    context: Context,
    private val mViewModel: GameServersContentViewModel,
    private val mBasicExposureSourceList: ArrayList<ExposureSource>?,
    private val mEntrance: String
) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context), IExposable {

    var mDataList = arrayListOf<GameEntity>()
    private val mExposureEventArray: SparseArray<ExposureEvent> = SparseArray()
    private var mPrevIsOver = false
    private var mPrevIsNetworkError = false
    private var mPrevIsLoading = false
    private var mNextIsOver = false
    private var mNextIsNetworkError = false
    private var mNextIsLoading = false
    private var mIsShowPullDownTip = false

    fun submitList(
        updateData: ArrayList<GameEntity>,
        isShowPullDownTip: Boolean,
        isDown: Boolean = false,
        downSize: Int = 0
    ) {
        mDataList = updateData
        mIsShowPullDownTip = isShowPullDownTip
        if (isDown) {
            notifyItemRangeInserted(0, downSize)
        } else {
            notifyDataSetChanged()
        }
    }

    fun resetStatus() {
        mPrevIsOver = false
        mPrevIsNetworkError = false
        mPrevIsLoading = false
        mNextIsOver = false
        mNextIsNetworkError = false
        mNextIsLoading = false
    }

    fun loadChange(pair: Pair<String?, LoadStatus>) {
        if (pair.first == "down") {
            when (pair.second) {
                LoadStatus.INIT -> {
                    mPrevIsLoading = true
                    mPrevIsOver = false
                    mPrevIsNetworkError = false
                }
                LoadStatus.INIT_OVER -> {
                    mPrevIsLoading = false
                    mPrevIsOver = true
                    mPrevIsNetworkError = false
                }
                LoadStatus.INIT_LOADED, LoadStatus.INIT_EMPTY -> {
                    mPrevIsLoading = false
                    mPrevIsOver = false
                    mPrevIsNetworkError = false
                }
                LoadStatus.INIT_FAILED -> {
                    mPrevIsLoading = false
                    mPrevIsOver = false
                    mPrevIsNetworkError = true
                }
                else -> {
                    // do nothing
                }
            }
            notifyItemChanged(0)
        } else {
            when (pair.second) {
                LoadStatus.INIT -> {
                    mNextIsLoading = true
                    mNextIsOver = false
                    mNextIsNetworkError = false
                }
                LoadStatus.INIT_OVER -> {
                    mNextIsLoading = false
                    mNextIsOver = true
                    mNextIsNetworkError = false
                }
                LoadStatus.INIT_LOADED, LoadStatus.INIT_EMPTY -> {
                    mNextIsLoading = false
                    mNextIsOver = false
                    mNextIsNetworkError = false
                }
                LoadStatus.INIT_FAILED -> {
                    mNextIsLoading = false
                    mNextIsOver = false
                    mNextIsNetworkError = true
                }
                else -> {
                    // do nothing
                }
            }
            notifyItemChanged(itemCount - 1)
        }
    }

    override fun getItemCount() = if (mDataList.size == 0) 0 else mDataList.size + 2

    override fun getItemViewType(position: Int): Int {
        if (position == mDataList.size + 1 || position == 0) {
            return VIEW_TYPE_FOOTER
        }

        val gameEntity = mDataList[position - 1]
        return if (gameEntity.kaifuTimeHint != null && gameEntity.kaifuTimeHint != 0L || gameEntity.fixedTopHint!!) {
            VIEW_TYPE_TOP
        } else VIEW_TYPE_ITEM
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            VIEW_TYPE_FOOTER -> FooterViewHolder(mLayoutInflater.inflate(com.gh.gamecenter.common.R.layout.refresh_footerview, parent, false))
            VIEW_TYPE_TOP -> GameServerTimeViewHolder(parent.toBinding())
            else -> GameTestViewHolder(parent.toBinding())
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is GameTestViewHolder -> {
                val gameEntity = mDataList[position - 1]
                gameEntity.subPageCode = ExposureConstants.GAME_SERVERS

                var fixedTop = ""
                if (gameEntity.serverEntity != null && gameEntity.serverEntity!!.getTime() == 0L) {
                    fixedTop = "热门开服"
                }
                val mExposureSourceList = arrayListOf<ExposureSource>()
                if (mBasicExposureSourceList != null) {
                    mExposureSourceList.addAll(mBasicExposureSourceList)
                }
                mExposureSourceList.add(ExposureSource("开服表"))

                // 热门开服与其它的曝光路径区分开
                if (!TextUtils.isEmpty(fixedTop)) {
                    mExposureSourceList.add(ExposureSource("开服", fixedTop))
                } else {
                    val exposureSourceValue: String = getExposureSourceValue()
                    mExposureSourceList.add(ExposureSource("开服", exposureSourceValue))
                }
                val exposureEvent = createEvent(
                    gameEntity,
                    mExposureSourceList,
                    null,
                    ExposureType.EXPOSURE
                )
                mExposureEventArray.put(position, exposureEvent)

                val serverRemaining = gameEntity.serverRemaining
                if (serverRemaining != null) {
                    holder.binding.extendContainer.visibility = View.VISIBLE
                    holder.binding.extendContainer.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(mContext))
                    holder.binding.extendContent.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(mContext))
                    holder.binding.extendContent.text = "展开剩余" + serverRemaining.size + "条开服信息"
                    holder.binding.extendContent.setOnClickListener {
                        mViewModel.mergerRemainingData(gameEntity, position)
                        notifyItemChanged(position)
                    }
                } else {
                    holder.binding.extendContainer.visibility = View.GONE
                }

                if (position != 0 && getItemViewType(position - 1) == VIEW_TYPE_TOP) {
                    holder.binding.contentContainer.setPadding(
                        DisplayUtils.dip2px(16f), DisplayUtils.dip2px(4f),
                        DisplayUtils.dip2px(18f), DisplayUtils.dip2px(8f)
                    )
                } else if (getItemViewType(position + 1) == VIEW_TYPE_TOP) {
                    holder.binding.contentContainer.setPadding(
                        DisplayUtils.dip2px(16f), DisplayUtils.dip2px(8f),
                        DisplayUtils.dip2px(18f), DisplayUtils.dip2px(16f)
                    )
                } else {
                    holder.binding.contentContainer.setPadding(
                        DisplayUtils.dip2px(16f), DisplayUtils.dip2px(8f),
                        DisplayUtils.dip2px(18f), DisplayUtils.dip2px(8f)
                    )
                }
                initGameTestViewHolder(gameEntity, holder)
            }

            is GameServerTimeViewHolder -> {
                holder.binding.root.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(mContext))
                holder.binding.kaifuItemTimeTv.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(mContext))
                if (mIsShowPullDownTip && position == 1) {
                    holder.binding.emptyView.visibility = View.VISIBLE
                } else {
                    holder.binding.emptyView.visibility = View.GONE
                }
                val gameEntity = mDataList[position - 1]
                if (gameEntity.fixedTopHint!!) {
                    holder.binding.kaifuItemHeader.setImageResource(R.drawable.ic_kaifu_hot)
                    holder.binding.kaifuItemTimeTv.text = "热门开服"
                } else {
                    val dateFm = SimpleDateFormat("yyyy-MM-dd (EEEE) HH:mm", Locale.CHINA)
                    holder.binding.kaifuItemHeader.setImageResource(R.drawable.kaifu_time_icon)
                    holder.binding.kaifuItemTimeTv.text = dateFm.format(gameEntity.kaifuTimeHint!! * 1000)
                }
            }

            is FooterViewHolder -> {
                holder.run {
                    itemView.setBackgroundColor(com.gh.gamecenter.common.R.color.ui_background.toColor(mContext))
                    if (position == 0) {
                        when {
                            mPrevIsNetworkError -> {
                                loading.visibility = View.GONE
                                hint.setText(com.gh.gamecenter.common.R.string.loading_failed_retry)
                                itemView.isClickable = true
//                            itemView.setOnClickListener(onClickListener)
                            }
                            mPrevIsOver -> {
                                loading.visibility = View.GONE
                                hint.setText(com.gh.gamecenter.common.R.string.load_over_hint)
                                itemView.isClickable = true
//                            itemView.setOnClickListener(onClickListener)
                            }
                            else -> {
                                loading.visibility = View.VISIBLE
                                hint.setText(com.gh.gamecenter.common.R.string.loading)
                                itemView.isClickable = false
                            }
                        }
                    } else {
                        when {
                            mNextIsNetworkError -> {
                                loading.visibility = View.GONE
                                hint.setText(com.gh.gamecenter.common.R.string.loading_failed_retry)
                                itemView.isClickable = true
//                            itemView.setOnClickListener(onClickListener)
                            }
                            mNextIsOver -> {
                                loading.visibility = View.GONE
                                hint.setText(com.gh.gamecenter.common.R.string.load_over_hint)
                                itemView.isClickable = true
//                            itemView.setOnClickListener(onClickListener)
                            }
                            else -> {
                                loading.visibility = View.VISIBLE
                                hint.setText(com.gh.gamecenter.common.R.string.loading)
                                itemView.isClickable = false
                            }
                        }
                    }
                }
            }
        }
    }

    private fun initGameTestViewHolder(gameEntity: GameEntity, viewHolder: GameTestViewHolder) {
        viewHolder.run {
            binding.contentContainer.background = com.gh.gamecenter.common.R.drawable.reuse_listview_item_style.toDrawable(mContext)
            gameName.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(mContext))
            gameDes.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(mContext))
        }

        viewHolder.gameName.text = gameEntity.name
        BindingAdapters.setGame(viewHolder.gameThumb, gameEntity)

        if (gameEntity.serverEntity == null || TextUtils.isEmpty(gameEntity.serverEntity!!.remark)) {
            viewHolder.binding.home2TestTime.visibility = View.GONE
        } else {
            viewHolder.binding.home2TestTime.visibility = View.VISIBLE
            viewHolder.binding.home2TestTime.text = gameEntity.serverEntity!!.remark
            viewHolder.binding.home2TestType.background = getServerDrawableBySource(com.gh.gamecenter.common.R.color.tag_orange)
        }

        GameItemViewHolder.initGameSubtitleAndAdLabel(
            gameEntity,
            viewHolder.binding.gameSubtitleTv,
            forceShowSubtitle = true
        )

        if (gameEntity.fixedTop!!) {
            val tag = "今日开服"
            viewHolder.binding.home2TestType.visibility = View.VISIBLE
            viewHolder.binding.home2TestType.text = tag
            viewHolder.binding.home2TestType.background = getServerDrawableBySource(com.gh.gamecenter.common.R.color.tag_yellow)
        } else {
            val type = gameEntity.serverEntity!!.type
            if (TextUtils.isEmpty(type)) {
                viewHolder.binding.home2TestType.visibility = View.GONE
            } else if (("不删档内测" == type || "删档内测" == type || "公测" == type)
                && TextUtils.isEmpty(gameEntity.serverEntity!!.getNote())
            ) {
                if (!TextUtils.isEmpty(gameEntity.serverEntity!!.getNote())) {
                    val testType: String? = if ("公测" == type) {
                        gameEntity.serverEntity!!.type + "：" + gameEntity.serverEntity!!.getNote()
                    } else {
                        gameEntity.serverEntity!!.getNote()
                    }
                    viewHolder.binding.home2TestType.text = testType
                    viewHolder.binding.home2TestType.background = getServerDrawableBySource(com.gh.gamecenter.common.R.color.tag_yellow)
                    viewHolder.binding.home2TestType.visibility = View.VISIBLE
                } else {
                    viewHolder.binding.home2TestType.visibility = View.GONE
                }
            } else {
                viewHolder.binding.home2TestType.text = gameEntity.serverEntity!!.getNote()
                viewHolder.binding.home2TestType.background = getServerDrawableBySource(com.gh.gamecenter.common.R.color.tag_yellow)
                viewHolder.binding.home2TestType.visibility = View.VISIBLE
            }
        }

        if (gameEntity.getApk().isEmpty()) {
            viewHolder.gameDes.text = gameEntity.brief
        } else {
            viewHolder.gameDes.text = String.format("%s  %s", gameEntity.getApk()[0].size, gameEntity.brief)
        }

        DownloadItemUtils.setOnClickListener(
            mContext,
            viewHolder.gameDownloadBtn, gameEntity, viewHolder.adapterPosition, this@GameServersContentAdapter,
            StringUtils.buildString(mEntrance, "+(开服表[", viewHolder.adapterPosition.toString(), "])"),
            location = StringUtils.buildString("开服表:", gameEntity.name),
            traceEvent = mExposureEventArray.get(viewHolder.adapterPosition)
        )

        DownloadItemUtils.updateItem(mContext, gameEntity, viewHolder)

        viewHolder.itemView.setOnClickListener {
            GameDetailActivity.startGameDetailActivity(
                mContext,
                gameEntity,
                StringUtils.buildString(mEntrance, "+(开服表[", viewHolder.adapterPosition.toString(), "])"),
                traceEvent = mExposureEventArray.get(viewHolder.adapterPosition)
            )
        }
    }

    private fun getExposureSourceValue(): String {
        val sb = StringBuilder()
        when (mViewModel.day) {
            "today" -> {
                sb.append("今日")
            }
            "after" -> {
                sb.append("后续")
            }
            "tomorrow" -> {
                sb.append("明日")
            }
            else -> {
                sb.append("全部")
            }
        }
        sb.append("开服")
        if (mViewModel.hour != null) {
            sb.append(mViewModel.hour)
            sb.append("时")
        }
        if (mViewModel.tags != null) {
            sb.append("+")
            sb.append(mViewModel.tags!!.replace("-", "+"))
        }
        return sb.toString()
    }

    fun isPrevLoading() = mPrevIsLoading

    fun isPrevOver() = mPrevIsOver

    fun isNextLoading() = mNextIsLoading

    fun isNextOver() = mNextIsOver

    override fun getEventByPosition(pos: Int): ExposureEvent? {
        return mExposureEventArray[pos]
    }

    override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
        return null
    }

    companion object {
        const val VIEW_TYPE_TOP = 0
        const val VIEW_TYPE_ITEM = 1
        const val VIEW_TYPE_FOOTER = 2
    }
}