import API from "@/api"

let data_source = null

function tree2list(tree, list = []) {
    tree.forEach(item => {
        if (item.devices && item.devices.length) {
            item.devices.forEach(d => list.push(d))
        }
        if (item.child && item.child.length) {
            let arr = tree2list(item.child)
            arr.forEach(d => list.push(d))
        }
    })
    return list
}

function tree2list_org(tree, list = []) {
    tree.forEach(item => {
        list.push(item)
        if (item.child && item.child.length) {
            // 为了不失去引用，所以写成遍历然后 push
            let arr = tree2list_org(item.child)
            arr.forEach(_item => list.push(_item))
        }
    })
    return list
}

export default {
    //请求无人机控制权限
    async jursdiction() {
        let res = await API.FCKERNEL.checkUavControl({
            deviceHardId: this.uav.NoticeData.deviceHardId
        })
        if (res.code == 200) {
            this.$message.success(res.msg)
            this.uav.NoticeFlag = false
        }
    },


    async init_data_source() {
        data_source = new Cesium.CustomDataSource("FCKERNEL_LAYER")
        await viewer.dataSources.add(data_source)
    },
    destroy_data_source() {
        if (data_source) {
            data_source.entities.removeAll()
            viewer.dataSources.remove(data_source, true)
            data_source = null
        }
    },

    async list(search) {
        let list = await API.DEVICE.List({...search,cate:1});
        // let list = await API.FCKERNEL.ListUAV(params);
        if (list && list.length && list[0].child) {
            list[0].child.sort(function (a, b) {
                return a.sort - b.sort
            })
        }

        function each(tree, flag) {
            return tree.map((item) => ({
                ...item,
                collapse: flag,
                devices: item.devices && item.devices.length ?
                    item.devices.map((device) => ({
                        ...device,
                        _location: false,
                        _video: false,
                        _airway: false,
                        _control: false,
                        org_id: item.id,
                        // reportStatus: 1
                    })) : [],
                child: item.child && item.child.length ? each(item.child, true) : [],
            }));
        }

        if (list && list.length) {
            list = each(list)
        }
        this.uav.list = list || []
    },

    subscribe(topic, callbck) {
        this.mqtt_subscribe(topic, callbck)
    },
    async fn(cate, device, orgName) {
        if (device.reportStatus !== 1) {
            this.$message('无人机不在线');
            return
        }

        if (!data_source) {
            await this.uav_init_data_source()
        }
        this.controlMenuFlag = true
        let uavCate = device.cateName == 'px4' ? 'PX4' : 'APM'
        let topic = `${uavCate}/RECEIVE/${device.deviceHardId}`

        if (cate === 4) {
            // let list = await API.FCKERNEL.ListUAV()
            // 控制面板
            device._control = !device._control
            if (device._control) {
                device._video = true
                this.uav_show_video(device, orgName)
                this.uav_show_control(device)
                this.ControlFlag = true
                this.VideoTomapFlag = true
                // 打开 任务面板
                this.uav_subscribe(topic, () => {
                    console.log(`订阅无人机数据：topic:${topic}`);
                })
            } else {
                this.VideoTomapFlag = false
                // if (this.mqtt.client) {
                //     this.mqtt.client.end()
                //     this.mqtt.client = null
                // }
                // // 取消订阅
                // device._video = false
                // this.mqtt_unsubscribe(topic)
                this.uav_hide_control(device)
                this.uav_hide_video(device)
            }

        }
    },
    trans_location_data(device, uav_data) {
        if (!uav_data) {
            return uav_data
        }

        let uavInfo = uav_data.uavInfo

        let position = Cesium.Cartesian3.fromDegrees(
            uavInfo.longitude * 1,
            uavInfo.latitude * 1,
            (uavInfo.altitude * 1)
        );
        let yaw = Cesium.Math.toRadians(uavInfo.yaw + 90),
            pitch = Cesium.Math.toRadians(uavInfo.pitch),
            roll = Cesium.Math.toRadians(uavInfo.roll),
            hpr = new Cesium.HeadingPitchRoll(yaw, pitch, roll),
            orientation = Cesium.Transforms.headingPitchRollQuaternion(
                position,
                hpr
            );

        let positions = [];
        if (uavInfo.longitude != 0 && uavInfo.latitude != 0) {
            positions.push(position);
        }

        return {
            position,
            positions,
            orientation,
            device
        };
    },


    trans_mqtt_location_data(device, uav_data) {
        if (!uav_data) {
            return uav_data
        }
        // 获取航线
        let location = uav_data.locationCoordinate3D
        let position = Cesium.Cartesian3.fromDegrees(
            location.longitude * 1,
            location.latitude * 1,
            location.altitude * 1
        );


        let positions = [];
        let attitude = uav_data.attitude
        let yaw = Cesium.Math.toRadians(attitude.yaw + 90),
            pitch = Cesium.Math.toRadians(attitude.pitch),
            roll = Cesium.Math.toRadians(attitude.roll),
            hpr = new Cesium.HeadingPitchRoll(yaw, pitch, roll),
            orientation = Cesium.Transforms.headingPitchRollQuaternion(
                position,
                hpr
            );
        if (this.uav.model) {
            let model = this.uav.model
            const curPos = model.position.getValue(
                Cesium.JulianDate.now()
            );
            if (curPos) {
                const curCart = new Cesium.Cartesian3(curPos.x, curPos.y, curPos.z);
                const afterCart = new Cesium.Cartesian3(position.x, position.y, position.z);
                if (curCart.equals(afterCart)) { } else {
                    // 航线数据
                    positions.push(position);
                }
            } else { }
        }

        return {
            position,
            positions,
            orientation,
            device
        };
    },
    Cartesian3_to_WGS84(point) {
        var cartesian33 = new Cesium.Cartesian3(point.x, point.y, point.z);
        var cartographic = Cesium.Cartographic.fromCartesian(cartesian33);
        var lat = Cesium.Math.toDegrees(cartographic.latitude);
        var lng = Cesium.Math.toDegrees(cartographic.longitude);
        var alt = cartographic.height;
        return {
            lng: lng,
            lat: lat,
            alt: alt
        };

    },

    async show_location(device) {
        viewer.trackedEntity = null
        let uav_data = await API.FCKERNEL.GetLastUavData({
            deviceHardId: device.deviceHardId
        })

        if (!uav_data) {
            this.$el_message("暂未找到位置信息", () => { }, "error")
            return uav_data
        }
        if (!data_source) {
            await this.uav_init_data_source()
        }
        let entities = data_source.entities
        let cesium_layer = this.g_cesium_layer()
        let data = this.uav_trans_location_data(device, uav_data)
        let deviceHardId = device.deviceHardId
        let model = entities.getById(`fckernel_model_${deviceHardId}`);
        this.uav.model = model
        if (!model) {
            this.uav.online[deviceHardId] = data
            this.uav.online[deviceHardId].entity_id = `fckernel_model_${deviceHardId}`
            model = this.uav.model = cesium_layer.add_model(entities, this.uav.online[deviceHardId])
        }
        let polyline = entities.getById(`fckernel_polyline_${deviceHardId}`)
        if (!polyline) {
            cesium_layer.add_polyline(entities, {
                ...data,
                entity_id: `fckernel_polyline_${data.device.deviceHardId}`,
                options: {
                    show: true
                }
            })
        }
        viewer.camera.flyTo({
            destination: model.position.getValue(Cesium.JulianDate.now()),
            maximumHeight: 100,
            complete: () => {
                viewer.trackedEntity = model
            }
        })
        model.viewFrom = new Cesium.Cartesian3(0, 0, 1000)
    },
    hide_location(device, uav_data) {
        viewer.trackedEntity = null
    },
    update_location(device, uav_data) {
        let online = this.uav.online[device.deviceHardId]
        if (online) {
            let data = this.uav_trans_mqtt_location_data({
                device
            }, uav_data)
            online.orientation = data.orientation
            online.position = data.position
            if (data.positions.length > 0) {
                online.positions.push(data.position)
            }
        }
    },

    async show_airway(device) {
        let polyline = entities.getById(`fckernel_polyline_${deviceHardId}`)
        if (!polyline) {
            cesium_layer.add_polyline(entities, {
                ...data,
                entity_id: `fckernel_polyline_${data.device.deviceHardId}`,
                options: {
                    show: true
                }
            })
        }
    },
    hide_airway(device) {
        if (!data_source) {
            return false
        }

        let entities = data_source.entities
        let entity = entities.getById(`fckernel_polyline_${device.deviceHardId}`)
        entity && (entity.polyline.show = false)
        if (device.deviceHardId) {
            try {
                window.viewer.entities.removeById(`fckernel_polyline_${device.deviceHardId}`)
            } catch (error) {
            }
        }
    },

    async show_video(device, orgName) {
        // 先清空所有无人机控制的状态
       /*  try {
            let device_list = tree2list(this.uav.list)
            device_list.forEach(item => {
                if ((item.deviceHardId !== device.deviceHardId) && item._control) {
                    item._video = false
                    this.uav_hide_control(item)
                }
            })

            this.$set(this.uav.control, "device", device)
        } catch (error) {

        } */
        // onLine
        let data = await API.FCKERNEL.GetDeviceStreamAddressByDeviceId({
            deviceHardId: device.deviceHardId,
        })
        if (!data.list) {
            if (device._video) {

                device._video = false;
            }
            return this.$message.info('暂无视频')
        } else {
            let index = this.uav.videos.findIndex(item => item && (item.deviceHardId == device.deviceHardId))
            if (index === -1) {
                //当前飞机视频未播放，找个空位
                let index1 = this.uav.videos.findIndex(item => item && (item.deviceHardId == ''))
                this.uav.videos[index1] = {
                    ...device,
                    orgName,
                    videos: data,
                }
            } else {
                //已存在
                /* this.uav.videos[index] = {
                    deviceHardId:"",
                    deviceName:"",
                    id:"",
                    videos: {}
                } */
                // this.uav_hide_video(this.uav.videos[0])
                // this.uav_show_video(device, uav_data)
            }
        }

    },
    hide_video(device) {
        let {
            deviceHardId
        } = device
        this.uav.videos.forEach((item, i) => {
            if (item.deviceHardId === deviceHardId){
                this.uav.videos[i] = {
                    deviceHardId:"",
                    deviceName:"",
                    id:"",
                    videos: {}
                }
            }
        })
        
    },

    show_control(device) {
        // 先清空所有无人机控制的状态
        let device_list = tree2list(this.uav.list)
        device_list.forEach(item => {
            if ((item.deviceHardId !== device.deviceHardId) && item._control) {
                item._control = false
                this.uav_hide_control(item)
            }
        })

        this.$set(this.uav.control, "device", device)

    },
    hide_control(device) {
        this.uav.control.device = null
        this.uav.control.device = null
        this.uav.control.data = null
        this.uav.control.battery = null
        this.uav.control.mount = null
        this.uav.control.mounts = []
        this.uav.control.mounts = []

    },
    update_control(device, uav_data) {
        let control_device = this.uav.control.device
        if (control_device && control_device.deviceHardId === device.deviceHardId) {
            this.$set(this.uav.control, "data", uav_data)
        }
    },
    update_control_battery(device, battery_data) {
        let control_device = this.uav.control.device
        if (control_device && control_device.deviceHardId === device.deviceHardId) {
            this.$set(this.uav.control, "battery", battery_data)
        }
    },
    update_channelData(device, channelData) {
        // if (this.uav.control.device.deviceHardId === device.deviceHardId) {
        this.$set(this.uav.control, "channelData", channelData)
        // }
    },
    // 无人机提示信息
    update_control_info(device, battery_data) {
        let control_device = this.uav.control.device
        if (control_device && control_device.deviceHardId === device.deviceHardId) {
            this.uav.control.info.push(battery_data)
        }
    },
    update_mount(device, data) {
        let control_device = this.uav.control.device
        if (control_device && control_device.deviceHardId === device.deviceHardId) {
            let mount = this.mount.list.find(item => item.name === data.gimbalName)
            if (mount) {
                let find_item = this.uav.control.mounts.find(item => item.name === data.gimbalName)
                if (!find_item) {
                    this.uav.control.mounts.push({
                        ...data,
                        ...mount
                    })
                }
            }
        }
    },
    change_mount(mount) {
        this.$set(this.uav.control, "mount", mount)
    },
    mount_directive(data) {
        let mount = this.uav.control.mount

        if (mount) {
            this.uav_mqtt_fn({
                type: 514,
                data: {
                    mountId: mount.mountId,
                    payload: data
                }
            })
        }
    },
    move_directive(data) {
        if (data.mountId && data.data) {
            this.uav_mqtt_fn({
                type: 514,
                data: {
                    mountId: data.mountId,
                    payload: data.data
                }
            })
        }
    },

    /**
     * 切换无人机模式
     * { type: 513, data: mode }
     * @param {*} data 
     */
    change_mode(mode) {
        this.uav_mqtt_fn({
            type: 513,
            data: mode.data
        })
    },

    update_org_status(cate, id) {
        let list = tree2list_org(this.uav.list)
        let org_id = id
        while (org_id) {
            let org = list.find(x => x.id === org_id)
            if (org) {
                if (cate === 1) {
                    org.offline -= 1;
                    org.online += 1;
                }
                if (cate === 0) {
                    org.offline += 1;
                    org.online -= 1;
                }
                org_id = org.pid
            } else {
                org_id = null
            }
        }
    },

    /**
     * cate { -1: 离线, 1: 上线 }
     * @param {*} cate 
     * @param {*} deviceHardId 
     */
    update_device_report_status(cate, deviceHardId) {
        let devices = tree2list(this.uav.list)
        let did = this.uav.control.device && this.uav.control.device.deviceHardId
        devices.map(item => {
            if (item.deviceHardId == deviceHardId) {
                if (item.reportStatus !== cate) {
                    item.reportStatus = cate
                    if (cate === 1) {
                        this.uav_update_org_status(1, item.org_id)
                    } else if (cate == 0) {
                        this.uav_update_org_status(0, item.org_id)
                        item._control = false
                        // // 视频推流状态关闭
                        // item._videoStatus = 0
                        if (did && (did == deviceHardId)) {
                            this.uav.control = {}
                        }
                    }
                }
            }
        })
    },

    /**
     * 无人机 mqtt 发送指令
     * @param {*} data 
     */
    mqtt_fn(data, type) {
        let device = this.uav.control.device
        if (device) {
            let uavCate = device.cateName == 'px4' ? 'PX4' : 'APM'
            // let uavCate = device.cateName == 'PX4'
            let topic = `${uavCate}/OBTAIN/${device.deviceHardId}`
            this.mqtt_publish(topic, data, e => {
                // console.log('发送指令', data, 'topic');
            })
        }
    },
}