package com.adealink.weparty.room.micseat.defaults

import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.annotation.CallSuper
import com.adealink.frame.log.Log
import com.adealink.frame.room.data.TAG_ROOM_SEAT
import com.adealink.frame.util.DisplayUtil
import com.adealink.weparty.module.room.constant.SEAT_AVATAR_SIZE_RATIO_TO_SCREEN_WIDTH
import com.adealink.weparty.module.room.constant.SEAT_MAX_AVATAR_SIZE
import com.adealink.weparty.module.room.constant.SEAT_MIN_AVATAR_SIZE
import com.adealink.weparty.module.room.constant.SEAT_MIN_HEIGHT_RATIO
import com.adealink.weparty.module.room.data.MicIndex
import com.adealink.weparty.module.room.data.MicSeatStatus
import com.adealink.weparty.module.room.data.isSeatEmpty
import com.adealink.weparty.module.room.data.micStatus
import com.adealink.weparty.module.room.data.micUid
import com.adealink.weparty.module.room.listener.IMemberInfoListener
import com.adealink.weparty.room.micseat.BaseSeatView
import com.adealink.weparty.room.micseat.ISeatApi
import com.adealink.weparty.room.micseat.decor.IAvatarDecorApi
import com.adealink.weparty.room.micseat.decor.IAvatarFrameDecorApi
import com.adealink.weparty.room.micseat.decor.ILockDecorApi
import com.adealink.weparty.room.micseat.decor.IMicIndexDecorApi
import com.adealink.weparty.room.micseat.decor.IMuteDecorApi
import com.adealink.weparty.room.micseat.decor.INameDecorApi
import com.adealink.weparty.room.micseat.decor.ISpeakingRippleDecorApi
import io.trtc.tuikit.atomicxcore.api.live.SeatInfo

/**
 * 所有视图View的基类
 */
abstract class BaseDefaultSeatView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : BaseSeatView(context, attrs, defStyleAttr),
    ISeatApi {

    //麦位头像默认大小是屏幕宽度 / 375 * 55，最大是80dp，最小是45dp
    override val baseSize = ((DisplayUtil.getScreenWidth() * SEAT_AVATAR_SIZE_RATIO_TO_SCREEN_WIDTH)
        .coerceAtLeast(SEAT_MIN_AVATAR_SIZE * scale)
        .coerceAtMost(SEAT_MAX_AVATAR_SIZE * scale) * scale).toInt()

    var memberInfoListener: IMemberInfoListener? = null
    private var memberInfoGetFailed = false //成员信息获取失败

    init {
        minHeight = (baseSize * SEAT_MIN_HEIGHT_RATIO).toInt()
    }

    /**
     * 处理麦位信息
     * @return 返回是否麦位变化
     */
    open fun handleMicSeatInfo(
        micSeatInfo: SeatInfo?,
        onMicOn: ((micSeatInfo: SeatInfo) -> Unit)? = null, //上麦
        onMicOff: (() -> Unit)? = null, //上麦
    ) {
        Log.d(
            TAG_ROOM_SEAT,
            "handleMicSeatInfo, index:${micIndex.index}, newMicSeatInfo:$micSeatInfo, oldMicSeatInfo:${this.micSeatInfo}"
        )
        val lastMicSeatInfo = this.micSeatInfo
        this.micSeatInfo = micSeatInfo

        if (lastMicSeatInfo?.micStatus() != micSeatInfo?.micStatus()) {
            onMicSeatStatusChanged(lastMicSeatInfo, micSeatInfo)
        }

        if (micSeatInfo == null || micSeatInfo.isSeatEmpty()) {
            onMemberOffMicSeat(lastMicSeatInfo, micSeatInfo)
        } else {
            if (lastMicSeatInfo?.micUid() != micSeatInfo.micUid()) {
                onMicSeatMemberChanged(lastMicSeatInfo, micSeatInfo)
            }
            if (!micSeatInfo.isSeatEmpty()) {
                onMemberStayMicSeat(micSeatInfo)
            }
        }

        //判断上下麦结果
        if ((lastMicSeatInfo == null || lastMicSeatInfo.isSeatEmpty()) &&
            (micSeatInfo != null && !micSeatInfo.isSeatEmpty())
        ) {
            //上麦
            onMicOn?.invoke(micSeatInfo)

        } else if ((lastMicSeatInfo != null && !lastMicSeatInfo.isSeatEmpty()) &&
            (micSeatInfo == null || micSeatInfo.isSeatEmpty())
        ) {
            //下麦
            onMicOff?.invoke()

        } else if (micSeatInfo != null && lastMicSeatInfo?.micUid() != micSeatInfo.micUid()) {
            //麦位换人(即另一个人上麦)
            onMicOn?.invoke(micSeatInfo)
        }
    }

    /**
     * 麦位状态变化
     */
    @CallSuper
    override fun onMicSeatStatusChanged(oldSeatInfo: SeatInfo?, newSeatInfo: SeatInfo?) {
        showMute(
            newSeatInfo?.micStatus() == MicSeatStatus.MUTE,
        )
        if (newSeatInfo != null && newSeatInfo.isSeatEmpty()) {
            showLock(newSeatInfo.micStatus() == MicSeatStatus.LOCK)
        }
    }

    /**
     * 麦位成员变化
     */
    @CallSuper
    override fun onMicSeatMemberChanged(oldSeatInfo: SeatInfo?, newSeatInfo: SeatInfo) {
        memberInfoGetFailed = false
        if (newSeatInfo.isSeatEmpty()) {
            onMemberOffMicSeat(oldSeatInfo, newSeatInfo)
        } else {
            onMemberOnMicSeat(oldSeatInfo, newSeatInfo)
        }
    }


    /**
     * 房间成员下麦
     */
    @CallSuper
    override fun onMemberOffMicSeat(oldSeatInfo: SeatInfo?, offSeatInfo: SeatInfo?) {
        Log.d(TAG_ROOM_SEAT, "onMemberOffMicSeat(index:${micIndex.index})")
        //原来就是空麦位,就不刷新这个麦位状态了
//        if (((oldSeatInfo == null || oldSeatInfo.isSeatEmpty()) && (offSeatInfo == null || offSeatInfo.isSeatEmpty()))) {
//            //只更新基础麦位基础信息
//            showMicIndex(micIndex)
//            showLock(offSeatInfo?.micStatus() == MicSeatStatus.LOCK)
//            return
//        }
        showAvatar("")
        showAvatarFrame(false)
        showMicIndex(micIndex)
        showLock(offSeatInfo?.micStatus() == MicSeatStatus.LOCK)
        showSpeaking(false)
    }

    /**
     * 重置麦位状态,清除状态
     */
    @CallSuper
    override fun resetMicSeat() {
        super.resetMicSeat()
        Log.d(TAG_ROOM_SEAT, "resetMicSeat(index:${micIndex.index})")
        this.micSeatInfo = null
        showAvatarFrame(false)
        showMicIndex(micIndex)
        showLock(false)
        showSpeaking(false)
    }

    /**
     * 房间成员上麦
     */
    @CallSuper
    override fun onMemberOnMicSeat(oldSeatInfo: SeatInfo?, onSeatInfo: SeatInfo) {
        Log.d(TAG_ROOM_SEAT, "onMemberOnMicSeat(index:${micIndex.index}), $onSeatInfo")
        showAvatar(onSeatInfo.userInfo.avatarURL)
        showAvatarFrame(true)
        showMemberInfo(onSeatInfo)
    }

    /**
     * 房间成员持续停留在麦位上
     */
    @CallSuper
    override fun onMemberStayMicSeat(seatInfo: SeatInfo) {
        if (memberInfoGetFailed) {
            showMemberInfo(seatInfo)
        }
    }

    private fun showMemberInfo(seatInfo: SeatInfo) {
        val uid = seatInfo.micUid() ?: return
        memberInfoListener?.getMemberInfo(uid) {
            if (this.micSeatInfo?.micUid() == uid) {
                if (it == null) {
                    memberInfoGetFailed = true
                    showAvatar(seatInfo.userInfo.avatarURL)
                    showName(seatInfo.userInfo.userName, seatInfo.userInfo.userID)
                } else {
                    memberInfoGetFailed = false
                    showAvatar(it.avatar ?: "")
                    showName(it.nickName ?: "", it.uid)
                }
            }
        }
    }

    /**
     * DefaultSeatApi
     */
    override fun showAvatar(url: String) {
        getDecorApi(IAvatarDecorApi::class.java)?.onEach {
            it.showAvatar(url)
        }
    }

    override fun showAvatarFrame(show: Boolean) {
        getDecorApi(IAvatarFrameDecorApi::class.java)?.onEach {
            it.showAvatarFrame(show)
        }
    }

    override fun getAvatarView(): View? {
        getDecorApi(IAvatarDecorApi::class.java)?.onEach {
            val view = it.getAvatarView()
            if (view != null) {
                return view
            }
        }
        return null
    }

    override fun showName(name: String, uid: String) {
        getDecorApi(INameDecorApi::class.java)?.onEach {
            it.showName(name, uid)
        }
    }

    override fun showMicIndex(micIndex: MicIndex) {
        getDecorApi(IMicIndexDecorApi::class.java)?.onEach {
            it.showMicIndex(micIndex)
        }
    }

    override fun showLock(lock: Boolean) {
        getDecorApi(ILockDecorApi::class.java)?.onEach {
            it.showLock(lock)
        }
    }

    override fun showMute(mute: Boolean) {
        getDecorApi(IMuteDecorApi::class.java)?.onEach {
            it.showMute(mute)
        }
    }

    override fun showSpeaking(speaking: Boolean) {
        getDecorApi(ISpeakingRippleDecorApi::class.java)?.onEach {
            it.showSpeaking(speaking)
        }
    }

    override fun setAvatarEmptyResId(id: Int) {
        getDecorApi(IAvatarDecorApi::class.java)?.onEach {
            it.setAvatarEmptyResId(id)
        }
    }

    override fun setAvatarLockResId(id: Int) {
        getDecorApi(IAvatarDecorApi::class.java)?.onEach {
            it.setAvatarLockResId(id)
        }
    }

    override fun resetAvatar() {
        getDecorApi(IAvatarDecorApi::class.java)?.onEach {
            it.resetAvatar()
        }
    }
}