<template>
    <!-- 告警弹窗 -->
    <view>
        <view class="mask" v-if="alarmModel"></view>
        <view class="alarm-modal" v-if="alarmModel">
            <view class="alarm">
                <!-- <image src="../../images/alram.png" mode="" /> -->
                <image src="../../static/alarm.png"></image>
            </view>
            <view class="alarm-header">
                <image src="../../static/alarm_event.png" mode="" />
            </view>
            <view class="nowTime">
                {{ nowTime }}
            </view>
            <view class="alarm-info">
                <text style="color: #ff6d6d">{{ devName }}</text>
                检测到可能发生跌倒事件，请立即处理！
            </view>
            <view class="backImg">
                <image src="../../static/actionRed.png" mode="" />
            </view>
            <view class="alarm-bottom">
                <template v-if="voipFlag">
                    <view
                        class="alarm-voice"
                        v-if="authorizeFlag"
                        @click="gotoCallPage"
                    >
                        语音确认
                    </view>
                    <view class="alarm-voice" v-else @click="authorizeIot">
                        语音确认
                    </view>
                </template>
                <view class="alarm-handle" @click="handleAlarm()">
                    已知晓
                </view>
            </view>
        </view>
    </view>
</template>
<script>
import config from "../../data/config.js";
import mqtt from "../../utils/mqtt";
import {
    getSnTicket,
    authorize,
    getDeviceVoIPList,
    getContactList,
    getUser,
} from "../../api/index.js";
import {
    CameraStatus,
    AuthorizeStatus,
    CallPagePlugin,
    isWmpf,
} from "../../const.js";
import { AsyncValue } from "../../utils";
const wmpfVoip = requirePlugin("wmpf-voip").default;
const envVersion = wx.getAccountInfoSync().miniProgram.envVersion;
const apiTypes = ["校园模式", "硬件模式", "呼叫安卓", "校园+硬件模式"];
const apiTypesWMPF = [1, 0, 3];
const apiTypesWechat = [2];

const getEnvVersionForVoip = (function () {
    const _map = {
        develop: "developer",
        trial: "trial",
        release: "formal",
    };
    return () => {
        return _map[envVersion];
    };
})();

export default {
    comments: {
        name: "alarModel",
    },
    props: {
        clientIdProp: {
            default: null,
        },
    },
    data() {
        return {
            alarmModel: false,
            eventListId: "",
            nowTime: "",
            devName: "",
            authorizeFlag: true,
            clientId: "",
            mqttClientTwo: "",
            // voip相关
            isWmpf: isWmpf,
            name: "用户",
            voipDevices: [],
            sn: "",
            isShowPopUp: false,
            contactList: [],
            isWmpf,
            envVersion,
            apiTypesValid: (isWmpf ? apiTypesWMPF : apiTypesWechat).map(
                (id) => apiTypes[id]
            ),
            apiTypeIndex: 0,
            currentIndex: 0,
            voipFlag: "",
            mqttClientFlag: false,
            inactivityTimer: "",
        };
    },
    computed: {},
    methods: {
        authorizeIot() {
            this.hanledList("Voice");
            this.sn = this.clientId;
            this.alarmModel = false;
            // const { name, sn, voipDevices } = this;
            const name = this.name;
            const sn = this.clientId;
            const voipDevices = this.voipDevices;
            if (!name || name.length === 0 || !sn || sn.length === 0) {
                wx.showToast({
                    title: "请输入授权人名称和设备clientId",
                    icon: "none",
                });
                return;
            }
            const { modelId } = config;
            console.log(sn, modelId, 77777);
            const { snTicket } = getSnTicket({
                sn,
                modelId,
            });
            console.log(snTicket, sn, 99999999);
            var that = this;
            wx.requestDeviceVoIP({
                sn,
                snTicket,
                modelId,
                deviceName: sn,
                async success(res) {
                    console.log(`requestDeviceVoIP`, res);
                    await authorize({
                        sn,
                        name,
                    });
                    wx.showToast({
                        title: "授权成功",
                        icon: "none",
                    });
                    const key = `voipDevices[${voipDevices.length}]`;
                    // that.setData({
                    //     [key]: {
                    //         sn,
                    //         modelId,
                    //         status: 1,
                    //     },
                    // });
                    that.voipDevices[voipDevices.length] = {
                        sn,
                        modelId,
                        status: 1,
                    };

                    that.sn = sn;
                    that.modelId = modelId;
                    that.status = 1;
                    that.gotoCallPage();
                },
                fail(err) {
                    console.error(`requestDeviceVoIP failOne`, err);
                    wx.showToast({
                        title: "授权失败, 请前往设置页开启",
                        icon: "none",
                    });
                },
            });
        },
        handleAlarm() {
            this.hanledList("noVoice");
            this.alarmModel = false;
        },
        // voip相关方法
        async getVoipDevices() {
            const { list } = await getDeviceVoIPList();
            console.log("getDeviceVoIPList:", list);
            if (list && list.length > 0) {
                const authorizeFlag = list.some(
                    (item) => item.sn === this.clientId
                );
                console.log("authorizeFlag:", list, authorizeFlag);
                this.authorizeFlag = authorizeFlag;
            }
            if (!list || list.length === 0) {
                this.authorizeFlag = false;
            }
            if (typeof list === "object") {
                this.voipDevices = list;
            }
        },
        async authorizeIot() {
            this.sn = this.clientId;
            // this.alarmModel = false;
            const name = this.name;
            const sn = this.sn;
            const voipDevices = this.voipDevices;
            console.log(name, sn, voipDevices, 9999999999999);
            // const { name, sn, voipDevices } = this;
            if (!name || name.length === 0 || !sn || sn.length === 0) {
                wx.showToast({
                    title: "请输入授权人名称和设备dev_id",
                    icon: "none",
                });
                return;
            }
            const { modelId } = config;
            console.log(sn, modelId, 77777);
            const { snTicket } = await getSnTicket({
                sn,
                modelId,
            });
            console.log(snTicket, sn, 99999999);
            var that = this;
            wx.requestDeviceVoIP({
                sn,
                snTicket,
                modelId,
                deviceName: sn,
                async success(res) {
                    console.log(`requestDeviceVoIP`, res);
                    await authorize({
                        sn,
                        name,
                    });
                    wx.showToast({
                        title: "授权成功",
                        icon: "none",
                    });
                    const key = `voipDevices[${voipDevices.length}]`;
                    // that.key = {
                    //     sn,
                    //     modelId,
                    //     status: 1,
                    // };
                    that.voipDevices[voipDevices.length] = {
                        sn,
                        modelId,
                        status: 1,
                    };
                    that.gotoCallPage();
                },
                fail(err) {
                    console.error(`requestDeviceVoIP failTwo`, err);
                    wx.showToast({
                        title: "授权失败, 请前往设置页开启",
                        icon: "none",
                    });
                },
            });
        },
        async gotoCallPage() {
            this.hanledList("Voice");
            wx.showToast({
                title: "通话加载中...",
                icon: "loading",
                duration: 2000, //持续的时间
            });
            // this.alarmModel = false;
            this._caller = new AsyncValue();
            let options = {
                sn: this.sn,
            };
            await this.getSelf(options);
            await this.getContactList();
            let voiceCan = {
                sn: this.sn,
                idx: 1,
                type: "voice",
            };
            await this.call(voiceCan);
        },
        async getSelf(options = {}) {
            if (!this._caller.isPending()) {
                return;
            }
            if (isWmpf) {
                const { sn } = options;
                if (sn) {
                    config.sn = sn;
                    this.sn = sn;
                }
                this._caller.set({
                    id: config.sn,
                    name: config.sn,
                });
            } else {
                try {
                    const resp = await getUser();
                    console.log(`getUser`, resp);
                    this._caller.set({
                        id: resp.openid,
                        name: resp.name,
                    });
                } catch (error) {
                    console.error(`getself error`, error);
                }
            }
        },
        async getContactList() {
            wx.showLoading();
            try {
                let contactList = [];
                const raw_contactList = await getContactList({
                    sn: isWmpf ? config.sn : null,
                });
                console.log(`raw_contactList`, raw_contactList);
                if (!isWmpf) {
                    // 微信呼叫设备
                    const { list } = await getDeviceVoIPList();
                    contactList = raw_contactList.map(({ sn, pushToken }) => {
                        let canCall = true;
                        if (typeof list === "object") {
                            const canCallList = list
                                .filter(
                                    (item) =>
                                        item.status === AuthorizeStatus.ACCEPT
                                )
                                .map((item) => item.sn);
                            canCall = canCallList.includes(sn);
                        }
                        return {
                            id: sn,
                            name: sn,
                            canCall,
                            ticket: pushToken,
                        };
                    });
                } else {
                    // 设备呼叫微信
                    const raw_contactList = await getContactList({
                        sn: config.sn,
                    });
                    console.log(`raw_contactList: 业务方存储`, raw_contactList);
                    if (raw_contactList.length > 0) {
                        const canCallList = (
                            await wmpfVoip.getIotBindContactList({
                                sn: config.sn,
                                model_id: config.modelId,
                                openid_list: raw_contactList.map(
                                    (item) => item.openid
                                ),
                            })
                        ).contact_list
                            .filter(
                                (item) => item.status === AuthorizeStatus.ACCEPT
                            )
                            .map((item) => item.openid);
                        console.log(`canCallList: 微信授权存储`, canCallList);
                        contactList = raw_contactList.map((item) => {
                            const canCall = canCallList.includes(item.openid);
                            return {
                                id: item.openid,
                                name: item.name,
                                canCall,
                                ticket: "",
                            };
                        });
                    }
                }
                console.log(`getContactList: `, contactList);

                this.contactList = contactList;
            } catch (error) {
                console.error(`getContactList error: `, error);
            }
            wx.hideLoading();
        },
        async call(e) {
            console.log(`call`, "走到了call方法");
            const { sn, idx, type: roomtype } = e;
            // console.log(e, this.contactList, 888870);
            const target = this.contactList.find((item) => item.id === sn);
            console.log("走到了这里了。。。。1", target);
            // const target = this.contactList[idx];
            const apiTypeName = this.apiTypesValid[this.apiTypeIndex];
            const businessType = apiTypes.indexOf(apiTypeName);
            try {
                if (!target.canCall) {
                    wx.showToast({
                        title: "用户未授权或设备不在线",
                        icon: "none",
                    });
                    throw Error("target can not call");
                }
                console.log("走到了这里了。。。。2");
                const _caller = await this._caller.get();
                console.log(`caller: `, _caller);
                console.log(`listener: `, target);
                const { roomId } = await wmpfVoip.callDevice({
                    roomType: "voice",
                    sn: sn,
                    modelId: "iFJ2BNIQcd9WlUIaT7_l4Q",
                    nickName: "xx",
                    isCloud: true,
                    payload: "radar-power.cn",
                });
                wx.redirectTo({
                    url: CallPagePlugin,
                });
            } catch (error) {
                console.log(`>>>>>>>>>>>>>>>>>>>>>>>>>>>`);
                console.error(`call error`, error);
            }
        },
        // mqtt相关方法
        connectMQTTwo() {
            // if (this.mqttClientTwo && this.mqttClientTwo.connected) {
            //     console.log("MQTT连接已存在，无需重新创建", this.mqttClientTwo);
            //     return;
            // }
            // if (this.mqttClientTwo) {
            //     try {
            //         this.mqttClientTwo.end();
            //         this.mqttClientTwo = null;
            //         console.log("清理旧MQTT连接");
            //     } catch (e) {
            //         console.error("清理连接时出错:", e);
            //     }
            // }

            if (this.mqttClientFlag) {
                console.log("主题已订阅");
                return;
            }
            const THRESHOLD = 2;
            const params = {
                keepalive: 6000,
                clean: true,
                connectTimeout: 30 * 1000,
                clientId:
                    "wx_mqtt_" + Math.random().toString(16).substring(2, 8),
                username: "admin",
                password: "public",
                // 微信小程序特定配置
                wsOptions: {
                    WebSocket: function (url) {
                        return wx.connectSocket({
                            url: url,
                            header: {
                                "content-type": "application/json",
                            },
                            protocols: ["mqtt"],
                        });
                    },
                },
                reconnectPeriod: 0,
                rejectUnauthorized: false, // 仅开发环境使用，生产环境应设为true或移除
            };
            let client = "";
            let selectedService = uni.getStorageSync("sercviceChoice");
            if (!selectedService || selectedService == "aloneServe") {
                if (__wxConfig.envVersion == "develop") {
                    client = mqtt.connect(
                        "wxs://api.radar-power.asia:8084/mqtt",
                        params
                    );
                    // client = mqtt.connect(
                    //     "wxs://radar-power.cn:8084/mqtt",
                    //     params
                    // );
                }
                if (__wxConfig.envVersion == "trial") {
                    client = mqtt.connect(
                        "wxs://radar-power.cn:8084/mqtt",
                        params
                    );
                }
            }
            // 存储client引用以便后续操作
            this.mqttClientTwo = client;
            client.on("connect", () => {
                console.log("MQTT连接成功");
                this.mqttClientFlag = true;
                let userId = uni.getStorageSync("userId");
                client.subscribe(`/mps/wx_${userId}/notice`, (err) => {
                    if (err) {
                        console.error("订阅失败", err);
                    } else {
                        console.log(
                            `成功订阅设备主题: /mps/wx_${userId}/notice`
                        );
                    }
                });
                console.log(this.clientIdProp);
                if (this.clientIdProp !== null) {
                    client.subscribe(
                        `/dev/${this.clientIdProp}/dsp_data`,
                        (err) => {
                            if (err) {
                                console.error("订阅clientId失败", err);
                            } else {
                                console.log(
                                    `成功订阅设备主题: /dev/${this.clientIdProp}/dsp_data`
                                );
                            }
                        }
                    );
                }
            });
            client.on("disconnect", () => {
                console.log("MQTT不在连接");
            });
            client.on("error", (err) => {
                this.mqttClientFlag = false;
                setTimeout(() => {
                    this.connectMQTTwo();
                }, 1000);
            });

            client.on("reconnect", () => {});

            client.on("close", () => {});

            client.on("message", (topic, message) => {
                console.log(JSON.parse(message.toString()), "8870");
                // 处理点位消息
                if (this.clientIdProp !== null) {
                    this.handleMessage(topic, message, this.clientIdProp);
                }

                let userId = uni.getStorageSync("userId");
                const noticeMatch = /^\/mps\/wx_(.+)\/notice$/;
                const match = topic.match(noticeMatch);
                if (!match) return;
                this.alarmModel = true;
                const data = JSON.parse(message.toString());
                this.clientId = data.clientId;
                this.devName = data.devName;
                this.sn = data.clientId;
                this.eventListId = data.eventListId;
                this.getVoipAuthor(this.clientId, userId);
                console.log(data, topic, "接收到消息222:");
                console.log(
                    "接收到消息:",
                    this.clientId,
                    this.devName,
                    this.sn,
                    this.eventListId,
                    data
                );
                const now = new Date();
                const year = now.getFullYear();
                const month = (now.getMonth() + 1).toString().padStart(2, "0");
                const day = now.getDate().toString().padStart(2, "0");
                const hours = now.getHours().toString().padStart(2, "0");
                const minutes = now.getMinutes().toString().padStart(2, "0");
                const formattedTime = `${year}-${month}-${day} ${hours}:${minutes}`;
                this.nowTime = formattedTime;
                console.log("isWmpf:", isWmpf);
                if (!isWmpf) {
                    console.log("isWmpf:", isWmpf);
                    this.getVoipDevices();
                }
                console.log("接收到消息:", topic, data);
            });
        },

        hanledList(type) {
            this.$http
                .get(`wap/event/handleEvent`, {
                    eventListId: this.eventListId,
                })
                .then((res) => {
                    if (res.data.code == 200) {
                        if (type === "noVoice") {
                            uni.showToast({
                                title: "已处理",
                                icon: "success",
                                duration: 1500,
                            });
                        }
                    } else {
                        uni.showToast({
                            title: "处理失败",
                            icon: "none",
                            duration: 1500,
                        });
                    }
                });
        },
        closemqtt() {
            this.mqttClientFlag = false;
            if (this.mqttClientTwo) {
                this.mqttClientTwo.end();
                this.mqttClientTwo = null;
                console.log("MQTT连接已断开");
            }
        },
        getVoipAuthor(clientId, userId) {
            console.log(clientId, userId);
            this.$http
                .post(
                    "wap/share/queryUserVoipPermission",
                    {
                        userId: userId,
                        clientId: clientId,
                    },
                    {
                        header: {
                            "Content-Type": "application/json;charset=UTF-8",
                        },
                    }
                )
                .then((res) => {
                    if (res.data.data) {
                        console.log(res.data.data, 9999);
                        if (res.data.data.voipFlag === 0) {
                            this.voipFlag = true;
                        } else {
                            this.voipFlag = false;
                        }
                    }
                });
        },

        // 处理点位消息
        handleMessage(topic, message, clientId) {
            // 清除不活动定时器
            clearTimeout(this.inactivityTimer);
            this.inactivityTimer = setTimeout(() => {
                this.targetPoints = {};
                console.log("长时间没有点位，清除数据");
                this.sendChange();
                this.$emit("sendHealth", 0);
            }, 1500);

            // 验证topic格式
            const match = topic.match(/^\/dev\/(.+)\/dsp_data$/);
            if (!match || match[1] !== clientId) return;

            try {
                const data = JSON.parse(message.toString());
                if (data.health) {
                    if (
                        data.health.breath_rpm ||
                        data.health.breath_rpm === 0
                    ) {
                        this.$emit(
                            "sendHealth",
                            Math.floor(data.health.breath_rpm)
                        );
                    } else {
                        this.$emit("sendHealth", 0);
                    }
                }
                this.processTrackerData(data.tracker_targets);
            } catch (e) {
                console.error("MQTT消息解析失败", e);
            }
        },

        processTrackerData(arr) {
            if (Array.isArray(arr) && arr.length > 0 && Array.isArray(arr[0])) {
                this.targetPoints = {};
                const currentIds = new Set();
                const newTargetPoints = {};
                // 处理每个追踪目标
                arr.forEach((item) => {
                    if (!Array.isArray(item) || item.length < 4) return;

                    const [x, y, z, id] = item;
                    currentIds.add(id.toString());

                    // 处理新点或更新现有点
                    if (!this.targetPoints[id]) {
                        newTargetPoints[id] = this.createNewTargetPoint(
                            x,
                            y,
                            z,
                            id
                        );
                    } else {
                        newTargetPoints[id] = this.updateExistingTargetPoint(
                            this.targetPoints[id],
                            x,
                            y,
                            z,
                            2
                        );
                    }
                });

                // 移除不存在的点
                Object.keys(this.targetPoints).forEach((id) => {
                    if (!currentIds.has(id)) {
                        delete this.targetPoints[id];
                    }
                });

                // 更新目标点
                this.targetPoints = {
                    ...this.targetPoints,
                    ...newTargetPoints,
                };
                if (Array.isArray(this.targetPoints)) {
                    this.targetPoints = this.targetPoints.filter(
                        (item) => item !== null && item !== undefined
                    );
                }
                console.log("当前目标点11111", this.targetPoints);
                this.sendChange();
            }
        },
        sendChange() {
            this.$emit("sendChange", this.targetPoints);
        },
        // 创建新目标点
        createNewTargetPoint(x, y, z, id) {
            return {
                x,
                y,
                z,
                id,
                displayX: x,
                displayY: y,
                lastX: x,
                lastY: y,
            };
        },
        // 更新现有目标点
        updateExistingTargetPoint(existingPoint, x, y, z, THRESHOLD) {
            const dx = x - existingPoint.lastX;
            const dy = y - existingPoint.lastY;
            const distance = Math.sqrt(dx * dx + dy * dy);

            if (distance > THRESHOLD) {
                return {
                    ...existingPoint,
                    x,
                    y,
                    z,
                    lastX: x,
                    lastY: y,
                    displayX: x,
                    displayY: y,
                };
            }

            return existingPoint;
        },
    },
    mounted() {
        this.connectMQTTwo();
    },

    beforeDestroy() {
        this.closemqtt();
    },
};
</script>

<style lang="less" scoped>
/* 弹窗部分样式 */
.mask {
    position: fixed;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.3);
    z-index: 100;
}

.alarm-modal {
    width: 675rpx;
    height: 1100rpx;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: linear-gradient(180deg, #ffdfdf 0%, #ffffff 30.3%);
    border-radius: 37rpx 37rpx;
    z-index: 103;
    padding: 50rpx 55rpx;
    box-sizing: border-box;

    .alarm-header image {
        width: 315rpx;
        height: 40rpx;
    }

    .alarm image {
        position: fixed;
        top: 0;
        right: 0;
        width: 180rpx;
        height: 175rpx;
    }

    .nowTime {
        width: 270rpx;
        margin-top: 20rpx;
        text-align: center;
        align-items: center;
        line-height: 100%;
        background: #fed5d5;
        color: #111111;
        font-size: 28rpx;
        border-radius: 10rpx;
        padding: 5rpx 5rpx;
    }

    .alarm-info {
        margin-top: 40rpx;
        color: #111111;
        font-size: 28rpx;
        letter-spacing: 4%;
    }

    .backImg {
        margin: 37rpx auto;
        width: 400rpx;
        height: 600rpx;
        background-color: #fff;
        border: 12rpx solid #333333;
        background-image: url(http://jkld.radar-power.com//uploadFiles/framework/file/20250620/toilet_bg.png);
        background-repeat: no-repeat;
        background-position: center;

        image {
            position: absolute;
            top: 50%;
            left: 50%;
            width: 60rpx;
            height: 60rpx;
        }
    }

    .alarm-bottom {
        display: flex;
        justify-content: flex-end;
        align-items: center;

        .alarm-voice {
            width: 185rpx;
            height: 85rpx;
            background: #f3e2dd;
            border-radius: 28rpx;
            color: #111111;
            font-size: 32rpx;
            text-align: center;
            line-height: 85rpx;
        }

        .alarm-handle {
            margin-left: 20rpx;
            width: 185rpx;
            height: 85rpx;
            background: linear-gradient(114.23deg, #a27867 0%, #74483d 100%);
            border-radius: 28rpx;
            box-shadow: 0rpx 4.69rpx 18.75rpx rgba(72, 41, 29, 0.15),
                0rpx 9.38rpx 9.38rpx rgba(154, 132, 89, 0.2),
                0rpx -4.69rpx 28.13rpx 4.69rpx #a16647 inset;
            color: #ffffff;
            font-size: 32rpx;
            text-align: center;
            line-height: 85rpx;
        }
    }
}
</style>
