package com.cr.pages

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import androidx.fragment.app.activityViewModels
import com.bigkoo.pickerview.adapter.ArrayWheelAdapter
import com.contrarywind.listener.OnItemSelectedListener
import com.cr.common.CrColorManager
import com.cr.common.CrLiveManager
import com.cr.common.CrSaveManager
import com.cr.common.CrUnitManager
import com.cr.cruav.CrApplication
import com.cr.cruav.R
import com.cr.data.CrUtil
import com.cr.dialog.DialogInput
import com.cr.event.BarAction
import com.cr.event.CrCommonAction
import com.cr.event.EventCommon
import com.cr.event.EventFragmentBarAction
import com.cr.models.CompletionModel
import com.cr.models.ICompletion
import com.cr.view.CrViewWheel
import com.cr.viewmodel.CrLiveStreamVM
import dji.v5.common.video.channel.VideoChannelState

/**
 * 操作系统：MAC系统
 * 创建者：王成
 * 创建日期：2023/9/12 13:50
 * 描述：直播页面
 */
class FragmentLiveStream : CrNavigationFragment(), View.OnClickListener {
    // todo: 2023/9/12 控件定义
    private var wheelLiveQuality: CrViewWheel? = null  // define: 2023/9/12 直播品质选择器
    private var wheelLiveUrl: CrViewWheel? = null  // define: 2023/9/12 直播地址选择器
    private var wheelLiveChannelType: CrViewWheel? = null // define: 2023/9/12 直播通道选择器
    private var btnActionAppendUrl: LinearLayout? = null // define: 2023/9/12 添加直播地址按钮
    private var btnActionQuality:LinearLayout?=null // define: 2023/9/14 视频质量
    private var btnActionChannelType:LinearLayout?= null // define: 2023/9/14 设置视频通道
    private var lblInfo: TextView? = null  // define: 2023/9/13 直播动态信息
    private var btnStartLive: Button? = null // define: 2023/9/13 直播开始
    private var btnStopLive: Button? = null // define: 2023/9/13 停止直播


    // todo: 2023/9/12 定义变量
    private var adapterWheelLiveQuality: ArrayWheelAdapter<String>? = null // define: 2023/9/12 适配器
    private var adapterWheelLiveUrl: ArrayWheelAdapter<String>? = null  // define: 2023/9/12 适配器
    private var adapterWheelChannelType: ArrayWheelAdapter<String>? = null // define: 2023/9/12 适配器
    private var itemsLiveQuality: MutableList<String>? = null  // define: 2023/9/12 直播视频质量数据集
    private var itemsLiveUrl: MutableList<String>? = null  // define: 2023/9/12 直播地址数据集
    private var itemsLiveChannelType: MutableList<String>? = null  // define: 2023/9/12 直播通道选择集

    private var indexLiveQuality:Int = -1  // define: 2023/9/13 直播质量当前索引
    private var indexLiveChannelType:Int = -1  // define: 2023/9/13 直播通道当前索引
    private var indexLiveUrl:Int = -1  // define: 2023/9/13 直播地址当前索引

    // todo: 2023/9/13 动态显示的直播信息
    private var isStreaming: String = "否"  // define: 2023/9/13 是否正在直播
    private var fps: Int = 0   // define: 2023/9/13 帧率
    private var vbps: Int = 0  // define: 2023/9/13 码率
    private var resolutionWidth: Int = 0  // define: 2023/9/13 分辨率宽
    private var resolutionHeight: Int = 0  // define: 2023/9/13 分辨率高
    private var packetLoss: Int = 0  // define: 2023/9/13 丢包率
    private var rtt: Int = 0  // define: 2023/9/13 延迟时间
    private var error: String = "" // define: 2023/9/13 错误信息


    // define: 2023/9/12 绑定直播模型
    private val liveStreamVm: CrLiveStreamVM by activityViewModels()

    /**
     * 初始化
     * @param inflater LayoutInflater
     * @param container ViewGroup?
     * @param savedInstanceState Bundle?
     * @return View?
     */
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // todo: 2023/9/13 设置动画方向
        setAnimationDirection(AnimationDirection.RIGHT)
        self = this
        mainView = inflater.inflate(R.layout.frag_live_stream, null)
        // todo: 2023/9/13 设置导航栏
        setBar(R.id.nv)
        // todo: 2023/9/12 挂载控件
        joinControls()
        // todo: 2023/9/12 初始化页面
        initPage()
        return mainView
    }

    /**
     * 挂载控件
     */
    override fun joinControls() {
        super.joinControls()
        mainView?.let {
            // todo: 2023/9/12 挂接直播地址选择器
            wheelLiveUrl = it.findViewById(R.id.wheel_live_url)
            CrUnitManager.setWheel(wheelLiveUrl!!, wheelLiveUrlListener)
            // todo: 2023/9/12 挂接直播视频质量选择器
            wheelLiveQuality = it.findViewById(R.id.wheel_live_quality)
            CrUnitManager.setWheel(wheelLiveQuality!!, wheelLiveQualityListener)
            // todo: 2023/9/12 挂接直播视频通道选择器
            wheelLiveChannelType = it.findViewById(R.id.wheel_live_channel_type)
            CrUnitManager.setWheel(wheelLiveChannelType!!, wheelLiveChannelTypeListener)
            // todo: 2023/9/12 挂载添加直播地址按钮
            btnActionAppendUrl = it.findViewById(R.id.btn_append_url)
            btnActionAppendUrl?.setOnClickListener(this)
            // todo: 2023/9/13 挂接直播动态信息
            lblInfo = it.findViewById(R.id.live_info)
            // todo: 2023/9/13 挂接直播操作按钮
            btnStartLive = it.findViewById(R.id.btn_start_live)
            btnStartLive?.setOnClickListener(this)
            btnStopLive = it.findViewById(R.id.btn_stop_live)
            btnStopLive?.setOnClickListener(this)
            btnActionQuality = it.findViewById(R.id.btn_set_quality)
            btnActionQuality?.setOnClickListener(this)
            btnActionChannelType = it.findViewById(R.id.btn_set_channel_type)
            btnActionChannelType?.setOnClickListener(this)
        }
    }

    /**
     * 初始化页面
     */
    override fun initPage() {
        super.initPage()
        // todo: 2023/9/12 初始化直播视频质量选择器
        itemsLiveQuality = mutableListOf()
        adapterWheelLiveQuality = ArrayWheelAdapter(itemsLiveQuality)
        wheelLiveQuality?.adapter = adapterWheelLiveQuality
        syncWheelLiveQuality()

        // todo: 2023/9/13 初始化直播地址选择器
        itemsLiveUrl = mutableListOf()
        adapterWheelLiveUrl = ArrayWheelAdapter(itemsLiveUrl)
        wheelLiveUrl?.adapter = adapterWheelLiveUrl
        syncWheelUrl()

        // todo: 2023/9/13 初始化直播通道选择器
        itemsLiveChannelType = mutableListOf()
        adapterWheelChannelType = ArrayWheelAdapter(itemsLiveChannelType)
        wheelLiveChannelType?.adapter = adapterWheelChannelType
        syncWheelChannelType()

        // todo: 2023/9/13 订阅
        initObserve()

        // todo: 2023/9/13 初始化直播信息
        clearLiveStreamInfo()
    }

    /**
     * 订阅
     */
    private fun initObserve() {
        // todo: 2023/9/13 注册动态信息监听
        liveStreamVm.streamStatusInfo.observe(requireActivity()) {
            it?.let {
                isStreaming = if (it.isStreaming) "是" else "否"
                fps = it.fps
                vbps = it.vbps
                resolutionWidth = it.videoWidth
                resolutionHeight = it.videoHeight
                packetLoss = it.packetLoss
                rtt = it.rtt
                activeStreamInfo()
            }
        }
        // todo: 2023/9/13 注册错误监听
        liveStreamVm.streamErrorInfo.observe(requireActivity()) {
            it?.let {
                error = it.description()
                activeStreamInfo()
            }
        }
    }

    /**
     * 同步视频质量
     */
    private fun syncWheelLiveQuality() {
        itemsLiveQuality?.clear()
        var qualityTitleList = CrLiveManager.getInstance().getQualityList()
        for (title in qualityTitleList) {
            itemsLiveQuality?.add(title)
        }
        wheelLiveQuality?.setSelectItem(itemsLiveQuality!![0])
        wheelLiveQuality?.onItemSelected()
    }

    /**
     * 同步码流通道
     */
    private fun syncWheelChannelType() {
        itemsLiveChannelType?.clear()
        var channelTypeTitleList = CrLiveManager.getInstance().getChannelTypeList()
        for (title in channelTypeTitleList) {
            itemsLiveChannelType?.add(title)
        }
        wheelLiveChannelType?.setSelectItem(itemsLiveChannelType!![0])
        wheelLiveChannelType?.onItemSelected()
    }

    /**
     * 同步直播地址
     */
    private fun syncWheelUrl() {
        itemsLiveUrl?.clear()
        var urlList = CrSaveManager.getInstance().getLiveUrlList()
        for (title in urlList) {
            itemsLiveUrl?.add(title)
        }
        wheelLiveUrl?.setSelectItem(itemsLiveUrl!![itemsLiveUrl!!.size - 1])
        wheelLiveUrl?.onItemSelected()
    }

    /**
     * 直播URL地址选择器监听
     */
    private val wheelLiveUrlListener = OnItemSelectedListener { index ->
        indexLiveUrl = index
    }

    /**
     * 直播画面品质选择器监听
     */
    private val wheelLiveQualityListener = OnItemSelectedListener { index ->
        indexLiveQuality = index
    }

    /**
     * 直播视频通道选择器监听
     */
    private val wheelLiveChannelTypeListener = OnItemSelectedListener { index ->
        indexLiveChannelType = index
    }

    /**
     * 显示追加直播地址对话框
     */
    private fun showAppendLiveUrlDialog() {
        var dialog = DialogInput(CrApplication.getContext())
        dialog.setTitle("输入直播地址")
        dialog.setLabels("直播地址", null)
        dialog.setButtonsText("设置", "关闭")
        dialog.setHints("输入直播地址rtmp://...", "")
        dialog.setContent("rtmp://", "")
        dialog.setListener(dialogInputListener)
        dialog.show()
    }

    /**
     * 添加直播地址对话框监听
     */
    private val dialogInputListener = object : DialogInput.DialogInputListener {
        // todo: 2023/9/12 完成
        override fun completion(valueOne: String, valueTwo: String, self: DialogInput) {
            CrSaveManager.getInstance().saveLiveUrl(valueOne)
            syncWheelUrl()
        }

        // todo: 2023/9/12 关闭
        override fun close() {

        }
    }

    /**
     * 恢复初始状态
     */
    private fun clearLiveStreamInfo() {
        fps = -1
        vbps = -1
        isStreaming = "否"
        resolutionWidth = -1
        resolutionHeight = -1
        packetLoss = -1
        rtt = -1
        error = ""
        lblInfo?.setTextColor(CrColorManager.getColor(R.color.live_normal))
        updateLiveStreamInfo()
    }

    /**
     * 激活直播信息
     */
    private fun activeStreamInfo() {
        lblInfo?.setTextColor(CrColorManager.getColor(R.color.live_active))
        updateLiveStreamInfo()
    }

    /**
     * 更新信息展示
     */
    private fun updateLiveStreamInfo() {
        val liveStreamInfo = "是否直播: $isStreaming \n" +
                "帧率: ${fps}fps \n" +
                "码率: ${vbps}Kbps \n" +
                "分辨率: $resolutionWidth * $resolutionHeight \n" +
                "丢包率: ${packetLoss}% \n" +
                "延迟: ${rtt}ms \n" +
                "错误: $error"
        lblInfo?.text = liveStreamInfo
    }

    /**
     * 开启直播
     */
    private fun startLive() {
        // todo: 2023/9/13 添加监听
        liveStreamVm.addStreamStatusListener()
        // todo: 2023/9/13 获取相关信息
        wheelLiveQuality?.setSelectItem(
            CrLiveManager.getInstance().getQualityTitle(liveStreamVm.getLiveStreamQuality())
        )
        wheelLiveChannelType?.setSelectItem(
            CrLiveManager.getInstance().getChannelTypeTitle(liveStreamVm.getVideoChannel())
        )
    }

    // todo: 2023/9/14 操作
    /**
     * 开始直播
     */
    private fun actionStartLive(){
        // todo: 2023/9/13 判断是否选择了直播地址
        if(indexLiveUrl == -1){
            showWarning("请选择直播地址后重试！")
            return
        }
        // todo: 2023/9/13 判断视频通道是否已开启
        if(!liveStreamVm.channelTypeIsOpen()){
            showWarning("请开启视频通道后重试！")
            return
        }
        // todo: 2023/9/13 设置直播地址
        liveStreamVm.setRTMStreamSettings(itemsLiveUrl!![indexLiveUrl])
        // todo: 2023/9/13 开始直播
        liveStreamVm.startStream(object : ICompletion<String> {
            override fun onCompletion(completion: CompletionModel<String>) {
                if (completion.isSuccess == true) {
                    showToast("直播开启成功！")
                    startLive()
                    // todo: 2023/9/13 发送隐藏直播信息展示组件
                    CrApplication.getEventBus().post(EventCommon(CrCommonAction.LIVE_INFO_STATE,true))
                } else {
                    showError(completion.result!!)
                }
            }
        })
    }

    /**
     * 停止直播
     */
    private fun actionStopLive(){
        liveStreamVm.stopStream(object : ICompletion<String> {
            override fun onCompletion(completion: CompletionModel<String>) {
                if (completion.isSuccess == true) {
                    showToast("直播已停止")
                } else {
                    showError(completion.result!!)
                }
                // todo: 2023/9/13 初始化信息 移除监听
                clearLiveStreamInfo()
                liveStreamVm.removeStreamStatusListener()
                // todo: 2023/9/13 发送隐藏直播信息展示组件
                CrApplication.getEventBus().post(EventCommon(CrCommonAction.LIVE_INFO_STATE,false))
            }
        })
    }

    /**
     * 设置视频质量
     */
    private fun actionSetQuality(){
        // todo: 2023/9/14 判断是否正在直播
        if(!liveStreamVm.streamStatusInfo?.value!!.isStreaming){
            showWarning("未直播，无法设置！")
        }else{
            var quality = CrLiveManager.getInstance().getQuality(itemsLiveQuality!![indexLiveQuality])
            liveStreamVm.setLiveStreamQuality(quality)
        }
    }

    /**
     * 设置直播通道
     */
    private fun actionSetChannelType(){
        // todo: 2023/9/14 判断是否正在直播
        if(!liveStreamVm.streamStatusInfo?.value!!.isStreaming){
            showWarning("未直播，无法设置！")
        }else{
            // todo: 2023/9/14 判断视频流是否开启
            var channelType = CrLiveManager.getInstance().getChannelType(itemsLiveChannelType!![indexLiveChannelType])
            if(liveStreamVm.getChannelStatus(channelType) != VideoChannelState.ON){
                showWarning("视频通道未开启，无法设置！")
            }else{
                liveStreamVm.setVideoChannel(channelType)
            }
        }
    }


    /**
     * 覆写点击事件
     * @param view View
     */
    override fun onClick(view: View?) {
        when (view?.id) {
            R.id.btn_append_url -> {
                // todo: 2023/9/12 添加直播地址
                showAppendLiveUrlDialog()
            }
            R.id.btn_start_live -> {
                // todo: 2023/9/14 开始直播
                actionStartLive()
            }
            R.id.btn_stop_live -> {
                // todo: 2023/9/14 停止直播
               actionStopLive()
            }
            R.id.btn_set_quality->{
                // todo: 2023/9/14 设置直播画质
                actionSetQuality()
            }
            R.id.btn_set_channel_type->{
                // todo: 2023/9/14 设置视频通道
                actionSetChannelType()
            }
        }
    }

    /**
     * 覆写关闭方法
     */
    override fun dismiss() {
        CrApplication.getEventBus().post(EventFragmentBarAction(self!!, BarAction.ACTION_DISMISS))
    }
}