package com.adealink.weparty.commonui.text

import android.content.Context
import android.text.Editable
import android.text.TextWatcher
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
import kotlin.math.min

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

    private var ellipsisListeners = mutableListOf<(Boolean) -> Unit>()
    private var isEllipsized = false

    private var checkEllipsized = false

    init {
        // 监听文本变化
        addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
            override fun afterTextChanged(s: Editable?) {
                doCheckEllipsis()
            }
        })
    }

    fun addEllipsisListener(listener: (Boolean) -> Unit) {
        ellipsisListeners.add(listener)
    }

    fun removeEllipsisListener(listener: (Boolean) -> Unit) {
        ellipsisListeners.remove(listener)
    }

    fun clearEllipsisListener() {
        ellipsisListeners.clear()
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        if (!checkEllipsized) {
            return
        }
        doCheckEllipsis()
    }

    fun checkEllipsis() {
        checkEllipsized = true
        doCheckEllipsis()
    }

    private fun doCheckEllipsis() {
        post {
            if (!checkEllipsized) {
                return@post
            }
            checkEllipsized = false
            val newState = calculateIsEllipsized()
            if (newState != isEllipsized) {
                isEllipsized = newState
                ellipsisListeners.forEach { it.invoke(isEllipsized) }
            }
        }
    }

    private fun calculateIsEllipsized(): Boolean {
        val maxLines = maxLines
        if (maxLines <= 0) return false
        val layout = layout ?: return false

        // 检查行数是否超过
        val lineCount = layout.lineCount
        val textLength = text.length
        if (lineCount > maxLines) return true

        // 检查省略号
        val checkLine = min(lineCount, maxLines)
        for (i in 0 until checkLine) {
            val lineEnd = layout.getLineEnd(i)
            if (lineEnd < textLength) {
                return true
            }
        }
        return false
    }

    /**
     * 获取可见文本（未被省略的部分）
     */
    fun getVisibleText(): CharSequence {
        return layout?.let { layout ->
            val maxLine = min(maxLines, layout.lineCount)
            if (maxLine > 0) {
                val lastLineEnd = layout.getLineEnd(maxLine - 1)
                return@let text.subSequence(0, lastLineEnd)
            }
            text
        } ?: text
    }

    /**
     * 获取被省略的文本
     */
    fun getEllipsizedText(): CharSequence {
        return layout?.let { layout ->
            val maxLine = min(maxLines, layout.lineCount)
            if (maxLine > 0) {
                val lastLineEnd = layout.getLineEnd(maxLine - 1)
                if (lastLineEnd < text.length) {
                    return@let text.subSequence(lastLineEnd, text.length)
                }
            }
            ""
        } ?: ""
    }
}