package com.gh.gamecenter.home.custom.adapter

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.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.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.CustomPageTrackData
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.home.custom.eventlistener.OtherItemEventHelper
import com.gh.gamecenter.retrofit.RetrofitManager
import com.google.android.flexbox.FlexboxLayout
import com.lightgame.download.DownloadEntity
import okhttp3.ResponseBody

class CustomDiscoverCardGameAdapter(
    context: Context,
    private var entrance: String,
    private val childEventHelper: OtherItemEventHelper
) : CustomBaseChildAdapter<GameEntity, DiscoveryGameViewHolder>(context) {

    override fun getKey(t: GameEntity): String {
        return t.id
    }

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

    override fun onBindViewHolder(holder: DiscoveryGameViewHolder, position: Int) {
        val gameEntity = dataList[position]
        val isEndOfRow = position >= if (itemCount % SPAN_COUNT == 0) {
            itemCount - SPAN_COUNT
        } else {
            itemCount - itemCount % SPAN_COUNT
        }
        val screenWidth = context.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(context, gameEntity, holder, "star")
        holder.bindGameItem(gameEntity)
        holder.itemView.setBackgroundColor(com.gh.gamecenter.common.R.color.transparent.toColor(context))
        holder.itemView.setOnClickListener {
            childEventHelper.trackGameExploreClick("游戏", game = gameEntity)
            childEventHelper.navigateToGameDetailPageByGame(position, gameEntity)
        }
        holder.itemView.setOnLongClickListener {
            showDislikeWindow(holder.itemView, gameEntity)
            true
        }

        DownloadItemUtils.setOnClickListener(
            context,
            holder.binding.downloadBtn,
            gameEntity,
            position,
            this,
            StringUtils.buildString("(${entrance}", "-发现页卡片[", (position).toString(), "])"),
            location = StringUtils.buildString(entrance, ":", gameEntity.name),
            traceEvent = gameEntity.exposureEvent
        ) {
            childEventHelper.trackGameExploreClick("按钮", game = gameEntity)
            childEventHelper.onDownloadButtonClick(position, gameEntity)
        }
    }

    @SuppressLint("CheckResult")
    private fun showDislikeWindow(view: View, gameEntity: GameEntity) {
        val decorView = (context as? Activity)?.window?.decorView as? FrameLayout
        val binding = LayoutPopupDiscoveryDislikeBinding.inflate(LayoutInflater.from(context), 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 = dataList.indexOf(gameEntity)
                if (index < 0) return@setOnClickListener
                discoveryFeedback(gameEntity.id, popupItem.text.toString(), gameEntity.type ?: "") {
                    _dataList.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(context).apply {
            height = 32F.dip2px()
            text = reason
            textSize = 12F
            includeFontPadding = false
            setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(context))
            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(context)
        }
    }

    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("反馈失败")
                }
            })
    }

    override fun notifyDownload(download: DownloadEntity) {
        dataList.forEachIndexed { index, item ->
            if (item.id == download.gameId) {
                notifyItemChanged(index)
            }
        }
    }

    override fun notifyDownloadDeleted(status: EBDownloadStatus) {
        notifyChildItem(status.packageName)
    }

    override fun notifyInstalled(busFour: EBPackage) {
        notifyChildItem(busFour.packageName)
    }

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

    companion object {
        const val SPAN_COUNT = 3
    }
}