package com.adealink.weparty.playmate.list.adapter

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.Observer
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.log.Log
import com.adealink.frame.util.onClick
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.hide
import com.adealink.weparty.commonui.ext.isViewValid
import com.adealink.weparty.commonui.ext.show
import com.adealink.weparty.commonui.recycleview.adapter.BindingViewHolder
import com.adealink.weparty.commonui.recycleview.adapter.multitype.ItemViewBinder
import com.adealink.weparty.module.order.data.OrderDiscountInfo
import com.adealink.weparty.module.order.data.getFinalPrice
import com.adealink.weparty.module.order.data.observeDiscount
import com.adealink.weparty.module.order.data.unObserveDiscount
import com.adealink.weparty.playmate.R
import com.adealink.weparty.playmate.data.PlaymateListData
import com.adealink.weparty.playmate.data.PlaymateListItemData
import com.adealink.weparty.playmate.databinding.ItemPlaymateHomeListBinding
import com.adealink.weparty.util.formatDistanceStr
import com.adealink.weparty.util.formatNumber
import com.adealink.weparty.util.formatStar
import com.adealink.weparty.R as APP_R

class PlaymateListItemViewBinder(
    val lifecycleOwner: LifecycleOwner,
    val listener: OnPlaymateListListener
) : ItemViewBinder<PlaymateListItemData, PlaymateListItemViewBinder.ViewHolder>() {


    override fun onCreateViewHolder(
        inflater: LayoutInflater,
        parent: ViewGroup,
    ): ViewHolder {
        return ViewHolder(ItemPlaymateHomeListBinding.inflate(inflater, parent, false)).also {
            it.initView()
        }
    }

    override fun onViewDetachedFromWindow(holder: ViewHolder) {
        super.onViewDetachedFromWindow(holder)
        holder.binding.vVoice.stopPlay()
        holder.binding.vOnline.onStop()
    }

    override fun onViewAttachedToWindow(holder: ViewHolder) {
        super.onViewAttachedToWindow(holder)
        observeDiscount(lifecycleOwner, holder.discountObserver)
    }

    override fun onViewRecycled(holder: ViewHolder) {
        super.onViewRecycled(holder)
        holder.binding.vVoice.stopPlay()
        holder.binding.vOnline.onStop()
        unObserveDiscount(holder.discountObserver)
    }

    override fun onBindViewHolder(
        holder: ViewHolder,
        item: PlaymateListItemData
    ) {
        holder.update(item)
    }

    inner class ViewHolder(
        rootBinding: ItemPlaymateHomeListBinding,
    ) : BindingViewHolder<ItemPlaymateHomeListBinding>(rootBinding) {
        private var item: PlaymateListItemData? = null

        fun initView() {
            binding.root.onClick {
                val item = item ?: return@onClick
                listener.goCategoryDetail(item.data)
            }
        }

        fun update(item: PlaymateListItemData) {
            this.item = item
            binding.ivAvatar.setImageUrl(item.data.avatar)
            if (item.data.voice.isEmpty()) {
                binding.vVoice.gone()
                binding.vVoice.setSoundUrl(null)
            } else {
                binding.vVoice.show()
                binding.vVoice.setSoundUrl(item.data.voice)
            }
            if (item.data.online) {
                binding.vOnline.show()
                binding.vOnline.onStart()
            } else {
                binding.vOnline.gone()
                binding.vOnline.onStop()
            }

            binding.tvName.text = item.data.nickname
            binding.vGender.setAge(item.data.age)
            binding.vGender.setGender(item.data.gender)
            binding.tvLocation.text = formatDistanceStr(item.data.distance)

            if (item.data.newcomer == true) {
                binding.clNew.show()
                binding.clComment.gone()
            } else {
                binding.clNew.gone()
                binding.clComment.show()
                binding.tvStar.text = formatStar(item.data.star)
                binding.tvComment.text =
                    getCompatString(
                        R.string.playmate_comment_count,
                        item.data.commentCount.toString()
                    )
            }

            binding.ivCategory.setImageUrl(item.data.categoryIcon)
            binding.tvCategory.text = item.data.categoryName
            if (item.data.summary.isEmpty()) {
                binding.tvSummary.gone()
            } else {
                binding.tvSummary.show()
                binding.tvSummary.text = item.data.summary
            }
            item.data.photos.getOrNull(0)?.takeIf { it.isNotEmpty() }?.let {
                binding.ivPhoto1.show()
                binding.ivPhoto1.setImageUrl(it)
            } ?: let {
                binding.ivPhoto1.hide()
            }

            item.data.photos.getOrNull(1)?.takeIf { it.isNotEmpty() }?.let {
                binding.ivPhoto2.show()
                binding.ivPhoto2.setImageUrl(it)
            } ?: let {
                binding.ivPhoto2.hide()
            }

            item.data.photos.getOrNull(2)?.takeIf { it.isNotEmpty() }?.let {
                binding.ivPhoto3.show()
                binding.ivPhoto3.setImageUrl(it)
            } ?: let {
                binding.ivPhoto3.hide()
            }

            notifyPriceChanged()
        }

        val discountObserver = object : Observer<OrderDiscountInfo?> {

            override fun onChanged(value: OrderDiscountInfo?) {
                notifyPriceChanged()
            }
        }

        private fun notifyPriceChanged() {
            if (!this@ViewHolder.isViewValid()) {
                return
            }
            val item = this@ViewHolder.item
            val finalPrice = getFinalPrice(item?.data?.price ?: 0f)
            if (finalPrice.hasDiscount()) {
                //折扣价
                binding.vPrice.setDiscount(finalPrice.discountPrice, item?.data?.unit)
                binding.vPriceDiscount.show()
                binding.vPriceDiscount.text = getCompatString(
                    APP_R.string.common_price_discount,
                    formatNumber(finalPrice.discountPercent, true)
                )
            } else {
                binding.vPrice.setPrice(item?.data?.price ?: 0f, item?.data?.unit)
                binding.vPriceDiscount.gone()
            }
        }
    }

    interface OnPlaymateListListener {
        fun goCategoryDetail(data: PlaymateListData)
    }
}