package com.cr.viewmodel

import androidx.lifecycle.MutableLiveData
import com.cr.common.CrAudioUtil
import com.cr.common.CrFlightControlInfo
import com.cr.common.CrJTMManager
import com.cr.common.CrUnitManager
import com.cr.cruav.R
import com.cr.data.CrUtil
import dji.sdk.keyvalue.key.BatteryKey
import dji.sdk.keyvalue.key.FlightControllerKey
import dji.sdk.keyvalue.key.KeyTools
import dji.sdk.keyvalue.key.ProductKey
import dji.sdk.keyvalue.value.flightcontroller.CompassCalibrationState
import dji.sdk.keyvalue.value.flightcontroller.IMUCalibrationState
import dji.sdk.keyvalue.value.product.ProductType
import dji.v5.et.create
import dji.v5.et.listen
import dji.v5.manager.KeyManager
import dji.v5.utils.common.ContextUtil
import dji.v5.utils.common.StringUtils
import org.locationtech.jts.geom.Coordinate
import org.locationtech.jts.geom.GeometryFactory

/**
 * 操作系统：MAC系统
 * 创建者：王成
 * 创建日期：2023/3/9 16:00
 * 描述：飞行器视图模型
 */
class CrFlightControlVM : CrViewModel() {
    // define: 2023/3/9 飞行器信息
    var flightControlInfo = MutableLiveData<CrFlightControlInfo>()

    /**
     * 初始化
     */
    init {
        flightControlInfo.postValue(CrFlightControlInfo())
        flightControlInfo.value?.reset()
    }

    /**
     * 计算距离
     */
    private fun calculateDistance() {
        flightControlInfo.value?.let {
            if (it.homeLongitude > 0 && it.homeLatitude > 0 && it.longitude > 0 && it.latitude > 0) {
                val distance = CrJTMManager.calculateDistance(
                    it.homeLongitude,
                    it.homeLatitude,
                    it.longitude,
                    it.latitude
                )
                it.homeDistance = distance
                it.homeDistanceStr = CrUnitManager.formatLength(distance)
            }
        }
    }

    /**
     * 初始化监听
     */
    override fun initListener() {
        // todo: 2023/3/9 飞行器链接监听
        FlightControllerKey.KeyConnection.create().listen(this) {
            it?.let {
                if (it) {
                    flightControlInfo.value?.isConnection = true
                    var type = KeyManager.getInstance().getValue(
                        KeyTools.createKey(ProductKey.KeyProductType),
                        ProductType.UNKNOWN
                    )
                    flightControlInfo.value?.productName = type.toString()
                    refresh(flightControlInfo)
                } else {
                    flightControlInfo.value?.reset()
                    refresh(flightControlInfo)
                }
            }
        }
        // todo: 2023/3/9 飞行器电池监听
        BatteryKey.KeyConnection.create().listen(this) {
            it?.let {
                if (!it) {
                    flightControlInfo.value?.batteryPercent = 0
                    refresh(flightControlInfo)
                }
            }
        }
        // todo: 2023/3/9 飞行器电池电量百分比监听
        BatteryKey.KeyChargeRemainingInPercent.create().listen(this) {
            it?.let {
                flightControlInfo.value?.batteryPercent = it
                refresh(flightControlInfo)
            }
        }
        // todo: 2023/3/9 卫星数量监听
        FlightControllerKey.KeyGPSSatelliteCount.create().listen(this) {
            it?.let {
                flightControlInfo.value?.gpsCount = it.toString()
                refresh(flightControlInfo)
            }
        }
        // todo: 2023/3/9 IMU校准监听
        FlightControllerKey.KeyIMUCalibrationInfo.create().listen(this) {
            it?.let {
                var state = it.getCalibrationState()
                when (state) {
                    IMUCalibrationState.CALIBRATING ->
                        flightControlInfo.value?.imuState = "校准中"
                    IMUCalibrationState.SUCCESSFUL ->
                        flightControlInfo.value?.imuState = "成功"
                    IMUCalibrationState.FAILED ->
                        flightControlInfo.value?.imuState = "失败"
                    IMUCalibrationState.NONE ->
                        flightControlInfo.value?.imuState = "正常"
                    else ->
                        flightControlInfo.value?.imuState = "未知"
                }
                refresh(flightControlInfo)
            }
        }
        // todo: 2023/3/14 指南针状态监听
        FlightControllerKey.KeyCompassCalibrationStatus.create().listen(this) {
            it?.let {
                when (it) {
                    CompassCalibrationState.FAILED ->
                        flightControlInfo.value?.compassState = StringUtils.getResStr(
                            ContextUtil.getContext(),
                            R.string.value_compass_status_failed
                        )
                    CompassCalibrationState.IDLE ->
                        flightControlInfo.value?.compassState = StringUtils.getResStr(
                            ContextUtil.getContext(),
                            R.string.value_compass_status_idle
                        )
                    CompassCalibrationState.SUCCEEDED ->
                        flightControlInfo.value?.compassState = StringUtils.getResStr(
                            ContextUtil.getContext(),
                            R.string.value_compass_status_success
                        )
                    CompassCalibrationState.HORIZONTAL ->
                        flightControlInfo.value?.compassState = StringUtils.getResStr(
                            ContextUtil.getContext(),
                            R.string.value_compass_status_horizontal
                        )
                    CompassCalibrationState.VERTICAL ->
                        flightControlInfo.value?.compassState = StringUtils.getResStr(
                            ContextUtil.getContext(),
                            R.string.value_compass_status_vertical
                        )
                    else ->
                        flightControlInfo.value?.compassState = StringUtils.getResStr(
                            ContextUtil.getContext(),
                            R.string.value_compass_status_idle
                        )
                }
                refresh(flightControlInfo)
            }
        }
        // todo: 2023/8/15 飞行器位置监听
        FlightControllerKey.KeyAircraftLocation3D.create().listen(this) {
            it?.let {
                flightControlInfo.value?.longitude = it.longitude
                flightControlInfo.value?.latitude = it.latitude
                flightControlInfo.value?.altitude = it.altitude
                flightControlInfo.value?.longitudeStr = String.format("%.5f", it.longitude)
                flightControlInfo.value?.latitudeStr = String.format("%.5f", it.latitude)
                flightControlInfo.value?.altitudeStr = String.format("%.1f米", it.altitude)
                flightControlInfo.value?.isLocationValid = it.longitude > 30 && it.latitude > 10
                // todo: 2023/8/16 计算返航距离
                calculateDistance()
                refresh(flightControlInfo)
            }
        }
        // todo: 2023/8/15 速度监听
        FlightControllerKey.KeyAircraftVelocity.create().listen(this) {
            it?.let {
                flightControlInfo.value?.speedX = it.x
                flightControlInfo.value?.speedY = it.y
                flightControlInfo.value?.speedZ = it.z
                refresh(flightControlInfo)
            }
        }
        // todo: 2023/8/15 返航点
        FlightControllerKey.KeyHomeLocation.create().listen(this) {
            it?.let {
                flightControlInfo.value?.homeLongitude = it.longitude
                flightControlInfo.value?.homeLatitude = it.latitude
                flightControlInfo.value?.isHomeLocationValid = it.longitude > 30 && it.latitude > 10
                flightControlInfo.value?.isUpdateHomeLocation = false
                // todo: 2023/8/17 返航点有效 则通过计算确定是否需要更新返航位置
                if (flightControlInfo.value?.isHomeLocationValid == true) {
                    var dis = CrJTMManager.calculateDistance(
                        it.longitude,
                        it.latitude,
                        flightControlInfo.value?.homeOldLatitude!!,
                        flightControlInfo.value?.homeOldLatitude!!
                    )
                    // todo: 2023/8/17 大于30米 则更新
                    if(dis > 30){
                        flightControlInfo.value?.isUpdateHomeLocation = true
                        flightControlInfo.value?.homeOldLongitude = it.longitude
                        flightControlInfo.value?.homeOldLatitude = it.latitude
                    }else{
                        flightControlInfo.value?.isUpdateHomeLocation = false
                    }
                }
                // todo: 2023/8/16 计算返航距离
                calculateDistance()
                refresh(flightControlInfo)
            }
        }
        // todo: 2023/8/15 起飞海拔高度
        FlightControllerKey.KeyTakeoffLocationAltitude.create().listen(this) {
            it?.let {
                var altitude = 95.0
                if (it > 3) altitude = it
                flightControlInfo.value?.takeoffAltitude = altitude
                flightControlInfo.value?.takeoffAltitudeStr = String.format("%.1f米", altitude)
                refresh(flightControlInfo)
            }
        }
        // todo: 2023/8/16 返航高度
        FlightControllerKey.KeyGoHomeHeight.create().listen(this) {
            it?.let {
                flightControlInfo.value?.homeAltitude = it
                flightControlInfo.value?.homeAltitudeStr = String.format("%d米", it)
                refresh(flightControlInfo)
            }
        }
        // todo: 2023/8/17 飞行器姿态
        FlightControllerKey.KeyAircraftAttitude.create().listen(this) {
            it?.let {
                flightControlInfo.value?.yaw = it.yaw
                flightControlInfo.value?.roll = it.roll
                flightControlInfo.value?.pitch = it.pitch
                refresh(flightControlInfo)
            }
        }
        // todo: 2023/9/26 飞行器电调
        FlightControllerKey.KeyAreMotorsOn.create().listen(this){
            it?.let {
                flightControlInfo.value?.motorsIsOn = it
                refresh(flightControlInfo)
            }
        }
    }
}