package com.remax.visualnovel.widget.custom

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable
import android.text.TextUtils
import android.util.AttributeSet
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat
import com.remax.visualnovel.R
import com.remax.visualnovel.extension.dpToPx
import com.remax.visualnovel.extension.spToPx
import kotlin.math.max
import kotlin.math.min
import androidx.core.content.withStyledAttributes
import kotlin.collections.mutableListOf

class TagFlowLayout2 @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {

    // 属性变量
    private var horizontalSpacing = 10f.dpToPx()
    private var verticalSpacing = 8f.dpToPx()
    private var textSize = 12f.spToPx()
    private var textColor = context.resources.getColor(R.color.tag_text_color)
    private var textColorSelected = context.resources.getColor(R.color.white)
    private var tagBackground: Drawable? = null
    private var maxLinesWhileShrink = 1
    private var eachLineMaxTagNum = 2
    private var expandIndicator: Drawable? = null
    private var shrinkIndicator: Drawable? = null


    // 状态变量
    private var isExpanded = false
    private var actualLineCount = 0
    private var showExpandButton = false
    private var eachLineAvailableWidth = 0

    // 数据
    private val tagItems = mutableListOf<AbsTagBean>()
    private val tagViews = mutableListOf<TextView>()
    private lateinit var expandIcon: ImageView

    // 监听器
    private var onTagClickListener: ((AbsTagBean) -> Unit)? = null
    private var onExpandStateChangeListener: ((Boolean) -> Unit)? = null

    init {
        initAttributes(attrs)
        initExpandButton()
    }

    private fun initAttributes(attrs: AttributeSet?) {
        context.withStyledAttributes(attrs, R.styleable.TagFlowLayout2) {

            horizontalSpacing = getDimension(
                R.styleable.TagFlowLayout2_tag_horizontal_spacing, horizontalSpacing
            )
            verticalSpacing = getDimension(
                R.styleable.TagFlowLayout2_tag_vertical_spacing, verticalSpacing
            )
            textSize = getDimension(
                R.styleable.TagFlowLayout2_tag_text_size, textSize
            )
            textColor = getColor(
                R.styleable.TagFlowLayout2_tag_text_color, textColor
            )
            tagBackground = getDrawable(R.styleable.TagFlowLayout2_tag_background)
            maxLinesWhileShrink = getInt(R.styleable.TagFlowLayout2_tag_max_lines, 1)
            eachLineMaxTagNum = getInt(R.styleable.TagFlowLayout2_tag_each_line_max_num, 2)

            expandIndicator = getDrawable(R.styleable.TagFlowLayout2_tag_expand_drawable)
            shrinkIndicator = getDrawable(R.styleable.TagFlowLayout2_tag_shrink_drawable)
        }


        if (tagBackground == null) {
            tagBackground = createDefaultBackground()
        }
        if (expandIndicator == null) {
            expandIndicator = ContextCompat.getDrawable(context, R.mipmap.tag_flow_expand)
        }
        if (shrinkIndicator == null) {
            shrinkIndicator = ContextCompat.getDrawable(context, R.mipmap.tag_flow_shrink)
        }
    }

    private fun createDefaultBackground(): Drawable {
        val gradientDrawable = GradientDrawable()
        gradientDrawable.cornerRadius = 16f.dpToPx()
        gradientDrawable.setColor(Color.parseColor("#8A8A8E"))
        return gradientDrawable
    }

    private fun initExpandButton() {
        expandIcon = AppCompatImageView(context).apply {
            textSize = 12f
            setPadding(5.dpToPx(), 5.dpToPx(), 5.dpToPx(), 5.dpToPx())
            bringToFront()
            setOnClickListener {
                toggleExpandState()
            }
        }
        addView(expandIcon)

        updateExpandButton()
    }


    fun setTagDataList(tags: List<AbsTagBean>) {
        tagItems.clear()
        tagViews.forEach { removeView(it) }
        tagViews.clear()

        tagItems.addAll(tags)
        tags.forEach { tag ->
            val textView = createTagView(tag)
            tagViews.add(textView)
            addView(textView)
        }

        requestLayout()
    }

    private fun createTagView(tag: AbsTagBean): TextView {
        return TextView(context).apply {
            text = tag.showStr
            setTextColor(textColor)
            textSize = textSize / resources.displayMetrics.scaledDensity
            setPadding(10.dpToPx(), 7.dpToPx(), 10.dpToPx(), 7.dpToPx())
            setBackgroundResource(R.drawable.tag_flow_item_bg)
            isSingleLine = true
            ellipsize = TextUtils.TruncateAt.END
            maxLines = 1
            includeFontPadding = false

            setOnClickListener {
                onTagClickListener?.invoke(tag)
                with(tag) {
                    isSelected = !isSelected
                }

                setTextColor(if (tag.isSelected) textColorSelected else textColor)
                setBackgroundResource(if (tag.isSelected) R.drawable.tag_flow_item_bg_selected else R.drawable.tag_flow_item_bg)
                requestLayout()
            }
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val width = MeasureSpec.getSize(widthMeasureSpec)
        eachLineAvailableWidth = width - paddingLeft - paddingRight

        val oneTagMaxWidth = (eachLineAvailableWidth - (eachLineMaxTagNum-1) * horizontalSpacing)  / eachLineMaxTagNum
        var totalNeedHeight = 0
        if (tagViews.isEmpty()) {
            setMeasuredDimension(width, totalNeedHeight)
            return
        }

        // 为所有标签应用最大宽度限制
        tagViews.forEach { subView ->
            val maxWidthSpec = MeasureSpec.makeMeasureSpec(oneTagMaxWidth.toInt(), MeasureSpec.AT_MOST)
            val heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
            subView.measure(maxWidthSpec, heightSpec)
        }


        var curLineTotalWidth = 0
        var curLineTotalHeight = 0
        var lineIndex = 0
        val maxDisplayLines = if (isExpanded) Int.MAX_VALUE else maxLinesWhileShrink

        tagViews.forEach { view ->
            val childWidth = view.measuredWidth
            val childHeight = view.measuredHeight

            // 检查是否需要换行（考虑水平间距）
            val curLineNeedTotalWidth: Int = if (curLineTotalWidth == 0) childWidth
                                else curLineTotalWidth + horizontalSpacing.toInt() + childWidth

            if (curLineNeedTotalWidth > eachLineAvailableWidth) { // 换行处理
                lineIndex++
                if (lineIndex >= maxDisplayLines) {
                    return@forEach
                }

                totalNeedHeight += curLineTotalHeight + (if (lineIndex >= 1) verticalSpacing.toInt() else 0)
                curLineTotalWidth = childWidth
                curLineTotalHeight = childHeight
            } else {
                curLineTotalWidth = curLineNeedTotalWidth
                curLineTotalHeight = max(curLineTotalHeight, childHeight)
            }
        }

        // 添加最后一行高度
        if (tagViews.isNotEmpty()) {
            totalNeedHeight += curLineTotalHeight
        }

        // 添加padding
        totalNeedHeight += paddingTop + paddingBottom

        actualLineCount = lineIndex + 1
        showExpandButton = actualLineCount > maxLinesWhileShrink && !isExpanded

        // 测量展开按钮
        if (showExpandButton) {
            val buttonWidthSpec = MeasureSpec.makeMeasureSpec(eachLineAvailableWidth, MeasureSpec.AT_MOST)
            val buttonHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
            expandIcon.measure(buttonWidthSpec, buttonHeightSpec)
        }

        setMeasuredDimension(width, totalNeedHeight)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        if (tagViews.isEmpty()) return

        val width = r - l
        val maxTagWidth = (eachLineAvailableWidth * eachLineMaxTagNum).toInt()

        var currentLeft = paddingLeft
        var currentTop = paddingTop
        var currentLineHeight = 0
        var lineCount = 0
        val maxDisplayLines = if (isExpanded) Int.MAX_VALUE else maxLinesWhileShrink

        // 布局可见的标签
        for (i in tagViews.indices) {
            val view = tagViews[i]
            val childWidth = min(view.measuredWidth, maxTagWidth)
            val childHeight = view.measuredHeight

            // 检查是否需要换行
            if (currentLeft + childWidth > width - paddingRight) {
                lineCount++
                if (lineCount >= maxDisplayLines) {
                    view.visibility = GONE
                    continue
                }

                currentLeft = paddingLeft
                currentTop += currentLineHeight + verticalSpacing.toInt()
                currentLineHeight = 0
            }

            view.visibility = VISIBLE
            view.layout(currentLeft, currentTop, currentLeft + childWidth, currentTop + childHeight)

            currentLeft += childWidth + horizontalSpacing.toInt()
            currentLineHeight = max(currentLineHeight, childHeight)
        }

        // 布局展开按钮
        layoutExpandButton(width, currentTop, currentLineHeight)
    }

    private fun layoutExpandButton(parentWidth: Int, currentTop: Int, currentLineHeight: Int) {
        if (showExpandButton) {
            expandIcon.visibility = VISIBLE
            val buttonWidth = expandIcon.measuredWidth
            val buttonHeight = expandIcon.measuredHeight

            // 计算按钮位置（在当前行右侧）
            val buttonLeft = parentWidth - paddingRight - buttonWidth
            val buttonTop = currentTop + (currentLineHeight - buttonHeight) / 2

            expandIcon.layout(
                buttonLeft,
                buttonTop,
                buttonLeft + buttonWidth,
                buttonTop + buttonHeight
            )
        } else {
            expandIcon.visibility = GONE
        }
    }

    private fun toggleExpandState() {
        isExpanded = !isExpanded
        updateExpandButton()
        requestLayout()
        onExpandStateChangeListener?.invoke(isExpanded)
    }

    private fun updateExpandButton() {
        val indicator = if (isExpanded) shrinkIndicator else expandIndicator
        expandIcon.setImageDrawable(indicator)
    }

    fun setOnTagClickListener(listener: (AbsTagBean) -> Unit) {
        onTagClickListener = listener
    }

    fun setOnExpandStateChangeListener(listener: (Boolean) -> Unit) {
        onExpandStateChangeListener = listener
    }

    fun expand() {
        if (!isExpanded) {
            toggleExpandState()
        }
    }

    fun shrink() {
        if (isExpanded) {
            toggleExpandState()
        }
    }

    fun isExpanded(): Boolean = isExpanded

    fun setMaxTagsNumEachLine(maxTagNumForEachLine: Int) {
        require(maxTagNumForEachLine >= 1 && maxTagNumForEachLine <= 10) { "tags numb in one line must be between 1 and 8" }
        eachLineMaxTagNum = maxTagNumForEachLine
        requestLayout()
    }

    fun getSelectedTagList() : List<AbsTagBean> {
        return tagItems.filter { it.isSelected }
    }


}