package com.swago.room.anchor

import android.Manifest
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Toast
import androidx.activity.viewModels
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.alibaba.android.arouter.facade.annotation.Route
import com.gyf.immersionbar.ImmersionBar
import com.permissionx.guolindev.PermissionX
import com.swago.baseswago.SwagoAdapter
import com.swago.baseswago.agora.AgoraManager
import com.swago.baseswago.agora.ISwagoIRtcEngineEventHandler
import com.swago.baseswago.baseroom.IRoomInfo
import com.swago.baseswago.baseroom.RoleType
import com.swago.baseswago.baseroom.SwagoRoomManager
import com.swago.baseswago.baseroom.ui.AbsAnchorActivity
import com.swago.baseswago.constant.ARouteConstant
import com.swago.baseswago.dialog.ChoiceDialogFragment
import com.swago.baseswago.model.live.audio.AudioSeatModel
import com.swago.baseswago.model.live.audio.IMAudioModel
import com.swago.baseswago.model.live.pk.ProcessPKModel
import com.swago.baseswago.model.live.pk.PunishPKModel
import com.swago.baseswago.model.live.pk.StartPKModel
import com.swago.baseswago.model.live.pk.StopPKModel
import com.swago.baseswago.util.AppContext
import com.swago.baseswago.util.DpPxUtil
import com.swago.baseswago.util.NoDoubleClickListener
import com.swago.baseswago.util.UserInfo
import com.swago.room.R
import com.swago.room.adapter.GameAdapter
import com.swago.room.audio.AudioRoomManager
import com.swago.room.audio.IAudioRoomListener
import com.swago.room.base.NoContentFragment
import com.swago.room.bean.UserRoomModel
import com.swago.room.databinding.ActivityAnchorRoomBinding
import com.swago.room.dialog.AnchorCloseDialog
import com.swago.room.dialog.CanStartLiveDialog
import com.swago.room.dialog.ForceCloseRoomDialog
import com.swago.room.enum.RoomType
import com.swago.room.lianmai.LianMaiManager
import com.swago.room.lianmai.LianMaiVm
import com.swago.room.pk.IPKListener
import com.swago.room.pk.PKStateManager
import com.swago.room.pk.PkVm
import com.swago.room.service.AgoraForegroundService
import com.swago.room.service.AgoraForegroundService.ACTION_START_FOREGROUND_SERVICE
import com.swago.room.service.AgoraForegroundService.ACTION_STOP_FOREGROUND_SERVICE
import com.swago.room.vm.MsgVm
import com.swago.room.vm.RoomOtherVm
import com.swago.room.vm.RoomVm
import io.agora.rtc.IRtcEngineEventHandler
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

/**
 *@date 2021/10/6 10:35
 *description:
 */
@Route(path = ARouteConstant.Room.anchor)
class AnchorRoomActivity : AbsAnchorActivity<ActivityAnchorRoomBinding, IRoomInfo>(),
    ISwagoIRtcEngineEventHandler, IPKListener, IAudioRoomListener {

    private val roomVm by viewModels<RoomVm>()
    private val roomOtherVm by viewModels<RoomOtherVm>()
    private val msgVm by viewModels<MsgVm>()
    private val pkVm by viewModels<PkVm>()
    private val lianMaiVm by viewModels<LianMaiVm>()

    private var agoraService: Intent? = null

    private val fragments = arrayListOf(NoContentFragment(), AnchorRoomFragment())

    private val adapter = SwagoAdapter(fragments, supportFragmentManager)

    private var anchorRoomFragment: AnchorRoomFragment? = null

    private var anchorCloseDialog: AnchorCloseDialog? = null

    //开播类型  0视频房 1语音房
    private var roomType = RoomType.VIDEO

    override fun initLiveData() {
        PKStateManager.resetData()
        roomVm.init()
        msgVm.init()
        pkVm.init()
        lianMaiVm.init()
        PKStateManager.addPKListener(this)
        AudioRoomManager.addListener(this)
        initPeerAnchorLayoutParams()
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        agoraService = Intent(this, AgoraForegroundService::class.java)
        AgoraManager.initializeEngine(this, this)
        AgoraManager.setVideoConfiguration()
        AgoraManager.setVideoAudio(pullVideo = true, pullAudio = true, pushVideo = true, pushAudio = true)
        AgoraManager.setupLocalVideo(this, binding.flLocal)
        AgoraManager.enableAudioVolumeIndication()
        anchorRoomFragment = fragments[1] as AnchorRoomFragment
        binding.viewPager.adapter = adapter

        binding.clPrepare.setOnTouchListener { v, event ->
            return@setOnTouchListener true
        }

        binding.ivPrepareCamera.setOnClickListener(object : NoDoubleClickListener() {
            override fun onClick() {
                AgoraManager.changeCameraOrientation()
            }
        })
        binding.ivPrepareClose.setOnClickListener(object : NoDoubleClickListener() {
            override fun onClick() {
                binding.ivPrepareClose.isEnabled = false
                SwagoRoomManager.closeRoom()
            }
        })

        binding.llVideo.setOnClickListener(object:NoDoubleClickListener(){
            override fun onClick() {
                if (roomType == RoomType.VIDEO) return
                AgoraManager.setVideoAudio(pullVideo = true, pullAudio = true, pushVideo = true, pushAudio = true)
                roomType = RoomType.VIDEO
                binding.viewAudio.visibility = View.INVISIBLE
                binding.viewVideo.visibility = View.VISIBLE
                binding.tvVideo.setTextColor(ContextCompat.getColor(AppContext.getContext(),R.color._ffffff))
                binding.tvAudio.setTextColor(ContextCompat.getColor(AppContext.getContext(),R.color._d4ffffff))
                AgoraManager.setupLocalVideo(this@AnchorRoomActivity, binding.flLocal)
                anchorRoomFragment?.setAudioRvState(false)
                binding.viewPager.currentItem = 0
                binding.ivPrepareCamera.visibility = View.VISIBLE
            }
        })

        binding.llAudio.setOnClickListener(object:NoDoubleClickListener(){
            override fun onClick() {
                if (roomType == RoomType.AUDIO) return
                AgoraManager.setVideoAudio(pullVideo = false, pullAudio = true, pushVideo = false, pushAudio = true)
                roomType = RoomType.AUDIO
                binding.viewAudio.visibility = View.VISIBLE
                binding.viewVideo.visibility = View.INVISIBLE
                binding.tvVideo.setTextColor(ContextCompat.getColor(AppContext.getContext(),R.color._d4ffffff))
                binding.tvAudio.setTextColor(ContextCompat.getColor(AppContext.getContext(),R.color._ffffff))
                AgoraManager.stopPreviewAndRemoveLocalView(binding.flLocal)
                anchorRoomFragment?.setAudioRvState(true)
                binding.viewPager.currentItem = 1
                binding.ivPrepareCamera.visibility = View.GONE
            }
        })

        binding.tvStartLive.setOnClickListener(object : NoDoubleClickListener() {
            override fun onClick() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU){
                    PermissionX.init(this@AnchorRoomActivity)
                        .permissions(Manifest.permission.POST_NOTIFICATIONS)
                        .request { allGranted, grantedList, deniedList ->
                            if (allGranted) {
                                binding.tvStartLive.isEnabled = false
                                val userModel = UserRoomModel()
                                userModel.roomType = roomType
                                SwagoRoomManager.changeRoom(userModel)
                                if (roomType == RoomType.VIDEO){
                                    anchorRoomFragment?.setAudioRvState(false)
                                }
                            } else {
                                binding.tvStartLive.isEnabled = true
                                Toast.makeText(
                                    AppContext.getContext(),
                                    "These permissions are denied: $deniedList",
                                    Toast.LENGTH_LONG
                                ).show()
                            }
                        }
                }else{
                    binding.tvStartLive.isEnabled = false
                    val userModel = UserRoomModel()
                    userModel.roomType = roomType
                    SwagoRoomManager.changeRoom(userModel)
                    if (roomType == RoomType.VIDEO){
                        anchorRoomFragment?.setAudioRvState(false)
                    }
                }



            }
        })
        binding.ivClose.setOnClickListener(object : NoDoubleClickListener() {
            override fun onClick() {
                if (LianMaiManager.lianMaiState == 1){
                    ChoiceDialogFragment.newInstance(AppContext.getContext().resources.getString(R.string.lian_mai_ing_sure_close),AppContext.getContext().resources.getString(
                        R.string.tips)).apply {
                        this.sureFun = {
                            lianMaiVm.closeLianMai(){
                                this@AnchorRoomActivity.binding.lianMaiView.closeLianMai(true)
                                SwagoRoomManager.closeRoom()
                            }
                        }
                    }.show(supportFragmentManager,"ChoiceDialogFragment")
                }else{
                    SwagoRoomManager.closeRoom()
                }
            }
        })

        binding.lianMaiView.openCloseLianMaiDialogFun = {
            ChoiceDialogFragment.newInstance(AppContext.getContext().resources.getString(R.string.close_mic_content),AppContext.getContext().resources.getString(
                            R.string.end_lian_mai)).apply {
                this.sureFun = {
                    lianMaiVm.closeLianMai(){
                        this@AnchorRoomActivity.binding.lianMaiView.closeLianMai(true)
                    }
                }
            }.show(supportFragmentManager,"ChoiceDialogFragment")
        }

        msgVm.anchorRoomClosed = {
            SwagoRoomManager.closeRoom()
        }

        msgVm.forceCloseAnchorRoom = {
            ForceCloseRoomDialog.newInstance(it.closedReason,it.closeTime)
                .show(supportFragmentManager, "ForceCloseRoomDialog")
        }

        roomVm.showBannerTime = {
            CanStartLiveDialog.newInstance(it).show(supportFragmentManager, "CanStartLiveDialog")
        }

        roomVm.anchorCloseLiveData.observe(this) {
            anchorCloseDialog = AnchorCloseDialog.newInstance(it)
            anchorCloseDialog?.show(supportFragmentManager, "AnchorCloseDialog")
        }
    }

    override fun changeRoom(iRoomInfo: IRoomInfo) {
    }

    override fun leaveRoom(iRoomInfo: IRoomInfo) {
    }

    override fun joinedRoom(iRoomInfo: IRoomInfo) {
        UserInfo.getUserInfo()?.let {
            AgoraManager.joinChannel(
                iRoomInfo.getChannelName(),
                it.id.toInt(),
                iRoomInfo.getAgoraToken()
            )
        }
        binding.clPrepare.visibility = View.GONE
        binding.viewPager.currentItem = 1
        binding.ivClose.visibility = View.VISIBLE
    }

    override fun endRoom(iRoomInfo: IRoomInfo?) {
    }

    override fun receiveStopLive() {

    }

    override fun closeRoomed() {
        PKStateManager.resetData()
        LianMaiManager.clearData()
        AgoraManager.closedRoom()
    }

    override fun onBackPressed() {
        SwagoRoomManager.closeRoom()
    }


    override fun onResume() {
        super.onResume()
        agoraService?.let {
            it.action = ACTION_STOP_FOREGROUND_SERVICE
            startService(it)
        }
    }

    override fun onPause() {
        super.onPause()
        agoraService?.let {
            it.action = ACTION_START_FOREGROUND_SERVICE
            startService(it)
        }
    }

    override fun onDestroy() {
        anchorCloseDialog = null
        PKStateManager.removePKListener(this)
        AudioRoomManager.removeListener(this)
        agoraService?.let { stopService(it) }
        super.onDestroy()
    }

    override fun onFirstRemoteVideoDecoded(uid: Int, width: Int, height: Int, elapsed: Int) {

    }

    override fun onConnectionStateChanged(state: Int, reason: Int) {


    }

    override fun onChannelMediaRelayStateChanged(state: Int, code: Int) {
        if (PKStateManager.roomState == PKStateManager.PK && state == 2 && code == 0) {
            pkVm.pkSure(PKStateManager.pkId)
        }
    }

    override fun onFirstLocalAudioFramePublished(elapsed: Int) {

    }

    override fun onError(err: Int) {

    }

    override fun onAudioVolumeIndication(
        speakers: Array<out IRtcEngineEventHandler.AudioVolumeInfo>?,
        totalVolume: Int
    ) {
        lifecycleScope.launch(Dispatchers.Main) {
            SwagoRoomManager.iRoomInfo?.let {
                if (it.getRoomType() == RoomType.AUDIO.type) {
                    AudioRoomManager.dispatchOnAudioVolumeIndication(speakers)
                }
            }
        }
    }

    /**************************PK******************************/
    private val marginTopValue by lazy {
        ImmersionBar.getStatusBarHeight(this) + DpPxUtil.dip2px(78f)
    }

    //对方主播id
    private var peerAnchorId = 0
    override fun startPK(startPKModel: StartPKModel, isGetDataFromIM: Boolean) {
        peerAnchorId = startPKModel.oppositeUserId.toInt()
        AgoraManager.startPK(
            startPKModel.roomId,
            startPKModel.oppositeRoomId,
            startPKModel.userId.toInt(),
            startPKModel.sourceToken,
            startPKModel.destToken
        )
        setPKLayoutParams(binding.flLocal, true)
        AgoraManager.setupRemoteVideo(this@AnchorRoomActivity, peerAnchorId, binding.peerFl)

    }

    override fun stopPK(stopPKModel: StopPKModel) {
        AgoraManager.stopPK()
        setPKLayoutParams(binding.flLocal, false)
        AgoraManager.removeRemoteVideo(peerAnchorId, binding.peerFl)
    }

    override fun punishPK(punishPKModel: PunishPKModel, isGetDataFromIM: Boolean) {

    }

    override fun processChangePK(processPKModel: ProcessPKModel, isGetDataFromIM: Boolean) {

    }


    //设置视频画面大小
    private fun setPKLayoutParams(view: View?, isPK: Boolean) {
        if (isPK) {
            val x = DpPxUtil.getScreenWidth() / 2
            val y = DpPxUtil.getScreenWidth() * 275 / 360
            val params = ConstraintLayout.LayoutParams(x, y)
            params.topToTop = R.id.rootAnchorView
            params.startToStart = R.id.rootAnchorView
            params.width = x
            params.height = y
            params.topMargin = marginTopValue
            view?.layoutParams = params
        } else {
            val params = ConstraintLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )
            view?.layoutParams = params
        }
    }

    private fun initPeerAnchorLayoutParams() {
        val x = DpPxUtil.getScreenWidth() / 2
        val y = DpPxUtil.getScreenWidth() * 275 / 360
        val params = ConstraintLayout.LayoutParams(x, y)
        params.topToTop = R.id.rootAnchorView
        params.endToEnd = R.id.rootAnchorView
        params.width = x
        params.height = y
        params.topMargin = marginTopValue
        binding.peerFl.layoutParams = params
    }

    /*************************语音房***********************************/

    override fun lockOrUnlockSeat(imAudioModel: IMAudioModel) {
    }

    override fun openSeatMic() {
        AgoraManager.setMute(false)
    }

    override fun muteSeatMic() {
        AgoraManager.setMute(true)
    }

    override fun onSeatMic() {
    }

    override fun downSeatMic() {
    }

    override fun updateData(audioSeatModel: AudioSeatModel) {
    }

    override fun changeJiFen(imAudioModel: IMAudioModel) {
    }

    override fun clearJiFen() {

    }

}