package com.swago.baseswago.agora

import android.content.Context
import android.util.Log
import android.widget.FrameLayout
import com.swago.baseswago.R
import com.swago.baseswago.baseroom.RoleType
import com.swago.baseswago.constant.UrlConstant
import com.swago.baseswago.util.AppContext
import com.swago.baseswago.util.LogUtil
import io.agora.rtc.Constants.*
import io.agora.rtc.IRtcEngineEventHandler
import io.agora.rtc.RtcEngine
import io.agora.rtc.models.ClientRoleOptions
import io.agora.rtc.video.ChannelMediaInfo
import io.agora.rtc.video.ChannelMediaRelayConfiguration
import io.agora.rtc.video.VideoCanvas
import io.agora.rtc.video.VideoEncoderConfiguration
import java.lang.Exception

/**
 *@date 2021/10/6 11:16
 *description:
 */
object AgoraManager {

    private var mRtcEngine: RtcEngine? = null
    private var userType = -1
    private var iSwagoIRtcEngineEventHandler:ISwagoIRtcEngineEventHandler? = null

    fun initializeEngine(context: Context,iRtcEngineEventHandler: ISwagoIRtcEngineEventHandler) {
        try {
            this.iSwagoIRtcEngineEventHandler = iRtcEngineEventHandler
            mRtcEngine = RtcEngine.create(
                context,
                UrlConstant.getAgoraId(),
                object : IRtcEngineEventHandler() {

                    override fun onUserOffline(uid: Int, reason: Int) {
                        super.onUserOffline(uid, reason)
                    }

                    override fun onError(err: Int) {
                        super.onError(err)
                        iSwagoIRtcEngineEventHandler?.onError(err)
                        LogUtil.d("声网错误码-$err")
                    }

                    override fun onFirstLocalAudioFramePublished(elapsed: Int) {
                        super.onFirstLocalAudioFramePublished(elapsed)
                        iSwagoIRtcEngineEventHandler?.onFirstLocalAudioFramePublished(elapsed)
                        LogUtil.d("首帧推出")
                    }

                    override fun onFirstRemoteAudioDecoded(uid: Int, elapsed: Int) {
                        super.onFirstRemoteAudioDecoded(uid, elapsed)

                    }

                    override fun onFirstRemoteVideoDecoded(
                        uid: Int,
                        width: Int,
                        height: Int,
                        elapsed: Int
                    ) {
                        super.onFirstRemoteVideoDecoded(uid, width, height, elapsed)
                        LogUtil.d("首帧解码")
                    }

                    override fun onFirstRemoteVideoFrame(
                        uid: Int,
                        width: Int,
                        height: Int,
                        elapsed: Int
                    ) {
                        super.onFirstRemoteVideoFrame(uid, width, height, elapsed)
                        LogUtil.d("首帧视频")
                        iSwagoIRtcEngineEventHandler?.onFirstRemoteVideoDecoded(uid, width, height, elapsed)
                    }

                    override fun onAudioVolumeIndication(
                        speakers: Array<out AudioVolumeInfo>?,
                        totalVolume: Int
                    ) {
                        super.onAudioVolumeIndication(speakers, totalVolume)
                        iSwagoIRtcEngineEventHandler?.onAudioVolumeIndication(speakers,totalVolume)
                    }

                    override fun onConnectionStateChanged(state: Int, reason: Int) {
                        super.onConnectionStateChanged(state, reason)
                        iSwagoIRtcEngineEventHandler?.onConnectionStateChanged(state, reason)
                    }

                    override fun onChannelMediaRelayStateChanged(state: Int, code: Int) {
                        super.onChannelMediaRelayStateChanged(state, code)
                        Log.d("StateChanged","结果--$state----$code")
                        iSwagoIRtcEngineEventHandler?.onChannelMediaRelayStateChanged(state, code)
                    }

                    override fun onChannelMediaRelayEvent(code: Int) {
                        super.onChannelMediaRelayEvent(code)
                        Log.d("ChannelMediaRelayEvent","结果--$code")
                    }

                    override fun onUserJoined(uid: Int, elapsed: Int) {
                        super.onUserJoined(uid, elapsed)
                        Log.d("onUserJoined","结果--$uid")
                    }
                })
            setChannelProfile()
        } catch (e: Exception) {
            LogUtil.d(Log.getStackTraceString(e))
        }
    }


    private fun setChannelProfile() {
        mRtcEngine?.setChannelProfile(CHANNEL_PROFILE_LIVE_BROADCASTING)
        mRtcEngine?.enableAudio()
        mRtcEngine?.enableVideo()
    }


    fun setVideoAudio(pullVideo:Boolean,pullAudio:Boolean,pushVideo:Boolean,pushAudio:Boolean){
        if (pullVideo){
            mRtcEngine?.muteAllRemoteVideoStreams(false)
        }else{
            mRtcEngine?.muteAllRemoteVideoStreams(true)
        }
        if (pullAudio){
            mRtcEngine?.muteAllRemoteAudioStreams(false)
        }else{
            mRtcEngine?.muteAllRemoteAudioStreams(true)
        }
        if (pushAudio){
            mRtcEngine?.enableLocalAudio(true)
            mRtcEngine?.muteLocalAudioStream(false)
        }else{
            mRtcEngine?.enableLocalAudio(false)
            mRtcEngine?.muteLocalAudioStream(true)
        }
        if (pushVideo){
            mRtcEngine?.enableLocalVideo(true)
            mRtcEngine?.muteLocalVideoStream(false)
        }else{
            mRtcEngine?.enableLocalVideo(false)
            mRtcEngine?.muteLocalVideoStream(true)
        }
        if (pushVideo || pushAudio){
            setClientRole(RoleType.anchor)
        }else{
            setClientRole(RoleType.user)
        }
    }

    private fun setClientRole(userType: Int) {
        this.userType = userType
        if (userType == RoleType.anchor) {
            mRtcEngine?.setClientRole(CLIENT_ROLE_BROADCASTER)
        } else if (userType == RoleType.user) {
            val clientRoleOptions = ClientRoleOptions()
            clientRoleOptions.audienceLatencyLevel = AUDIENCE_LATENCY_LEVEL_LOW_LATENCY
            mRtcEngine?.setClientRole(CLIENT_ROLE_AUDIENCE, clientRoleOptions)
        }
    }

    /**
     * 主播设置预览画面
     */
    fun setupLocalVideo(context: Context, mLocalContainer: FrameLayout) {
        mRtcEngine?.startPreview()
        val mLocalView = RtcEngine.CreateRendererView(context)
        mLocalView.setZOrderMediaOverlay(true)
        mLocalContainer.addView(mLocalView)
        mRtcEngine?.setupLocalVideo(VideoCanvas(mLocalView, VideoCanvas.RENDER_MODE_HIDDEN, 0))
    }

    /**
     * 主播端切到语音房停止预览然后移除视频控件
     */
    fun stopPreviewAndRemoveLocalView(mLocalContainer: FrameLayout?){
        mRtcEngine?.stopPreview()
        mLocalContainer?.removeAllViews()
    }



    /**
     * 观众拉取远端主播画面
     */
    fun setupRemoteVideo(context: Context, anchorId: Int, mLocalContainer: FrameLayout) {
        val remoteView = RtcEngine.CreateRendererView(context)
        val result = mRtcEngine?.setupRemoteVideo(
            VideoCanvas(
                remoteView,
                VideoCanvas.RENDER_MODE_HIDDEN,
                anchorId
            )
        )
        mLocalContainer.removeAllViews()
        mLocalContainer.addView(remoteView)
        LogUtil.d("$result")
    }

    fun joinChannel(channelName: String, userId: Int, token: String = "", option: String = "") {
        val result = mRtcEngine?.joinChannel(token, channelName, option, userId)
    }


    /**
     * 观众切换房间
     */
    fun changeRoom(anchorId: Int, frameLayout: FrameLayout?) {
        mRtcEngine?.setupRemoteVideo(VideoCanvas(null, VideoCanvas.RENDER_MODE_HIDDEN, anchorId))
        frameLayout?.removeAllViews()
        mRtcEngine?.leaveChannel()
    }

    fun leaveChannel() {
        mRtcEngine?.leaveChannel()
    }

    /**
     * 关闭房间
     */
    fun closedRoom() {
        if (userType == RoleType.anchor) {
            mRtcEngine?.stopPreview()
        }
        mRtcEngine?.disableVideo()
        mRtcEngine?.leaveChannel()
        iSwagoIRtcEngineEventHandler = null
        RtcEngine.destroy()
        mRtcEngine = null
    }


    fun setVideoConfiguration(
        vd: VideoEncoderConfiguration.VideoDimensions = VideoEncoderConfiguration.VD_640x480,
        fps: VideoEncoderConfiguration.FRAME_RATE = VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15
    ) {
        mRtcEngine?.setVideoEncoderConfiguration(
            VideoEncoderConfiguration(
                vd, fps,
                VideoEncoderConfiguration.STANDARD_BITRATE,
                VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT
            )
        )
    }


    /**
     * PK时转发主播流
     * uid 填入用户在目标频道内的用户名
     */
    fun startPK(sourceChannelName: String,destChannelName: String,uid:Int,sourceChannelToken:String?=null,destChannelToken: String?=null){
        mRtcEngine?.stopChannelMediaRelay()
        val sourceChannelInfo = ChannelMediaInfo(sourceChannelName,sourceChannelToken,0)
        val mediaRelayConfiguration = ChannelMediaRelayConfiguration()
        mediaRelayConfiguration.setSrcChannelInfo(sourceChannelInfo)

        val destChannelInfo = ChannelMediaInfo(destChannelName, destChannelToken,uid)
        mediaRelayConfiguration.setDestChannelInfo(destChannelName,destChannelInfo)
        val result = mRtcEngine?.startChannelMediaRelay(mediaRelayConfiguration)
        Log.d("PK跨频道","结果---$result")
    }

    /**
     * 停止PK
     */
    fun stopPK(){
        mRtcEngine?.stopChannelMediaRelay()
    }

    /**
     * 移除远端视图
     */
    fun removeRemoteVideo(uid: Int,frameLayout: FrameLayout?) {
        mRtcEngine?.setupRemoteVideo(VideoCanvas(null, VideoCanvas.RENDER_MODE_HIDDEN, uid))
        frameLayout?.removeAllViews()
    }

    /**
     * 切换摄像头
     */
    fun changeCameraOrientation() {
        mRtcEngine?.switchCamera()
    }

    /**
     * 设置镜像
     */
    var isMirror = true
    fun setMirror(userId: Int) {
        if (isMirror) {
            mRtcEngine?.setRemoteRenderMode(userId, RENDER_MODE_HIDDEN, VIDEO_MIRROR_MODE_DISABLED)
        } else {
            mRtcEngine?.setRemoteRenderMode(userId, RENDER_MODE_HIDDEN, VIDEO_MIRROR_MODE_ENABLED)
        }
        isMirror = !isMirror
    }

    /**
     * 打开或者关闭本地音频流
     */
    fun setMute(mute:Boolean){
        mRtcEngine?.muteLocalAudioStream(mute)
    }


    /**
     * 连麦的时候用户端要重置token
     */
    fun renewToken(token:String){
        mRtcEngine?.renewToken(token)
    }


    fun enableAudioVolumeIndication(){
        mRtcEngine?.enableAudioVolumeIndication(2000,3,true)
    }

}