package com.cr.viewmodel

import android.os.Handler
import android.os.Looper
import androidx.lifecycle.MutableLiveData
import com.cr.common.CrVideoChannelInfo
import com.cr.data.CrUtil
import dji.sdk.keyvalue.key.CameraKey
import dji.v5.common.video.channel.VideoChannelType
import dji.v5.common.video.interfaces.IVideoChannel
import dji.v5.common.video.interfaces.IVideoFrame
import dji.v5.common.video.interfaces.StreamDataListener
import dji.v5.common.video.interfaces.VideoChannelStateChangeListener
import dji.v5.common.video.stream.StreamSource
import dji.v5.et.action
import dji.v5.et.create
import dji.v5.manager.datacenter.MediaDataCenter
import dji.v5.manager.datacenter.video.StreamSourceListener

/**
 * 操作系统：MAC系统
 * 创建者：王成
 * 创建日期：2023/3/10 09:55
 * 描述：视频通道模型
 */
class CrVideoChannelVM : CrViewModel() {

    // define: 2023/3/10 通道信息
    val videoChannelInfo = MutableLiveData<CrVideoChannelInfo>()

    // define: 2023/3/11 当前video的帧信息
    val videoFrame = MutableLiveData<IVideoFrame>()

    // define: 2023/3/9 码流源集合
    private var videoStreamSources = mutableListOf<StreamSource>()

    // define: 2023/3/11 视频通道集合
    private var videoChannels = mutableListOf<IVideoChannel>()

    // define: 2023/3/10 主视频通道
    private var primaryVideoChannel: IVideoChannel? = null

    // define: 2023/3/11 第二视频通道
    private var secondaryVideoChannel: IVideoChannel? = null

    // define: 2023/3/10 主线程的Looper
    private val handler = Handler(Looper.getMainLooper())

    // define: 2023/3/11 监听
    lateinit var listener: CrVideoChannelListener

    // todo: 2023/3/13 当前视频通道
    private var curVideoChannel: IVideoChannel? = null

    /**
     * 初始化
     */
    init {
        videoChannelInfo.value = CrVideoChannelInfo()
        // todo: 2023/3/10 防止进入图传界面的时候还处于回放状态
        CameraKey.KeyExitPlayback.create(0).action()
    }

    /**
     * 主要视频通道状态监听
     */
    private var videoChannelStateListener = VideoChannelStateChangeListener { from, to ->
//        CrUtil.print("通道类型=" + curVideoChannel?.videoChannelType.toString() + " 前=" + from.toString() + "后=" + to.toString())
    }



    /**
     * 主通道数据流监听
     */
    private var videoChannelStreamDataListener = StreamDataListener {
        it?.let {
//            CrUtil.print("通道类型=" + curVideoChannel?.videoChannelType.toString() + " 通道帧率=" + it.fps.toString())
        }
    }


    /**
     * 获取全部可用的视频通道
     * @return List<IVideoChannel>?
     */
    private fun getAllVideoChannels(): List<IVideoChannel>? {
        return MediaDataCenter.getInstance().videoStreamManager?.let {
            MediaDataCenter.getInstance().videoStreamManager.availableVideoChannels
        } ?: let {
            null
        }
    }


    /**
     * 覆写移除
     */
    override fun onCleared() {
        // todo: 2023/3/11 移除码流监听 飞行器监听 重置码流通道
        removeStreamSourceListener()
        resetMultiVideoChannels()
    }


    /**
     * 开启视频通道
     * 此方法调用需要在链接飞行器成功后在使用，
     * 否则将导致无法获取有效码流和码流通道
     */
    fun beginVideoChannel() {
        // todo: 2023/3/11 绑定码流监听
        addStreamSourceListener()
    }

    /**
     * 关闭视频通道
     */
    fun endVideoChannel() {
        // todo: 2023/3/11 解除码流绑定
        removeStreamSourceListener()
        resetMultiVideoChannels()
        // todo: 2023/3/13 解除视频通道监听
        removeVideoChannelListener()
    }

    /**
     * 码流源变化监听
     */
    private val streamSourcesListener = StreamSourceListener { it1 ->
        it1!!.let {
            videoStreamSources = it1
            if (videoStreamSources.size > 0 && videoChannels.size == 0) {
                // todo: 2023/3/11 获取全部可用通道
                videoChannels = getAllVideoChannels() as MutableList<IVideoChannel>
                if(videoChannels.size == 1){
                    primaryVideoChannel = getVideoChannelByType(VideoChannelType.PRIMARY_STREAM_CHANNEL)
                }else if(videoChannels.size == 2){
                    primaryVideoChannel = getVideoChannelByType(VideoChannelType.PRIMARY_STREAM_CHANNEL)
                    secondaryVideoChannel = getVideoChannelByType(VideoChannelType.SECONDARY_STREAM_CHANNEL)
                }
                // todo: 2023/3/13 如果次要通道不为空 则优先图传次要通道 因为DJI默认这是FPV
                if(secondaryVideoChannel != null){
                    secondaryVideoChannel?.let {
                        curVideoChannel = secondaryVideoChannel
                    }
                }else{
                    primaryVideoChannel?.let {
                        curVideoChannel = primaryVideoChannel
                    }
                }
                // todo: 2023/3/13 初始化图传通道
                curVideoChannel?.let {
                    listener.initVideoChannel(it)
                }
                // todo: 2023/3/13 添加监听
                addVideoChannelListener()
            }
        }
    }

    /**
     * 根据类型获取通道
     * @param channelType VideoChannelType
     * @return IVideoChannel?
     */
    private fun getVideoChannelByType(channelType:VideoChannelType): IVideoChannel? {
        return MediaDataCenter.getInstance().videoStreamManager.getAvailableVideoChannel(channelType)
    }


    /**
     * 添加通道监听
     */
    private fun addVideoChannelListener() {
        curVideoChannel?.addVideoChannelStateChangeListener(videoChannelStateListener)
        curVideoChannel?.addStreamDataListener(videoChannelStreamDataListener)
    }

    /**
     * 移除通道监听
     */
    private fun removeVideoChannelListener() {
        curVideoChannel?.removeVideoChannelStateChangeListener(videoChannelStateListener)
        curVideoChannel?.removeStreamDataListener(videoChannelStreamDataListener)
    }

    /**
     * 添加码流监听
     */
    private fun addStreamSourceListener() {
        MediaDataCenter.getInstance().videoStreamManager.addStreamSourcesListener(
            streamSourcesListener
        )
    }

    /**
     * 移除码流监听
     */
    private fun removeStreamSourceListener() {
        MediaDataCenter.getInstance().videoStreamManager.removeStreamSourcesListener(
            streamSourcesListener
        )
    }

    /**
     * 重置通道
     */
    private fun resetMultiVideoChannels() {
        if (MediaDataCenter.getInstance().videoStreamManager != null) {
            MediaDataCenter.getInstance().videoStreamManager.resetAllVideoChannels()
        }
    }


    /**
     * 切换码流源
     */
    fun triggerStreamSource() {
        // todo: 2023/3/11 如果通道多于一个
        if (videoChannels.size > 1) {
            if(curVideoChannel?.videoChannelType == VideoChannelType.PRIMARY_STREAM_CHANNEL){
                curVideoChannel = secondaryVideoChannel
                listener.updateVideoChannelType(VideoChannelType.SECONDARY_STREAM_CHANNEL)
            }else{
                curVideoChannel = primaryVideoChannel
                listener.updateVideoChannelType(VideoChannelType.PRIMARY_STREAM_CHANNEL)
            }
        }
    }
}