package com.kaixed.kchat.ui.adapter

import android.content.Context
import android.graphics.drawable.ColorDrawable
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.PopupWindow
import androidx.core.view.updateMargins
import androidx.recyclerview.widget.RecyclerView
import com.kaixed.kchat.R
import com.kaixed.kchat.data.objectbox.ObjectBox
import com.kaixed.kchat.data.objectbox.entity.Messages
import com.kaixed.kchat.databinding.ChatRecycleItemCustomMineBinding
import com.kaixed.kchat.databinding.ChatRecycleItemCustomOtherBinding
import com.kaixed.kchat.databinding.ChatRecycleItemTipBinding
import com.kaixed.kchat.databinding.PopwindowsBinding
import com.kaixed.kchat.utils.ConstantsUtil.getUsername
import com.kaixed.kchat.utils.DensityUtil.dpToPx
import com.kaixed.kchat.utils.ImageSpanUtil
import com.kaixed.kchat.utils.TextUtil
import io.objectbox.Box
import java.util.LinkedList


class ChatAdapter(
    private val context: Context, private val messages: LinkedList<Messages>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    companion object {
        // 普通文本消息
        private const val ITEM_TYPE_CUSTOM_MINE = 0
        private const val ITEM_TYPE_CUSTOM_OTHER = 1

        // 提示消息，如撤回消息
        private const val ITEM_TYPE_TIP_MINE = 2
        private const val ITEM_TYPE_TIP_OTHER = 3

        // 图片消息
        private const val ITEM_TYPE_IMAGE_MINE = 4
        private const val ITEM_TYPE_IMAGE_OTHER = 5

        // 语音消息
        private const val ITEM_TYPE_VOICE_MINE = 6
        private const val ITEM_TYPE_VOICE_OTHER = 7

        // 位置消息
        private const val ITEM_TYPE_LOCATION_MINE = 8
        private const val ITEM_TYPE_LOCATION_OTHER = 9

        // 表情消息
        private const val ITEM_TYPE_EMOJI_MINE = 10
        private const val ITEM_TYPE_EMOJI_OTHER = 11

        // 红包消息
        private const val ITEM_TYPE_RED_PACKET_MINE = 12
        private const val ITEM_TYPE_RED_PACKET_OTHER = 13

        private const val TAG = "ChatAdapter"
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            ITEM_TYPE_CUSTOM_MINE -> {
                CustomViewMineHolder(
                    ChatRecycleItemCustomMineBinding.inflate(
                        LayoutInflater.from(parent.context), parent, false
                    )
                )
            }

            ITEM_TYPE_CUSTOM_OTHER -> {
                CustomViewOtherHolder(
                    ChatRecycleItemCustomOtherBinding.inflate(
                        LayoutInflater.from(parent.context), parent, false
                    )
                )
            }

            else -> {
                TipViewHolder(
                    ChatRecycleItemTipBinding.inflate(
                        LayoutInflater.from(parent.context), parent, false
                    )
                )
            }
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val singleMessage = messages[position]

        when (holder) {
            is TipViewHolder -> {
                holder.bindData(singleMessage)
            }

            is CustomViewMineHolder -> {
                if (position == messages.size - 1) {
                    holder.binding.tvTimer.visibility = View.VISIBLE
                    holder.binding.tvTimer.text =
                        TextUtil.getTimestampString(singleMessage.timestamp)
                } else {
                    if (singleMessage.timestamp - messages[position + 1].timestamp < 1L * 60 * 1000) {
                        holder.binding.tvTimer.visibility = View.GONE
                    } else {
                        holder.binding.tvTimer.visibility = View.VISIBLE
                        holder.binding.tvTimer.text =
                            TextUtil.getTimestampString(singleMessage.timestamp)
                    }
                }
                holder.binding.tvMessageContent.setOnLongClickListener {
                    showPopupWindow(
                        holder.binding.tvMessageContent, singleMessage.senderId == getUsername()
                    )
                    true
                }
                holder.binding.tvMessageContent.text = ImageSpanUtil.setEmojiSpan(
                    context, singleMessage.content, dpToPx(18)
                )
            }

            is CustomViewOtherHolder -> {
                if (position == messages.size - 1) {
                    holder.binding.tvTimer.visibility = View.VISIBLE
                    holder.binding.tvTimer.text =
                        TextUtil.getTimestampString(singleMessage.timestamp)
                } else {
                    if (singleMessage.timestamp - messages[position + 1].timestamp < 1L * 60 * 1000) {
                        holder.binding.tvTimer.visibility = View.GONE
                    } else {
                        holder.binding.tvTimer.visibility = View.VISIBLE
                        holder.binding.tvTimer.text =
                            TextUtil.getTimestampString(singleMessage.timestamp)
                    }
                }
                holder.binding.tvMessageContent.setOnLongClickListener {
                    showPopupWindow(
                        holder.binding.tvMessageContent, singleMessage.senderId == getUsername()
                    )
                    true
                }
                holder.binding.tvMessageContent.text = ImageSpanUtil.setEmojiSpan(
                    context, singleMessage.content, dpToPx(18)
                )
            }
        }
    }

    class TipViewHolder(val binding: ChatRecycleItemTipBinding) :
        RecyclerView.ViewHolder(binding.root) {
        fun bindData(message: Messages) {
            if (message.show) {
                binding.tvTip.text = binding.root.context.getString(
                    R.string.withdraw_message_format, message.senderId
                )
            }
        }
    }

    class CustomViewMineHolder(val binding: ChatRecycleItemCustomMineBinding) :
        RecyclerView.ViewHolder(binding.root)

    class CustomViewOtherHolder(val binding: ChatRecycleItemCustomOtherBinding) :
        RecyclerView.ViewHolder(binding.root)

    override fun getItemViewType(position: Int): Int {
        val message = messages[position]
        return if (message.senderId == getUsername()) {
            message.type.toInt()
        } else {
            message.type.toInt() + 1
        }
    }

    private fun updateDb(message: Messages) {
        val messagesBox: Box<Messages> = ObjectBox.get().boxFor(Messages::class.java)
        messagesBox.put(message)
    }

    override fun getItemCount(): Int = messages.size

    private fun showPopupWindow(parentView: View, isMine: Boolean) {
        val binding: PopwindowsBinding = PopwindowsBinding.inflate(LayoutInflater.from(context))
        val popupWindow: PopupWindow = PopupWindow(
            binding.root, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT
        ).apply {
            isFocusable = true
            isOutsideTouchable = true
            setBackgroundDrawable(ColorDrawable())
        }

        // 获取屏幕的总宽度
        val screenWidth = context.resources.displayMetrics.widthPixels
        val screenHeight = context.resources.displayMetrics.heightPixels

        val location = IntArray(2)
        parentView.getLocationOnScreen(location)
        binding.root.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)

        // popupWindow的长度
        val popupWidth = binding.root.measuredWidth
        val popupHeight = binding.root.measuredHeight

        val parentWidth = parentView.width
        val parentHeight = parentView.height

        val parentX = location[0]

        // 父布局中心点横坐标
        val distanceToLeftEdge = parentX + parentView.width / 2
        // 中心点距离右侧距离
        val distanceToRightEdge = screenWidth - distanceToLeftEdge


        binding.ivArrowDown.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
        val arrowWidth = binding.ivArrowDown.measuredWidth

        val isYEnoughSpace = (screenHeight - popupHeight) > popupHeight
        val xOffset: Int
        val yOffset = if (isYEnoughSpace) -popupHeight - parentHeight + arrowWidth / 3 else 0
        val marginStart: Int

        var rightEnough = false
        var leftEnough = false

        if (isYEnoughSpace) {
            binding.ivArrowUp.visibility = View.GONE
            binding.ivArrowDown.visibility = View.VISIBLE
        } else {
            binding.ivArrowUp.visibility = View.VISIBLE
            binding.ivArrowDown.visibility = View.GONE
        }


        if (isMine) {
            rightEnough = (popupWidth / 2) < distanceToRightEdge
            xOffset = if (rightEnough)
                (parentWidth - popupWidth) / 2
            else
                parentWidth - popupWidth + dpToPx(45)

            marginStart = popupWidth - (dpToPx(55) + parentWidth / 2)

        } else {
            leftEnough = (popupWidth / 2) < distanceToLeftEdge
            xOffset = if (leftEnough) parentWidth - popupWidth
            else -dpToPx(45)

            marginStart = dpToPx(35) + parentWidth / 2
        }


        binding.ivArrowDown.layoutParams =
            (binding.ivArrowUp.layoutParams as LinearLayout.LayoutParams).apply {
                val enoughSpace = if (isMine) rightEnough else leftEnough
                if (enoughSpace) {
                    gravity = Gravity.CENTER_HORIZONTAL
                } else {
                    updateMargins(left = marginStart)
                }
            }

        popupWindow.showAsDropDown(parentView, xOffset, yOffset)

//        binding.ivWithdraw.setOnClickListener {
//            messages[position].status = "withdraw"
//            updateDb(messages[position])
//            notifyItemChanged(position)
//            popupWindow.dismiss()
//        }
    }
}
