package com.ez.ertc.call.ui

import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.preference.PreferenceManager
import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.*
import androidx.recyclerview.widget.RecyclerView
import com.ez.baselib.utils.LogUtil
import com.ez.basertc.RTCConstant
import com.ez.ertc.ConstantApp
import com.ez.ertc.MyApp
import com.ez.ertc.R
import com.ez.ertc.call.bean.DeviceState
import com.ez.ertc.utils.ViewUtil
import com.ez.ertc.call.bean.UserStatusData
import com.ez.ertc.call.ui.widget.EzmTextureView
import java.util.*
import kotlin.math.sqrt

class GridVideoViewContainerAdapter(
    activity: Activity,
    localUserId: String,
    userTextureViewList: HashMap<String, EzmTextureView?>,
    userStatusList: ArrayList<UserStatusData>
): RecyclerView.Adapter<RecyclerView.ViewHolder>(){

    val networkQualityDesc = arrayOf("未知", "非常好", "比较好", "一般", "较差", "很差", "不可用", "无法检测", "检测中")
    val decodeEngintDesc = arrayOf("失败", "未知", "软解", "硬解")

    protected val mInflater: LayoutInflater
    protected val mContext: Context
    protected var userStatusList: ArrayList<UserStatusData>
    protected var userTextureViewList: HashMap<String, EzmTextureView?>
    protected var mLocalUid: String
    protected var mItemWidth = 0
    protected var mItemHeight = 0
    private var mDefaultChildItem = 0

    init {
        mInflater = activity.layoutInflater
        mContext = activity.applicationContext
        mLocalUid = localUserId
        this.userStatusList = userStatusList
        this.userTextureViewList = userTextureViewList
        customizedInit(userTextureViewList)
    }

    //初始化
    fun customizedInit(userTextureViewList: HashMap<String, EzmTextureView?>) {
        //去除非本地user
        removeNotExisted(userStatusList, userTextureViewList, mLocalUid)

        //设置宽高
        if (mItemWidth == 0 || mItemHeight == 0) {
            val windowManager = mContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
            val outMetrics = DisplayMetrics()
            windowManager.defaultDisplay.getMetrics(outMetrics)
            val screenWidth = outMetrics.widthPixels
            val screenHeight = outMetrics.heightPixels

            LogUtil.d("test", "screenWidth: $screenWidth screenHeight: $screenHeight")
//            val count = uids.size
//            var DividerX = getNearestSqrt(count)
//            var DividerY = Math.ceil((count * 1f / DividerX).toDouble()).toInt()

            var DividerX = 3

            val resIndex = PreferenceManager.getDefaultSharedPreferences(mContext).getInt(ConstantApp.PrefManager.PREF_PROPERTY_VIDEO_ENC_RESOLUTION, ConstantApp.DEFAULT_VIDEO_ENC_RESOLUTION_IDX)
            val videoResolution = RTCConstant.ERTCVideoResolution.values()[resIndex]

            val margin = ViewUtil.dp2px(mContext, 48f + 100f + 48f + 320f)
            if (screenWidth > screenHeight) {
                mItemWidth = screenHeight / DividerX
            } else {
                mItemWidth = screenWidth / DividerX
            }
//            mItemHeight = mItemWidth * videoResolution.height / videoResolution.width
            mItemHeight = mItemWidth * videoResolution.width / videoResolution.height
        }
    }

    fun setLocalUid(userId: String) {
        mLocalUid = userId
    }
    private var listener : OnClickListener? = null
    interface OnClickListener {
        fun onVideoViewClick(v: View, position: Int)
    }
    fun setListener(listener : OnClickListener){
        this.listener = listener
    }

    private fun getNearestSqrt(n: Int): Int {
        return sqrt(n.toDouble()).toInt()
    }

    fun removeNotExisted(
        users: ArrayList<UserStatusData>,
        userTextureViewList: HashMap<String, EzmTextureView?>,
        localUserId: String
    ) {
        val it = users.iterator()
        while (it.hasNext()) {
            val user = it.next()
            if (userTextureViewList[user.userId] == null && user.userId != localUserId) {
                it.remove()
            }
        }
    }

    fun notifyUiChanged(
        userTextureViewList: HashMap<String, EzmTextureView?>,
        userStatusList: ArrayList<UserStatusData>
    ) {
        this.userTextureViewList = userTextureViewList
        this.userStatusList = userStatusList
        notifyDataSetChanged()
    }

    fun notifyDataSetChanged(userStatusList: ArrayList<UserStatusData>) {
        this.userStatusList = userStatusList
        notifyDataSetChanged()
    }

    override fun getItemCount(): Int {
        return userStatusList.size
    }

    fun getItem(position: Int): UserStatusData {
        return userStatusList[position]
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val v = mInflater.inflate(R.layout.video_view_container, parent, false) as ViewGroup
        v.layoutParams.width = mItemWidth
        v.layoutParams.height = mItemHeight
        mDefaultChildItem = v.childCount
        return VideoUserStatusHolder(v)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val myHolder = holder as VideoUserStatusHolder
        val user = userStatusList[position]
        val holderView = myHolder.itemView as FrameLayout
        val mTextureView = userTextureViewList[user.userId]
        var tagUser:UserStatusData ? = null
         holderView.tag?.apply {
             tagUser = this as UserStatusData
         }
        if(mTextureView != null) {
            if (holderView.childCount == mDefaultChildItem || user.userId != tagUser?.userId) {
                mTextureView?.let {
                    stripView(it)
                    //添加视频view
                    holderView.addView(
                        mTextureView,
                        0,
                        FrameLayout.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.MATCH_PARENT
                        )
                    )
                    holderView.tag = user
                }
            }
        } else {
            if(holderView.childCount > mDefaultChildItem) {
                holderView.removeViewAt(0)
            }
        }
        renderExtraData(user, myHolder, mLocalUid)
        holder.holder.tag = user
        holder.holder.setOnClickListener{
            listener?.onVideoViewClick(it, position)
        }
    }

    fun renderExtraData(user: UserStatusData, myHolder: VideoUserStatusHolder, localuId : String) {
        if (user.videoStatus != DeviceState.DS_Active.value) {
            myHolder.mAvatar.visibility = View.VISIBLE
            myHolder.mMaskView.setBackgroundColor(mContext.resources.getColor(R.color.darker_gray))
        } else {
            myHolder.mAvatar.visibility = View.GONE
            myHolder.mMaskView.setBackgroundColor(Color.TRANSPARENT)
        }
        var volume = user.volume
        if (user.audioStatus != DeviceState.DS_Active.value) {
            myHolder.mIndicator.setImageResource(R.mipmap.icon_muted)
            myHolder.mIndicator.visibility = View.VISIBLE
            volume = 0
        } else {
            if (volume > 0) {
                myHolder.mIndicator.setImageResource(R.mipmap.icon_speaker)
                myHolder.mIndicator.visibility = View.VISIBLE
            } else {
                myHolder.mIndicator.visibility = View.INVISIBLE
            }
        }

        var netQuality = networkQualityDesc[user.networkQuality]
        var decodeEngine = MyApp.ertcEngine?.getDecodeEngine(user.userId)?:-1;

        if (user.videoInfoData != null) {
            var show = "[id:${user.userId}] [音量:$volume] \n[网络:$netQuality] [解码:${decodeEngintDesc[decodeEngine + 1]}] "
            myHolder.mMetaData.text = show
            myHolder.mVideoInfo.visibility = View.VISIBLE
        } else {
            myHolder.mVideoInfo.visibility = View.GONE
        }

        if (user.userId == localuId || user.streamType != RTCConstant.ERTC_VIDEO_STREAM_TYPE_SMALL){
            myHolder.mCheckBoxStreamType.visibility = View.GONE
        }else {
            myHolder.mCheckBoxStreamType.visibility = View.VISIBLE
            myHolder.mCheckBoxStreamType.setOnCheckedChangeListener(null)
//            myHolder.mCheckBoxStreamType.isChecked = user.streamType == RTCConstant.ERTC_VIDEO_STREAM_TYPE_SMALL
            myHolder.mCheckBoxStreamType.tag = user
            myHolder.mCheckBoxStreamType.setOnCheckedChangeListener { buttonView, isChecked ->
                val tagUser = buttonView.tag as UserStatusData
                var streamType = if (isChecked) RTCConstant.ERTC_VIDEO_STREAM_TYPE_SMALL else RTCConstant.ERTC_VIDEO_STREAM_TYPE_BIG
//                tagUser.streamType = if (isChecked) RTCConstant.ERTC_VIDEO_STREAM_TYPE_SMALL else RTCConstant.ERTC_VIDEO_STREAM_TYPE_BIG
                MyApp.ertcEngine?.setRemoteVideoStreamType(tagUser.userId, streamType)
            }
        }

    }

    fun stripView(view: View) {
        val parent = view.parent
        if (parent != null) {
            (parent as FrameLayout).removeView(view)
        }
    }


    class VideoUserStatusHolder(v: View) : RecyclerView.ViewHolder(v) {
        @JvmField
        val mMaskView: RelativeLayout = v.findViewById<View>(R.id.user_control_mask) as RelativeLayout

        @JvmField
        val mAvatar: ImageView = v.findViewById<View>(R.id.default_avatar) as ImageView

        @JvmField
        val mIndicator: ImageView = v.findViewById<View>(R.id.indicator) as ImageView

        @JvmField
        val mVideoInfo: LinearLayout = v.findViewById<View>(R.id.video_info_container) as LinearLayout

        @JvmField
        val mMetaData: TextView = v.findViewById<View>(R.id.video_info_metadata) as TextView

        @JvmField
        val mCheckBoxStreamType: CheckBox = v.findViewById<View>(R.id.check_box_stream_type) as CheckBox

        val holder = v

    }
}