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.TextView
import androidx.core.content.ContextCompat
import com.remax.visualnovel.R
import kotlin.math.max
import kotlin.math.min

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

    // 属性变量
    private var horizontalSpacing = 20f.dpToPx()
    private var verticalSpacing = 12f.dpToPx()
    private var textSize = 14f.spToPx()
    private var textColor = Color.WHITE
    private var tagBackground: Drawable? = null
    private var maxLines = Int.MAX_VALUE
    private var expandIndicator: Drawable? = null
    private var collapseIndicator: Drawable? = null
    private var eachLineMaxTagNum = 2 //一行最大标签宽度数

    // 状态变量
    private var isExpanded = false
    private var actualLineCount = 0
    private var showExpandButton = false
    private var eachLineAvailableWidth = 0 // 可用宽度

    // 数据
    private val tagItems = mutableListOf<TagItem>()
    private val tagViews = mutableListOf<TextView>()
    private lateinit var expandButton: TextView

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

    init {
        initAttributes(attrs)
        initExpandButton()
    }

    private fun initAttributes(attrs: AttributeSet?) {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.TagFlowLayout2)

        horizontalSpacing = typedArray.getDimension(
            R.styleable.TagFlowLayout2_tag_horizontal_spacing, horizontalSpacing
        )
        verticalSpacing = typedArray.getDimension(
            R.styleable.TagFlowLayout2_tag_vertical_spacing, verticalSpacing
        )
        textSize = typedArray.getDimension(
            R.styleable.TagFlowLayout2_tag_text_size, textSize
        )
        textColor = typedArray.getColor(
            R.styleable.TagFlowLayout2_tag_text_color, textColor
        )
        tagBackground = typedArray.getDrawable(R.styleable.TagFlowLayout2_tag_background)
        maxLines = typedArray.getInt(R.styleable.TagFlowLayout2_tag_max_lines, Int.MAX_VALUE)
        expandIndicator = typedArray.getDrawable(R.styleable.TagFlowLayout2_expand_indicator_drawable)
        collapseIndicator = typedArray.getDrawable(R.styleable.TagFlowLayout2_collapse_indicator_drawable)
        eachLineMaxTagNum = typedArray.getInt(R.styleable.TagFlowLayout2_each_line_max_num, 2)
        typedArray.recycle()


        if (tagBackground == null) {
            tagBackground = createDefaultBackground()
        }
        if (expandIndicator == null) {
            expandIndicator = ContextCompat.getDrawable(context, R.mipmap.tag_flow_expand)
        }
        if (collapseIndicator == null) {
            collapseIndicator = 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() {
        expandButton = TextView(context).apply {
            text = "展开"
            setCompoundDrawablesWithIntrinsicBounds(null, null, expandIndicator, null)
            compoundDrawablePadding = 4.dpToPx()
            setTextColor(Color.parseColor("#8A8A8E"))
            textSize = 12f
            setPadding(12.dpToPx(), 6.dpToPx(), 8.dpToPx(), 6.dpToPx())
            background = createExpandButtonBackground()

            setOnClickListener {
                toggleExpandState()
            }
        }
        addView(expandButton)
    }

    private fun createExpandButtonBackground(): Drawable {
        val gradientDrawable = GradientDrawable()
        gradientDrawable.cornerRadius = 16f.dpToPx()
        gradientDrawable.setColor(Color.parseColor("#E5E5EA"))
        gradientDrawable.setStroke(1.dpToPx(), Color.parseColor("#C6C6C8"))
        return gradientDrawable
    }

    // 设置标签数据
    fun setTags(tags: List<TagItem>) {
        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: TagItem): TextView {
        return TextView(context).apply {
            text = tag.text
            setTextColor(textColor)
            textSize = textSize / resources.displayMetrics.scaledDensity
            setPadding(16.dpToPx(), 8.dpToPx(), 16.dpToPx(), 8.dpToPx())
            setBackgroundResource(R.drawable.tag_flow_item_bg)
            isSingleLine = true
            ellipsize = TextUtils.TruncateAt.END
            maxLines = 1
            includeFontPadding = false

            setOnClickListener {
                onTagClickListener?.invoke(tag)
            }
        }
    }

    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 lineCount = 0
        val maxDisplayLines = if (isExpanded) Int.MAX_VALUE else maxLines

        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) {
                // 换行处理
                lineCount++
                if (lineCount >= maxDisplayLines) {
                    return@forEach
                }

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

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

        // 添加padding
        totalNeedHeight += paddingTop + paddingBottom

        actualLineCount = lineCount + 1
        showExpandButton = actualLineCount > maxLines && !isExpanded

        // 测量展开按钮
        if (showExpandButton) {
            val buttonWidthSpec = MeasureSpec.makeMeasureSpec(eachLineAvailableWidth, MeasureSpec.AT_MOST)
            val buttonHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
            expandButton.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 maxLines

        // 布局可见的标签
        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) {
            expandButton.visibility = VISIBLE
            val buttonWidth = expandButton.measuredWidth
            val buttonHeight = expandButton.measuredHeight

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

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

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

    private fun updateExpandButton() {
        val indicator = if (isExpanded) collapseIndicator else expandIndicator
        expandButton.setCompoundDrawablesWithIntrinsicBounds(null, null, indicator, null)
        expandButton.text = if (isExpanded) "收起" else "展开"
    }

    // 公共方法
    fun setOnTagClickListener(listener: (TagItem) -> Unit) {
        onTagClickListener = listener
    }

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

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

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

    fun isExpanded(): Boolean = isExpanded

    // 设置最大标签数
    fun setMaxTagsNumEachLine(maxTagNumForEachLine: Int) {
        require(maxTagNumForEachLine >= 1 && maxTagNumForEachLine <= 10) { "Ratio must be between 1 and 10" }
        eachLineMaxTagNum = maxTagNumForEachLine
        requestLayout()
    }

    // 扩展函数
    private fun Float.dpToPx(): Float = this * resources.displayMetrics.density
    private fun Int.dpToPx(): Int = (this * resources.displayMetrics.density).toInt()
    private fun Float.spToPx(): Float = this * resources.displayMetrics.scaledDensity
}