package com.gh.gamecenter.home.discovercard

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.RelativeLayout
import android.widget.TextView
import com.gh.common.util.DownloadItemUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.LayoutPopupDiscoveryDislikeBinding
import com.gh.gamecenter.discovery.DiscoveryAdapter.DiscoveryGameViewHolder
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.google.android.flexbox.FlexboxLayout
import com.lightgame.adapter.BaseRecyclerAdapter
import com.lightgame.download.DownloadEntity
import okhttp3.ResponseBody

class DiscoverCardGameAdapter(
    context: Context,
    private var mEntrance: String,
    private var mList: ArrayList<GameEntity>
) : BaseRecyclerAdapter<DiscoveryGameViewHolder>(context) {

    private var mCountAndKey: Pair<Int, String>? = null

    init {
        var dataIds = ""
        mList.forEach {
            dataIds += it.id
        }
        if (dataIds.isNotEmpty()) mCountAndKey = Pair(mList.size, dataIds)
    }

    override fun getItemCount() = mList.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DiscoveryGameViewHolder {
        return DiscoveryGameViewHolder(parent.toBinding())
    }

    override fun onBindViewHolder(holder: DiscoveryGameViewHolder, position: Int) {
        val gameEntity = mList[position]
        val isEndOfRow = position >= if (itemCount % SPAN_COUNT == 0) {
            itemCount - SPAN_COUNT
        } else {
            itemCount - itemCount % SPAN_COUNT
        }
        val screenWidth = mContext.resources.displayMetrics.widthPixels
        if (!isEndOfRow) {
            holder.itemView.layoutParams = ViewGroup.LayoutParams(screenWidth - 58F.dip2px(), 76F.dip2px())
            holder.itemView.setPadding(14F.dip2px(), 0, 0, 0)
        } else {
            holder.itemView.layoutParams = ViewGroup.LayoutParams(screenWidth - 44F.dip2px(), 76F.dip2px())
            holder.itemView.setPadding(14F.dip2px(), 0, 14F.dip2px(), 0)
        }
        DownloadItemUtils.updateItem(mContext, gameEntity, holder, "star")
        holder.bindGameItem(gameEntity)
        holder.itemView.setBackgroundColor(com.gh.gamecenter.common.R.color.transparent.toColor(mContext))
        holder.itemView.setOnClickListener {
            GameDetailActivity.startGameDetailActivity(
                mContext,
                gameEntity,
                StringUtils.buildString("(${mEntrance}", "-发现页卡片[", (position).toString(), "])"),
                traceEvent = gameEntity.exposureEvent
            )
        }
        holder.itemView.setOnLongClickListener {
            showDislikeWindow(holder.itemView, gameEntity)
            true
        }
        DownloadItemUtils.setOnClickListener(
            mContext,
            holder.binding.downloadBtn,
            gameEntity,
            position,
            this,
            StringUtils.buildString("(${mEntrance}", "-发现页卡片[", (position).toString(), "])"),
            location = StringUtils.buildString(mEntrance, ":", gameEntity.name),
            traceEvent = gameEntity.exposureEvent
        )
    }

    @SuppressLint("CheckResult")
    private fun showDislikeWindow(view: View, gameEntity: GameEntity) {
        val decorView = (mContext as Activity).window.decorView as? FrameLayout
        val binding = LayoutPopupDiscoveryDislikeBinding.inflate(LayoutInflater.from(mContext), decorView, true)
        binding.reasonFlex.removeAllViews()
        Constants.FEEDBACK_REASON_LIST.toList().forEach {
            val popupItem = getPopupItem(it)
            val params =
                FlexboxLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
            binding.reasonFlex.addView(popupItem, params)
            popupItem.setOnClickListener {
                val index = mList.indexOf(gameEntity)
                if (index < 0) return@setOnClickListener
                discoveryFeedback(gameEntity.id, popupItem.text.toString(), gameEntity.type ?: "") {
                    mList.removeAt(index)
                    notifyItemRemoved(index)
                    decorView?.removeView(binding.root)
                    ToastUtils.showToast("已根据你的偏好优化推荐机制~", Gravity.CENTER)
                }
            }
        }
        binding.root.setOnClickListener {
            decorView?.removeView(it)
        }
        binding.contentView.visibility = View.INVISIBLE
        binding.contentView.post {
            val (windowPosition, isNeedShowUp) = getWindowPosition(view, binding.contentView, 36F.dip2px())
            (binding.contentView.layoutParams as RelativeLayout.LayoutParams).run {
                topMargin = windowPosition[1]
                binding.contentView.layoutParams = this
            }
            binding.anchorUpIv.goneIf(isNeedShowUp)
            binding.anchorDownIv.goneIf(!isNeedShowUp)
            binding.contentView.visibility = View.VISIBLE
        }
    }

    private fun getPopupItem(reason: String): TextView {
        return TextView(mContext).apply {
            height = 32F.dip2px()
            text = reason
            textSize = 12F
            includeFontPadding = false
            setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(mContext))
            gravity = Gravity.CENTER
            setPadding(12F.dip2px(), 0F.dip2px(), 12F.dip2px(), 0F.dip2px())
            background = com.gh.gamecenter.common.R.drawable.bg_shape_space_radius_8.toDrawable(mContext)
        }
    }

    private fun getWindowPosition(
        anchorView: View,
        contentView: View,
        distanceY: Int = 0
    ): Pair<IntArray, Boolean> {
        val windowPos = IntArray(2)
        val anchorLoc = IntArray(2)
        anchorView.getLocationInWindow(anchorLoc)
        val anchorHeight = anchorView.height
        val screenHeight = anchorView.context.resources.displayMetrics.heightPixels
        contentView.measure(0, 0)
        val contentViewWidth = contentView.width
        val contentViewHeight = contentView.height
        val isNeedShowUp = screenHeight - anchorLoc[1] - anchorHeight < contentViewHeight
        windowPos[1] = if (isNeedShowUp) {
            anchorLoc[1] - contentViewHeight + distanceY
        } else {
            anchorLoc[1] + anchorHeight - distanceY
        }
        windowPos[0] = (anchorLoc[0] - contentViewWidth + anchorView.width) / 2
        return Pair(windowPos, isNeedShowUp)
    }

    @SuppressLint("CheckResult")
    private fun discoveryFeedback(gameId: String, reason: String, type: String, callback: () -> Unit) {
        val paramsMap = mapOf(
            "reason" to reason,
            "type" to type
        )
        RetrofitManager.getInstance().api.discorveryFeedback(gameId, paramsMap.toRequestBody())
            .compose(singleToMain())
            .subscribe(object : BiResponse<ResponseBody>() {

                override fun onSuccess(data: ResponseBody) {
                    callback.invoke()
                }

                override fun onFailure(exception: Exception) {
                    super.onFailure(exception)
                    ToastUtils.showToast("反馈失败")
                }
            })
    }

    fun notifyItemByDownload(downloadEntity: DownloadEntity?) {
        if (downloadEntity == null) {
            notifyDataSetChanged()
        } else {
            mList.forEachIndexed { position, gameEntity ->
                if (downloadEntity.gameId == gameEntity.id) {
                    notifyItemChanged(position)
                }
            }
        }
    }

    fun notifyChildItem(packageName: String) {
        mList.forEachIndexed { position, gameEntity ->
            gameEntity.getApk().forEach { apkEntity ->
                if (apkEntity.packageName == packageName) {
                    notifyItemChanged(position)
                    return
                }
            }
        }
    }

    fun checkResetData(update: ArrayList<GameEntity>) {
        var dataIds = ""
        update.forEach { dataIds += it.id }

        mList = update
        if (mCountAndKey?.first == update.size && mCountAndKey?.second != dataIds) { // 数量不变,内容发生改变
            notifyItemRangeChanged(0, itemCount)
        } else if (mCountAndKey?.first != update.size) { // 数量发生改变
            notifyDataSetChanged()
        }

        // 重新刷新数据标识
        mCountAndKey = Pair(update.size, dataIds)
    }

    companion object {
        const val SPAN_COUNT = 3
    }
}