package com.adealink.weparty.room.micseat

import android.content.Context
import android.content.res.TypedArray
import android.util.AttributeSet
import androidx.annotation.CallSuper
import androidx.constraintlayout.widget.ConstraintLayout
import com.adealink.weparty.module.room.data.MIC_OFF_INDEX
import com.adealink.weparty.module.room.data.MicIndex
import com.adealink.weparty.room.R
import com.adealink.weparty.room.micseat.decor.BaseDecorView
import com.adealink.weparty.room.micseat.decor.IDecorApi
import io.trtc.tuikit.atomicxcore.api.live.SeatInfo
import java.util.LinkedList

abstract class BaseSeatView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : ConstraintLayout(context, attrs, defStyleAttr) {

    val dynamicLayers: DecorDynamicLayers

    var scale = 1f
    abstract val baseSize: Int
    var micSeatInfo: SeatInfo? = null //当前麦位数据
    var micIndex: MicIndex = MIC_OFF_INDEX

    private val decorApis = hashMapOf<String, MutableSet<IDecorApi>>()

    init {
        val typedArray: TypedArray = context.obtainStyledAttributes(
            attrs,
            R.styleable.BaseSeatView
        )
        scale = typedArray.getFloat(R.styleable.BaseSeatView_scale, 1.0f)
        initAttrs(typedArray)
        typedArray.recycle()
        dynamicLayers = initDecorLayers()
        initViews()
    }

    open fun initAttrs(typedArray: TypedArray) {
    }

    abstract fun initDecorLayers(): DecorDynamicLayers

    abstract fun initViews()

    fun <T : IDecorApi> getDecorApi(decorApiClazz: Class<T>): Set<T>? {
        return decorApis[decorApiClazz.name] as? Set<T>?
    }

    private fun addDecorApi(decorApiName: String, decorApi: IDecorApi) {
        var decorApiSet = decorApis[decorApiName]
        if (decorApiSet == null) {
            decorApiSet = hashSetOf()
            decorApis[decorApiName] = decorApiSet
        }
        decorApiSet.add(decorApi)
    }

    private fun removeDecorApi(decorApiName: String, decorApi: IDecorApi) {
        decorApis[decorApiName]?.remove(decorApi)
    }

    fun addDecorView(decorView: BaseDecorView<*>) {
        //动态层级添加映射
        dynamicLayers.addDecor(decorView)
        //添加Decor方法映射
        val interfaceSet = getAllInterfaces(decorView::class.java).toTypedArray()
        interfaceSet.filter {
            it.interfaces.contains(IDecorApi::class.java)
        }.forEach {
            addDecorApi(it.name, decorView)
        }

        if (decorView.autoAttach && !decorView.isAttached()) {
            decorView.attach()
        }
    }

    private fun getAllInterfaces(clazz: Class<*>): Set<Class<*>> {
        val interfaces = mutableSetOf<Class<*>>()
        val queue = LinkedList<Class<*>>()
        queue.add(clazz)

        while (!queue.isEmpty()) {
            val currentClass = queue.poll()
            interfaces.addAll(currentClass.interfaces) // 添加当前类直接实现的接口

            // 将父类加入队列（如果有的话），以便后续处理
            val superClass = currentClass.superclass
            if (superClass != null && superClass != Object::class.java) {
                queue.add(superClass)
            }
        }

        // 移除重复的接口（如果有的话）
        return interfaces.toSet()
    }


    /**
     * 麦位状态变化
     */
    abstract fun onMicSeatStatusChanged(oldSeatInfo: SeatInfo?, newSeatInfo: SeatInfo?)

    /**
     * 麦位成员变化
     */
    abstract fun onMicSeatMemberChanged(oldSeatInfo: SeatInfo?, newSeatInfo: SeatInfo)


    /**
     * 房间成员下麦
     */
    abstract fun onMemberOffMicSeat(oldSeatInfo: SeatInfo?, offSeatInfo: SeatInfo?)

    /**
     * 房间成员上麦
     */
    abstract fun onMemberOnMicSeat(oldSeatInfo: SeatInfo?, onSeatInfo: SeatInfo)

    /**
     * 房间成员持续停留在麦位上
     */
    abstract fun onMemberStayMicSeat(seatInfo: SeatInfo)

    /**
     * 重置麦位状态,清除状态
     */
    @CallSuper
    open fun resetMicSeat() {
        this.micSeatInfo = null
    }

    companion object {
        private const val TAG = "BaseSeatView"
    }

}