package com.atmob.keyboard_android.ui.popup

import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
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.HelpMode
import com.atmob.keyboard_android.ext.click
import com.atmob.keyboard_android.model.ModeItem
import com.atmob.keyboard_android.ui.popup.item.ModeListItemViewBinder
import com.blankj.utilcode.util.ConvertUtils
import me.drakeet.multitype.Items
import me.drakeet.multitype.MultiTypeAdapter

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

    /**
     * 模式切换监听器
     */
    interface OnModeSelectedListener {
        fun onModeSelected(helpMode: HelpMode)
    }

    /**
     * 显示弹窗
     *
     * @param anchorView 锚点View
     * @param currentHelpMode 当前选中的模式
     */
    @SuppressLint("InflateParams", "NotifyDataSetChanged")
    fun show(anchorView: View, currentHelpMode: HelpMode, listener: OnModeSelectedListener) {
        if (isShowing()) {
            return
        }

        val context = anchorView.context

        if (mPopupWindow == 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.click {
                dismiss()
            }

            val listItems = Items().apply {
                addAll(HelpMode.getAll().mapIndexed { index, item ->
                    ModeItem(item, selected = item.modeName == currentHelpMode.modeName)
                })
            }

            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.helpMode.modeName
                        // 通知外部更新模式
                        listener.onModeSelected(targetItem.helpMode)

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

            contentView.setOnTouchListener { _, event ->
                // 拦截所有触摸事件，不传递给底层
                true
            }

            mPopupWindow = 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
                // 透明背景
                setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            }
        }

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

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

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

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

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