package cn.muchinfo.rma.view.autoWidget

import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.StateListDrawable

import android.text.TextUtils
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.PopupWindow
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import cn.muchinfo.rma.R
import com.blankj.utilcode.util.ScreenUtils
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButtonDrawable

import org.jetbrains.anko.*

class ListPopWindow private constructor() {

    private lateinit var builder: Builder

    internal var popX: Int = 0
    internal var popY: Int = 0

    fun show() {
        if (builder.bgShade) {
            (builder.attachView.context as? Activity)?.apply {
                // 变更背景颜色
                val attributes = window.attributes
                attributes.alpha = 0.5f
                window.attributes = attributes
                // 消失时变回正常
                builder.popupWindow.setOnDismissListener {
                    attributes.alpha = 1f
                    window.attributes = attributes
                    builder.popupWindow.setOnDismissListener(null)
                }
            }
        }
        builder.popupWindow.showAtLocation(builder.attachView.rootView, Gravity.START.or(Gravity.TOP), popX, popY)
    }

    class Builder(internal val attachView: View,backgroundColor : Int,textColor : String,isShowMark : Boolean = true) {
        enum class HorizontalPosition {
            LEFT,
            RIGHT,
            CENTER
        }

        internal val context: Context? = attachView.context
        internal val list: MutableList<IconParam> = arrayListOf()
        internal var bgShade: Boolean = false
        private var reversalOffY: Int = (ScreenUtils.getScreenHeight() * 0.8).toInt()
        internal var backgroundColor: Int = backgroundColor
        private var itemHeight: Int = autoSize(105)
        private var itemWidth: Int = wrapContent
        private var mDividerMarginLeft: Int = autoSize(40)
        private var mDividerMarginRight: Int = autoSize(40)
        private var mDividerHeight: Int = autoSize(1)
        private var mPopIconTintColor: Int = 0
        private var popOffY: Int = 0
        private var popOffX: Int = 0
        private var arrowContentOffX: Int = -autoSize(10)
        private var marginLeft: Int = autoSize(24)
        private var marginRight: Int = autoSize(24)
        private var cornerRadius: Int = autoSize(10)
        private var itemPaddingLeft: Int = autoSize(40)
        private var itemPaddingRight: Int = autoSize(40)
        private var iconSize: Int = autoSize(44)
        private var itemGravity: Int = Gravity.CENTER_VERTICAL
        internal var textSize: Int = 36
        internal var textColor: Int = Color.parseColor(textColor)
        private var textImageMargin: Int = autoSize(30)
        private var focus: Boolean = true
        private var isOutside: Boolean = true
        private var isShowMark : Boolean = isShowMark
        private var backgroundPressedColor: Int = Color.parseColor("#FFEEEEEE")
        private var popGravity: HorizontalPosition = HorizontalPosition.RIGHT
        private var mDividerColor: Int = Color.parseColor("#e5e5e5")
        internal lateinit var popupWindow: PopupWindow

        /**
         * 添加选项
         */
        fun addMenuItem(item: IconParam): Builder = this.apply { list.add(item) }

        fun build(): ListPopWindow {
            // 准备item的背景(带圆角的)
            val backgrounds = arrayOfNulls<Drawable>(list.size)
            for (i in backgrounds.indices) {
                val topRadius = if (i == 0) cornerRadius else 0
                val bottomRadius = if (i == backgrounds.size - 1) cornerRadius else 0
                val radii = floatArrayOf(topRadius.toFloat(), topRadius.toFloat(), topRadius.toFloat(), topRadius.toFloat(), bottomRadius.toFloat(), bottomRadius.toFloat(), bottomRadius.toFloat(), bottomRadius.toFloat())

                val normalDrawable = GradientDrawable()
                normalDrawable.shape = GradientDrawable.RECTANGLE
                normalDrawable.cornerRadii = radii
                normalDrawable.setColor(Color.TRANSPARENT)

                val pressedDrawable = GradientDrawable()
                pressedDrawable.shape = GradientDrawable.RECTANGLE
                pressedDrawable.cornerRadii = radii
                pressedDrawable.setColor(backgroundPressedColor)

                val stateListDrawable = StateListDrawable()
                stateListDrawable.addState(intArrayOf(android.R.attr.state_pressed), pressedDrawable)
                stateListDrawable.addState(intArrayOf(), normalDrawable)
                backgrounds[i] = stateListDrawable
            }

            // 获取目标view的位置和大小
            val targetLocation = IntArray(2) { 0 }
            attachView.getLocationInWindow(targetLocation)
            val attachViewWidth = if (attachView.width == 0) attachView.measuredWidth else attachView.width
            val attachViewHeight = if (attachView.height == 0) attachView.measuredHeight else attachView.height

            // 初始化箭头控件
            val arrowWidth = autoSize(30) + cornerRadius * 2
            val arrowHeight = autoSize(15)
            val arrowView = ImageView(attachView.context).apply {
                scaleType = ImageView.ScaleType.FIT_XY
                layoutParams = LinearLayout.LayoutParams(arrowWidth, arrowHeight)
                setPadding(cornerRadius, 0, cornerRadius, 0)
            }

            // 首先计算整个popWindow的高度
            val popHeight = itemHeight * list.size + arrowHeight

            // 判断pop是在目标的上方或者下方
            val isBelowTarget = targetLocation[1] + attachViewHeight + popHeight + popOffY < reversalOffY

            // 初始化整个pop的container
            val popView = _LinearLayout(attachView.context).apply {
                layoutParams = ViewGroup.LayoutParams(itemWidth, popHeight)
                orientation = LinearLayout.VERTICAL

                verticalLayout {
                    backgroundDrawable = QMUIRoundButtonDrawable().apply {
                        setIsRadiusAdjustBounds(false)
                        setColor(this@Builder.backgroundColor)
                        this.cornerRadius = this@Builder.cornerRadius.toFloat()
                    }

                    list.forEachIndexed { index, iconParam ->
                        linearLayout {
                            backgroundDrawable = backgrounds[index]
                            setPadding(itemPaddingLeft, 0, itemPaddingRight, 0)
                            gravity = itemGravity

                            // 设置图标
                            iconParam.iconImg?.let {
                                imageView {
                                    visibility = View.GONE
                                    if (mPopIconTintColor != 0)
                                        DrawableCompat.setTint(it, mPopIconTintColor)
                                    setImageDrawable(it)
                                    scaleType = ImageView.ScaleType.FIT_CENTER
                                }.lparams(iconSize, iconSize)
                                space().lparams(textImageMargin, 0)
                            }

                            // 设置文字
                            textView {
                                text = iconParam.title
                                textSizeAuto = this@Builder.textSize
                                textColor = this@Builder.textColor
                                lines = 1
                                ellipsize = TextUtils.TruncateAt.END
                            }.lparams(wrapContent, wrapContent)

                            onThrottleFirstClick {
                                popupWindow.dismiss()
                                iconParam.onItemClickListener?.invoke()
                            }
                        }.lparams(itemWidth, itemHeight)

                        if (mDividerHeight > 0 && index < list.size - 1) {
                            view { backgroundColor = mDividerColor }.lparams(matchParent, mDividerHeight) {
                                marginStart = mDividerMarginLeft
                                marginEnd = mDividerMarginRight
                            }
                        }
                    }

                }.lparams(wrapContent, wrapContent)
            }

            // 最后添加箭头控件
            val arrowLp = LinearLayout.LayoutParams(arrowWidth, arrowHeight)
            ImageView(context).apply {
                if (isShowMark){
                    visibility = View.VISIBLE
                }else{
                    visibility = View.GONE
                }
                //qmui_popup_arrow_up
                val arrowSrc = if (isBelowTarget) R.drawable.qmui_popup_arrow_down else R.drawable.qmui_popup_arrow_down
                val arrowDrawable = ContextCompat.getDrawable(context, arrowSrc)!!
                DrawableCompat.setTint(arrowDrawable, this@Builder.backgroundColor)
                setImageDrawable(arrowDrawable)
                setPadding(cornerRadius, 0, cornerRadius, 0)
                if (isBelowTarget) popView.addView(this, 0, arrowLp) else popView.addView(this, arrowLp)
            }

            popupWindow = PopupWindow(popView, itemWidth, popHeight)
            popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            popupWindow.contentView = popView
            popupWindow.isFocusable = focus
            popupWindow.isOutsideTouchable = isOutside
            popupWindow.animationStyle = android.R.style.Animation_Dialog

            val customPopWindow = ListPopWindow()
            customPopWindow.builder = this

            // 计算弹出框得位置
            // y轴的位置（相对于屏幕而言）
            if (isBelowTarget) {
                customPopWindow.popY = targetLocation[1] + attachView.height + popOffY
            } else {
                customPopWindow.popY = targetLocation[1] - popHeight - popOffY
            }

            // X轴的位置（相对于屏幕而言）
            val arrowCenterPositionX = targetLocation[0] + (attachViewWidth shr 1) + popOffX
            var popXTemp: Int
            popXTemp = when {
                popGravity === HorizontalPosition.LEFT -> arrowCenterPositionX - (arrowWidth shr 1)
                popGravity === HorizontalPosition.RIGHT -> arrowCenterPositionX + (arrowWidth shr 1) - itemWidth
                else -> arrowCenterPositionX - (itemWidth shr 1)
            }

            // 处理角标和列表的偏移
            popXTemp -= arrowContentOffX
            if (popXTemp > arrowCenterPositionX - (arrowWidth shr 1)) {
                popXTemp = arrowCenterPositionX - (arrowWidth shr 1)
            } else if (popXTemp + itemWidth < arrowCenterPositionX + (arrowWidth shr 1)) {
                popXTemp = arrowCenterPositionX + (arrowWidth shr 1) - itemWidth
            }

            // 处理靠边时得偏移
            if (popXTemp < marginLeft) {
                popXTemp = marginLeft
            } else if (popXTemp > ScreenUtils.getScreenWidth() - marginRight - itemWidth) {
                popXTemp = ScreenUtils.getScreenWidth() - marginRight - itemWidth
            }

            // 偏移箭头的位置
            arrowLp.leftMargin = arrowCenterPositionX - popXTemp - (arrowWidth shr 1)
            arrowView.layoutParams = arrowLp
            customPopWindow.popX = popXTemp
            return customPopWindow
        }
    }

    data class IconParam(
            var iconImg: Drawable? = null,
            var title: String? = null,
            var onItemClickListener: (() -> Unit)? = null
    )
}

