package com.atmob.keyboard_android.popup

import android.annotation.SuppressLint
import android.content.Context
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.atmob.keyboard_android.R
import com.atmob.keyboard_android.enums.Mode
import com.atmob.keyboard_android.model.ModeItem
import com.atmob.keyboard_android.popup.item.ModeListItemViewBinder
import com.blankj.utilcode.util.ConvertUtils
import me.drakeet.multitype.Items
import me.drakeet.multitype.MultiTypeAdapter

/**
 * 模式切换PopupWindow弹窗
 */
class ModeSwitchPopupWindow(private val context: Context) {
    private var popupWindow: PopupWindow? = null

    /**
     * 显示弹窗
     *
     * @param anchorView 锚点View
     */
    @SuppressLint("InflateParams", "NotifyDataSetChanged")
    fun show(anchorView: View) {
        if (isShowing()) {
            return
        }

        val context = anchorView.context

        if (popupWindow == null) {
            val contentView =
                LayoutInflater.from(context).inflate(R.layout.popup_mode_switch_attach, null, false)

            val currentSelectModeLayout: View =
                contentView.findViewById(R.id.current_select_mode_layout)
            val currentSelectMode: TextView = contentView.findViewById(R.id.current_select_mode)
            val list: RecyclerView = contentView.findViewById(R.id.list)

            currentSelectModeLayout.setOnClickListener {
                dismiss()
            }

            val listItems = Items().apply {
                addAll(Mode.getAll().mapIndexed { index, item ->
                    // TODO: 先写死选中第一个，后续根据flutter端传过来的模式，来决定选中哪个
                    ModeItem(item, selected = index == 0)
                })
            }

            list.apply {
                layoutManager = LinearLayoutManager(context)
                adapter = MultiTypeAdapter(listItems).apply {
                    register(ModeItem::class.java, ModeListItemViewBinder { item ->
                        // 先全部反选
                        listItems.map {
                            if (it is ModeItem) {
                                it.selected = false
                            }
                            it
                        }
                        // 再选中当前选择的模式
                        val targetPosition = listItems.indexOf(item)
                        val targetItem = listItems[targetPosition] as ModeItem
                        targetItem.selected = true
                        notifyDataSetChanged()

                        // 更新当前选择的模式
                        currentSelectMode.text = targetItem.mode.modeName

                        // 关闭弹窗
                        dismiss()
                    })
                }
            }

            popupWindow = PopupWindow(
                contentView,
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT,
                true
            ).apply {
                // 不获取焦点，否则获取焦点会将软键盘关闭
                isFocusable = false
                // 点击外部关闭
                isOutsideTouchable = true
                // 保持输入法活跃
                inputMethodMode = PopupWindow.INPUT_METHOD_NEEDED
                // 设置弹出动画
                animationStyle = R.style.PopupAnimation
            }
        }

        // 获取相对于输入法窗口的坐标
        val location = IntArray(2)
        anchorView.getLocationInWindow(location)

        // 计算弹窗显示位置
        val popupX = location[0] - ConvertUtils.dp2px(5f)
        val popupY = location[1] - ConvertUtils.dp2px(5f)

        popupWindow?.showAtLocation(
            anchorView,
            Gravity.NO_GRAVITY,
            popupX,
            popupY
        )
    }

    /**
     * 弹窗是否显示中
     */
    fun isShowing(): Boolean {
        return popupWindow?.isShowing == true
    }

    /**
     * 关闭弹窗
     */
    fun dismiss() {
        popupWindow?.dismiss()
    }
}