package com.example.iot_controlhost.utils.network;

import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.StringUtils;
import com.example.iot_controlhost.model.controller.AirConditionInfrared;
import com.example.iot_controlhost.model.sensor.GasSensor;
import com.example.iot_controlhost.model.sensor.Sensor;
import com.example.iot_controlhost.model.sensor.SensorInfo;
import com.example.iot_controlhost.model.thread.QueueIOTask;
import com.example.iot_controlhost.service.MQTTService;
import com.example.iot_controlhost.utils.AppUpdateUtil;
import com.example.iot_controlhost.utils.FrpUpdateUtil;
import com.example.iot_controlhost.utils.MMKVUtil;
import com.example.iot_controlhost.utils.MyQueue;
import com.example.iot_controlhost.utils.MyUtil;
import com.example.iot_controlhost.utils.control.RemoteControl;
import com.example.iot_controlhost.utils.control.infrared.MyInfraredUtils;
import com.example.iot_controlhost.utils.control.ventilator.VentilatorController;
import com.example.iot_controlhost.utils.global.AIModelSet;
import com.example.iot_controlhost.utils.global.AutoModelSet;
import com.example.iot_controlhost.utils.global.HardwareSetting;
import com.example.iot_controlhost.utils.global.RoomController;
import com.example.iot_controlhost.utils.global.RoomSensor;
import com.example.iot_controlhost.utils.global.RoomSetting;
import com.example.iot_controlhost.utils.global.RxTag;
import com.example.iot_controlhost.utils.log.MyLog;
import com.example.iot_controlhost.utils.log.UserLog;
import com.example.iot_controlhost.utils.old.OldSet;
import com.xuexiang.rxutil2.rxbus.RxBusUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * MQTT 主题
 */
public class TopicClass {
    /**
     * 临时变量，用于判断是否需要上传数据
     */
    private static String energyDataTemp = "";
    private static String areaDataTemp = "";
    private static String sensorDataTemp = "";
    private static String sensorInfoDataTemp = "";
    private static final int MAX_PENDING_LOGS = 200;
    private static final Queue<PendingLog> PENDING_LOGS = new ConcurrentLinkedQueue<>();

    //————————————————————————————————————————————————————————————————————————————————获取区域集合————————————————————————————————————————————————————————————————

    /**
     * 获取区域集合-发布
     */
    public static String arealistTopic() {
        return "arealist/" + HardwareSetting.getHostId() + "/get";
    }

    /**
     * 获取区域集合-发布
     */
    public static void getAreaList() {
        MQTTService.publish(arealistTopic(), "{\"code\": \"0\"}");
    }

    /**
     * 获取区域集合-订阅
     */
    public static String arealistGet() {
        return "arealist/" + HardwareSetting.getHostId() + "/get_reply";
    }

    /**
     * 获取区域集合-订阅数据解析
     */
    public static void handleAreaListMessage(String message) throws JSONException {
        MyLog.network("MQTT接收到'区域数据'消息");
        JSONObject json = new JSONObject(message);
        JSONArray jsons = json.getJSONArray("areas");
        boolean canUse = false;
        if (jsons.length() != 0) {
            //虽然可能有多个区域，但以可用的最后一个区域为主（因本系统设计初衷只服务于单个区域）
            for (int i = 0; i < jsons.length(); i++) {
                JSONObject jsonObject = jsons.getJSONObject(i);
                String code = jsonObject.getString("code");
                String name = jsonObject.getString("name");
                MMKVUtil.put(RoomSetting.ROOM_NAME, name);
                MMKVUtil.put(RoomSetting.AREA_CODE, code);
                //修改为可用
                canUse = true;
            }
        }
        RoomSetting.setRoomEnable(canUse);
        RxBusUtils.get().post(RxTag.UPDATE_MAIN, 1);
    }

    //————————————————————————————————————————————————————————————————————————————————获取主机基础信息————————————————————————————————————————————————————————————————

    /**
     * 获取主机基础信息-订阅
     */
    public static String hostbaseinfoGet() {
        return "hostbaseinfo/" + HardwareSetting.getHostId() + "/get_reply";
    }

    //————————————————————————————————————————————————————————————————————————————————数据透传————————————————————————————————————————————————————————————————

    /**
     * 数据透传-发布
     */
    public static String serianetTopic() {
        return "serianet/" + HardwareSetting.getHostId() + "/release";
    }

    /**
     * 数据透传 数据接收成功
     * 原样返回
     */
    public static void receiveSuccess(String json) {
        MQTTService.publish(serianetTopic(), json);
    }

    /**
     * 数据透传-订阅
     */
    public static String serianetGet() {
        return "serianet/" + HardwareSetting.getHostId() + "/excute";
    }

    /**
     * 数据透传-订阅解析数据
     */
    public static void hanldeSerianetMessage(String msg) {
        String tip = null;
        boolean actionLogged = false;
        switch (msg) {
            case "重启" -> {
                tip = "重启设备";
                MyUtil.reboot("远程控制");
                actionLogged = true;
            }
            case "关机" -> {
                tip = "关闭设备";
                MyUtil.shutDown("远程控制");
                actionLogged = true;
            }
            case "重启软件" -> {
                tip = "重启软件";
                MyUtil.relaunchApp("远程控制");
                actionLogged = true;
            }
            case "更新" -> {
                tip = "强制更新软件";
                AppUpdateUtil.updateAPP(ActivityUtils.getTopActivity(), true, true);
            }
            case "下载frp" -> {
                tip = "更新远程控制软件";
                FrpUpdateUtil.check(ActivityUtils.getTopActivity(), true);
            }
            case "检测更新" -> {
                tip = "检测软件更新";
                AppUpdateUtil.updateAPP(ActivityUtils.getTopActivity(), false, false);
            }
        }
        if (!StringUtils.isEmpty(tip)) {
            TopicClass.receiveSuccess(msg);
            if (!actionLogged) {
                UserLog.operate("远程控制", tip);
            }
        }
    }

    //————————————————————————————————————————————————————————————————————————————————区域环境控制指令————————————————————————————————————————————————————————————————

    /**
     * 区域环境控制指令-订阅
     */
    public static String areaenvcontrolGet() {
        return "areaenvcontrol/" + HardwareSetting.getHostId() + "/set";
    }

    /**
     * 区域环境控制指令-订阅数据解析
     *
     * @param msg 数据
     */
    public static void handleUploadControlMessage(String msg) {
        try {
            JSONObject json = new JSONObject(msg);
            String areaenvcontrolcommand = json.getString("areaenvcontrolcommand");
            JSONObject jsons = new JSONObject(areaenvcontrolcommand);
            //区域唯一码RoomId
            String code = jsons.getString("code");
            // 增加功能：如果不是当前区域或者当前区域不可用，则不执行远程控制指令
            if (!RoomSetting.getAreaCode().equals(code) && !RoomSetting.isRoomEnable()) {
                return;
            }
            int controlCommand = jsons.getInt("controlcommand");
            int gear = jsons.getInt("gear");
            int value = jsons.getInt("value");
            //如果运行成功，则立即反馈
            uploadControl(jsons);
            MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> {
                boolean operateSuccess = RemoteControl.remoteControl(controlCommand, gear, value);
                if (operateSuccess) {
                    String commandName = getCommandNameById(controlCommand, value);
                    if (controlCommand != 8) {
                        UserLog.operate("远程控制", "设备操作成功：" + commandName);
                    }
                    //设置完远程控制后 上传最新当前状态
                    if (controlCommand == 8) {
                        // 如果是切换模式，为优化速度，直接上传最新的模式，不等转换完成，
                        uploadDeviceState(true, value);
                    } else {
                        uploadDeviceState(true);//设置完远程控制后 上传最新当前状态
                    }
                } else {
                    String commandName = getCommandNameById(controlCommand, value);
                    UserLog.operateError("远程控制", controlCommand == 8 ? "模式切换失败" : "设备操作失败：" + commandName);
                    MyLog.remoteError("远程操作失败：" + commandName + "，指令=" + controlCommand + "，值=" + value);
                }
                //更新手动模式下设备UI
                RxBusUtils.get().post(RxTag.UPDATE_MANUAL, 0);
            }));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private static String getCommandNameById(int controlCommand, int value) {
        switch (controlCommand) {
            case 0:
                return "开始升温";
            case 1:
                return "停止升温";
            case 3:
                return "停止降温";
            case 2:
                return "开始降温";
            case 4:
                return "开始加湿";
            case 5:
                return "停止加湿";
            case 6:
                return "开始换气";
            case 7:
                return "停止换气";
            case 8:
                //切换模式 需要指定具体值
                int newMode = OldSet.oldModeToNewMode(value);
                return "切换模式:" + MyUtil.getModeName(newMode);
            case 9:
                return "开始匀风";
            case 10:
                return "停止匀风";
            case 11:
                return "开启灯光";
            case 12:
                return "关闭灯光";
        }
        return null;
    }

    /**
     * 区域环境控制指令-发布
     */
    public static String areaenvcontrolPost() {
        return "areaenvcontrol/" + HardwareSetting.getHostId() + "/post";
    }

    /**
     * 区域环境控制指令-发布
     */
    public static void uploadControl(JSONObject jsons) {
        MyLog.remote("发送区域环境控制指令操作成功反馈消息");
        try {
            JSONObject json = new JSONObject();
            json.put("code", jsons.getString("code"));
            json.put("uniquecode", jsons.getString("uniquecode"));
            json.put("reason", 0);
            json.put("controlcommand", jsons.getString("controlcommand"));
            json.put("value", jsons.getString("value"));
            json.put("datetime", MyUtil.getDateTime());
            json.put("gear", RoomController.floor.getGear());

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("areaenvcontrolcommandresult", json);
            MQTTService.publish(areaenvcontrolPost(), jsonObject.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    //————————————————————————————————————————————————————————————————————————————————设备运行日志上传————————————————————————————————————————————————————————————————

    /**
     * 设备运行日志-上传
     */
    public static String DeviceRunLogsPost() {
        return "DeviceRunLogs/" + HardwareSetting.getHostId() + "/release";
    }

    /**
     * 上传日志到服务器
     */
    public static void uploadLog(int tag, int priority, String message) {
        uploadLog(tag, priority, message, new Date());
    }

    public static void uploadLog(int tag, int priority, String message, Date datetime) {
        PendingLog pendingLog = new PendingLog(tag, priority, message, datetime);
        if (!MQTTService.getMQTTConnect()) {
            while (PENDING_LOGS.size() >= MAX_PENDING_LOGS) {
                PENDING_LOGS.poll();
            }
            PENDING_LOGS.offer(pendingLog);
            MyLog.network("用户日志等待MQTT连接后上传：类型=" + tag + "，级别=" + priority
                    + "，待上传=" + PENDING_LOGS.size() + "条");
            return;
        }
        publishLog(pendingLog);
    }

    private static void publishLog(PendingLog pendingLog) {
        JSONObject json = new JSONObject();
        try {
            json.put("areacode", RoomSetting.getAreaCode());
            json.put("tage", pendingLog.tag);
            json.put("msglevel", pendingLog.priority);
            json.put("msg", pendingLog.message);
            json.put("datetime", MyUtil.getDateTime(pendingLog.datetime));
            MQTTService.publish(DeviceRunLogsPost(), json.toString());
        } catch (JSONException e) {
            MyLog.networkError("用户日志序列化失败：类型=" + pendingLog.tag + "，原因=" + e.getMessage());
        }
    }

    public static void flushPendingLogs() {
        int count = 0;
        PendingLog pendingLog;
        while (MQTTService.getMQTTConnect() && (pendingLog = PENDING_LOGS.poll()) != null) {
            publishLog(pendingLog);
            count++;
        }
        if (count > 0) {
            MyLog.network("MQTT连接恢复，已补传本次进程缓存的用户日志" + count + "条");
        }
    }

    private static final class PendingLog {
        private final int tag;
        private final int priority;
        private final String message;
        private final Date datetime;

        private PendingLog(int tag, int priority, String message, Date datetime) {
            this.tag = tag;
            this.priority = priority;
            this.message = message;
            this.datetime = datetime;
        }
    }

    /**
     * 设备运行日志-订阅
     */
    public static String DeviceRunLogsGet() {
        return "DeviceRunLogs/" + HardwareSetting.getHostId() + "/excute";
    }

    //————————————————————————————————————————————————————————————————————————————————区域环境控制状态上报————————————————————————————————————————————————————————————————

    /**
     * 区域环境控制状态上报
     */
    public static String areaenvcontrolstatusTopic() {
        return "areaenvcontrolstatus/" + HardwareSetting.getHostId() + "/post";
    }

    private static String runningStateTemp = "";

    /**
     *
     * @param needForceUpload 是否需要无视重复消息 直接上传
     * @param targetMode 目标模式 如果不为-1，则直接使用该模式 如果为-1，则使用当前模式  目的是为了能快速返回服务器切换后的状态
     */
    public static void uploadDeviceState(boolean needForceUpload, int targetMode) {
        // 上传最新的温湿度、换气、当前模式等状态
        uploadRunningState(needForceUpload, targetMode);
        // 上传最新的目标温湿度、预警阈值等信息
        areaDataUpload(0, needForceUpload);
    }

    public static void uploadDeviceState(boolean needForceUpload) {
        uploadDeviceState(needForceUpload, -1);
    }

    /**
     * 区域-环境控制状态-上报
     */
    public static void uploadRunningState(Boolean needForceUpload, int targetMode) {
        JSONObject jsonObject = new JSONObject();
        JSONArray areadata = new JSONArray();
        try {
            JSONObject json = new JSONObject();
            json.put("code", RoomSetting.getAreaCode());
            //温度控制状态：  0无 1升温中 2降温中
            int tempstatus;
            if (RoomController.floor.isPowerSupply()
                    || (MyInfraredUtils.getInstances().isPowerSupply() && MyInfraredUtils.getInstances().getMode() == AirConditionInfrared.HEAT)) {
                tempstatus = 1;
            } else if (MyInfraredUtils.getInstances().isPowerSupply() && MyInfraredUtils.getInstances().getMode() == AirConditionInfrared.COLD) {
                tempstatus = 2;
            } else {
                tempstatus = 0;
            }
            json.put("tempstatus", tempstatus);
            //地暖控制状态：0关闭，1-5档
            json.put("gear", RoomController.floor.getGear());
            //湿度控制状态：0关闭 3加湿
            json.put("humistatus", RoomController.humidifier.isPowerSupply() ? 3 : 0);
            //换气控制状态：0关闭 4换气 5匀风
            int ventstatus;
            if (RoomController.fan.isPowerSupply()) {
                ventstatus = 4;
            } else if (RoomController.evenFan.isPowerSupply()) {
                ventstatus = 5;
            } else {
                ventstatus = 0;
            }
            json.put("ventstatus", ventstatus);
            //全局控制模式：1智能，2自动，3手动
            int curMode = RoomSetting.getMode();
            json.put("YXMS", targetMode == -1 ? OldSet.newModeToOldMode(curMode) : targetMode);
            areadata.put(json);
            jsonObject.put("areaenvcontrolstatus", areadata);
            if (needForceUpload || !runningStateTemp.equals(jsonObject.toString())) {
                // 需要强制发送设备状态信息（不理会日志重复）   或者   设备状态信息有变化（每十秒自动发送时）
                MQTTService.publish(areaenvcontrolstatusTopic(), jsonObject.toString());
                runningStateTemp = jsonObject.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //————————————————————————————————————————————————————————————————————————————————区域能耗上报————————————————————————————————————————————————————————————————

    /**
     * 区域能耗上报
     */
    public static String areaenergydataTopic() {
        return "areaenergydata/" + HardwareSetting.getHostId() + "/post";
    }


    /**
     * 区域-能耗-上报
     */
    public static void areaEnergyData() {
        double value = RoomSensor.consumptionSensor.getEnergyConsumption();
        if (value != 0) {
            //获取当前时间戳
            JSONObject jsonObject = new JSONObject();
            JSONArray areaData = new JSONArray();
            try {
                if (RoomSensor.consumptionSensor.isAvailable()) {
                    JSONObject json = new JSONObject();
                    json.put("code", RoomSetting.getAreaCode());
                    json.put("date", MyUtil.getDateDay());
                    json.put("value", RoomSensor.consumptionSensor.getEnergyConsumption());
                    areaData.put(json);
                    jsonObject.put("areadata", areaData);
                    if (!energyDataTemp.equals(jsonObject.toString())) {
                        MQTTService.publish(areaenergydataTopic(), jsonObject.toString());
                        energyDataTemp = jsonObject.toString();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    //————————————————————————————————————————————————————————————————————————————————区域数据上报————————————————————————————————————————————————————————————————

    /**
     * 区域数据上报
     */
    public static String areadataTopic() {
        return "areadata/" + HardwareSetting.getHostId() + "/post";
    }


    /**
     * 区域-环境数据-上报
     */
    public static void uploadSensorData() {
        try {
            JSONArray areaData = new JSONArray();
            JSONObject jsonObject = new JSONObject();
            JSONArray sensordata = new JSONArray();
            JSONObject json = new JSONObject();
            json.put("code", RoomSetting.getAreaCode());
            JSONObject item = new JSONObject();
            item.put("type", 1);
            item.put("value", RoomSensor.getAverageIndoorTemperature());
            sensordata.put(item);
            item = new JSONObject();
            item.put("type", 2);
            item.put("value", RoomSensor.getAverageIndoorHumidity());
            sensordata.put(item);
            //电压、电流、功率
            if (RoomSensor.consumptionSensor.isAvailable()) {
                item = new JSONObject();
                item.put("type", 9);
                item.put("value", RoomSensor.consumptionSensor.getVoltage());
                sensordata.put(item);
                item = new JSONObject();
                item.put("type", 10);
                item.put("value", RoomSensor.consumptionSensor.getCurrent());
                sensordata.put(item);
                item = new JSONObject();
                item.put("type", 11);
                item.put("value", RoomSensor.consumptionSensor.getPower());
                sensordata.put(item);
            }
            //地面
            if (!RoomSensor.dynamicFloorTSensorList.isEmpty()) {
                item = new JSONObject();
                item.put("type", 12);
                item.put("value", RoomSensor.getFloorTemperature());
                sensordata.put(item);
            }
            //室外
            if (RoomSensor.outdoorTHSensor.isAvailable()) {
                item = new JSONObject();
                item.put("type", 13);
                item.put("value", RoomSensor.outdoorTHSensor.temperature);
                sensordata.put(item);
                item = new JSONObject();
                item.put("type", 14);
                item.put("value", RoomSensor.outdoorTHSensor.humidity);
                sensordata.put(item);
            }
            //二氧化碳
            if (!RoomSensor.dynamicCO2SensorList.isEmpty()) {
                double co2 = 0;
                double temperature = 0;
                double humidity = 0;
                for (GasSensor sensor : RoomSensor.dynamicCO2SensorList) {
                    co2 += sensor.getValue();
                    temperature += sensor.getTemperature();
                    humidity += sensor.getHumidity();
                }
                int size = RoomSensor.dynamicCO2SensorList.size();
                co2 = co2 / size;
                temperature = temperature / size;
                humidity = humidity / size;
                item = new JSONObject();
                item.put("type", 5);
                item.put("value", co2);
                sensordata.put(item);
                item = new JSONObject();
                item.put("type", 15);
                item.put("value", temperature);
                sensordata.put(item);
                item = new JSONObject();
                item.put("type", 16);
                item.put("value", humidity);
                sensordata.put(item);
            }
            json.put("sensordata", sensordata);
            areaData.put(json);
            jsonObject.put("areadata", areaData);
            if (!sensorDataTemp.equals(jsonObject.toString())) {
                MQTTService.publish(areadataTopic(), jsonObject.toString());
                sensorDataTemp = jsonObject.toString();
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    //————————————————————————————————————————————————————————————————————————————————区域环境运行模式————————————————————————————————————————————————————————————————

    /**
     * 区域环境运行模式-接收
     */
    public static String arearunmodelGet() {
        return "arearunmodel/" + HardwareSetting.getHostId() + "/set";
    }

    /**
     * 区域环境运行模式接收(远程设定运行温度湿度等值)
     */
    public static void handleAreaRunModelMessage(String msg) throws JSONException {
        MyLog.network("MQTT接收到'区域环境运行模式'消息");
        JSONObject json = new JSONObject(msg);
        JSONArray areaRunModel = json.getJSONArray("arearunmodel");
        String ss = areaRunModel.getString(0);
        JSONObject jsons = new JSONObject(ss);
        //唯一区域码 之前通过唯一区域码获得索引，现在就一个房间，所以不需要
        String code = jsons.getString("code");
        if (RoomSetting.getAreaCode().equals(code)) {
            String oldProgram = AIModelSet.getAiSchemeName();
            double oldTempMax = AutoModelSet.getMaxTemperature();
            double oldTempMin = AutoModelSet.getMinTemperature();
            double oldHumidityMax = AutoModelSet.getMaxHumidity();
            double oldHumidityMin = AutoModelSet.getMinHumidity();
            boolean oldAutoTemperature = AutoModelSet.isAutoTemperature();
            double oldTargetTemperature = AutoModelSet.getTargetTemperature();
            boolean oldAutoHumidity = AutoModelSet.isAutoHumidity();
            double oldTargetHumidity = AutoModelSet.getTargetHumidity();
            boolean oldAutoVentilator = AutoModelSet.isAutoVentilator();
            int oldVentilatorOpen = AutoModelSet.getCycleStart();
            int oldVentilatorClose = AutoModelSet.getCycleStop();
            //预警值
            MMKVUtil.put(AIModelSet.AI_SCHEME_NAME, jsons.getString("autocontrolprogram"));
            MMKVUtil.put(AutoModelSet.MAX_TEMPERATURE, jsons.getDouble("tempmaxwarning"));
            MMKVUtil.put(AutoModelSet.MIN_TEMPERATURE, jsons.getDouble("tempminwarning"));
            MMKVUtil.put(AutoModelSet.MAX_HUMIDITY, jsons.getDouble("humimaxwarning"));
            MMKVUtil.put(AutoModelSet.MIN_HUMIDITY, jsons.getDouble("humiminwarning"));
            //温度
            MMKVUtil.put(AutoModelSet.AUTO_TEMPERATURE, jsons.getInt("autotemp") != 0);
            double targetTemperature = jsons.getDouble("autotempvalue");
            MMKVUtil.put(AutoModelSet.TARGET_TEMPERATURE, targetTemperature);
            //自动根据目标值匹配最大最小值
//            if (targetTemperature != AutoModelSet.getTargetTemperature()) {
//                //新需求：如果远程设置温度有变化，则同时改变最高温度和最低温度
//                double delta = targetTemperature - AutoModelSet.getTargetTemperature() ;
//                double[] minTargetMax = MyUtil.getTHMinMax(AutoModelSet.getTargetTemperature(), delta, AutoModelSet.getMaxTemperature(), AutoModelSet.getMinTemperature(), 0);
//                MMKVUtil.put(AutoModelSet.MAX_TEMPERATURE, minTargetMax[2]);
//                MMKVUtil.put(AutoModelSet.MIN_TEMPERATURE, minTargetMax[0]);
//                MMKVUtil.put(AutoModelSet.TARGET_TEMPERATURE, minTargetMax[1]);
//            }
            //湿度
            MMKVUtil.put(AutoModelSet.AUTO_HUMIDITY, jsons.getInt("autohumi") != 0);
            double targetHumidity = jsons.getDouble("autohumivalue");
            MMKVUtil.put(AutoModelSet.TARGET_HUMIDITY, targetHumidity);
            //自动根据目标值匹配最大最小值
//            if (targetHumidity != AutoModelSet.getTargetHumidity()) {
//                //新需求：如果远程设置湿度有变化，则同时改变最高湿度和最低湿度
//                double delta = targetHumidity - AutoModelSet.getTargetHumidity();
//                double[] minTargetMax = MyUtil.getTHMinMax(AutoModelSet.getTargetHumidity(), delta, AutoModelSet.getMaxHumidity(), AutoModelSet.getMinHumidity(), 1);
//                MMKVUtil.put(AutoModelSet.MIN_HUMIDITY, minTargetMax[0]);
//                MMKVUtil.put(AutoModelSet.TARGET_HUMIDITY, minTargetMax[1]);
//                MMKVUtil.put(AutoModelSet.MAX_HUMIDITY, minTargetMax[2]);
//            }
            //换气
            MMKVUtil.put(AutoModelSet.AUTO_VENTILATOR, jsons.getInt("autovent") != 0);
            MMKVUtil.put(AutoModelSet.CYCLE_START, jsons.getInt("autoventopenvalue"));
            MMKVUtil.put(AutoModelSet.CYCLE_STOP, jsons.getInt("autoventclosevalue"));
            boolean ventilatorRuleChanged = oldAutoVentilator != AutoModelSet.isAutoVentilator()
                    || oldVentilatorOpen != AutoModelSet.getCycleStart()
                    || oldVentilatorClose != AutoModelSet.getCycleStop();

            //2025年5月7日：取消以下逻辑
//            //切换为自动模式
//            RxBusUtils.get().post(RxTag.UPDATE_MAIN, 3);
            String changeSummary = "自动模式参数更新：方案=" + oldProgram + " → " + AIModelSet.getAiSchemeName()
                    + "；温控启用=" + oldAutoTemperature + " → " + AutoModelSet.isAutoTemperature()
                    + "，目标=" + oldTargetTemperature + " → " + AutoModelSet.getTargetTemperature() + "℃"
                    + "，区间=" + oldTempMin + "~" + oldTempMax + " → "
                    + AutoModelSet.getMinTemperature() + "~" + AutoModelSet.getMaxTemperature() + "℃"
                    + "；湿控启用=" + oldAutoHumidity + " → " + AutoModelSet.isAutoHumidity()
                    + "，目标=" + oldTargetHumidity + " → " + AutoModelSet.getTargetHumidity() + "%"
                    + "，区间=" + oldHumidityMin + "~" + oldHumidityMax + " → "
                    + AutoModelSet.getMinHumidity() + "~" + AutoModelSet.getMaxHumidity() + "%"
                    + "；换气启用=" + oldAutoVentilator + " → " + AutoModelSet.isAutoVentilator()
                    + "，开启=" + oldVentilatorOpen + " → " + AutoModelSet.getCycleStart() + "分钟"
                    + "，关闭=" + oldVentilatorClose + " → " + AutoModelSet.getCycleStop() + "分钟";
            UserLog.operate("远程控制", changeSummary);
            MyLog.remote(changeSummary + "，区域码=" + code);
            if (RoomSetting.getMode() == 1) {
                if (ventilatorRuleChanged) {
                    // 控制逻辑直接响应远程参数，不依赖自动模式页面及其Presenter是否存活。
                    VentilatorController.getInstance().reloadSchedule("远程控制");
                }
                // 如果是自动模式，则刷新自动模式参数
                RxBusUtils.get().post(RxTag.UPDATE_AUTO, 3);
            }

            uploadDeviceState(true);//设置完成自动模式参数后 上传最新当前状态
        }
    }

    /**
     * 区域环境运行模式-上报
     */
    public static String arearunmodel() {
        return "arearunmodel/" + HardwareSetting.getHostId() + "/post";
    }

    /**
     * 区域-运行模式-上报
     *
     * @param reason 触发类型，1代表本地触发，0代表远程触发
     */
    public static void areaDataUpload(int reason, boolean needForceUpload) {
//        MyLog.app("上报设备运行状态");
        JSONObject jsonObject = new JSONObject();
        JSONArray areadata = new JSONArray();
        try {
            JSONObject json = new JSONObject();
            json.put("code", RoomSetting.getAreaCode());
            json.put("reason", reason);
//            json.put("autocontrolprogram", MMKVUtil.get(AIModelSet.AI_SCHEME_NAME));
            //温度
            json.put("autotemp", AutoModelSet.isAutoTemperature() ? 1 : 0);
            json.put("autotempvalue", AutoModelSet.getTargetTemperature());
            //湿度
            json.put("autohumi", AutoModelSet.isAutoHumidity() ? 1 : 0);
            json.put("autohumivalue", AutoModelSet.getTargetHumidity());
            //换气扇
            json.put("autovent", AutoModelSet.isAutoVentilator() ? 1 : 0);
            json.put("autoventopenvalue", AutoModelSet.getCycleStart());
            json.put("autoventclosevalue", AutoModelSet.getCycleStop());
            //预警
            json.put("tempminwarning", AutoModelSet.getMinTemperature());
            json.put("tempmaxwarning", AutoModelSet.getMaxTemperature());
            json.put("humiminwarning", AutoModelSet.getMinHumidity());
            json.put("humimaxwarning", AutoModelSet.getMaxHumidity());
            areadata.put(json);
            jsonObject.put("areas", areadata);
            if (needForceUpload || !areaDataTemp.equals(jsonObject.toString())) {
                MQTTService.publish(arearunmodel(), jsonObject.toString());
                areaDataTemp = jsonObject.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //————————————————————————————————————————————————————————————————————————————————上传自定义数据（传感器数据）———————————————————————————————————————————————————————

    /**
     * 上传自定义数据（传感器数据）-发布
     */
    public static String areaCustomDataTopic() {
        return "area_custom_cache/" + HardwareSetting.getHostId() + "/release";
    }

    /**
     * 上传自定义数据（传感器数据）-发布
     */
    public static void uploadAreaCustomData() {
        JSONObject json = new JSONObject();
        try {
            json.put("code", RoomSetting.getAreaCode());
            List<SensorInfo> infoList = new ArrayList<>();
            // 所有温湿度传感器的数值
            for (Sensor sensor : RoomSensor.getAllAvailableSensors()) {
                infoList.add(new SensorInfo(sensor.getName(), sensor.toString()));
            }
            json.put("data", GsonUtils.toJson(infoList));
            if (!sensorInfoDataTemp.equals(json.toString())) {
                MQTTService.publish(areaCustomDataTopic(), json.toString());
                sensorInfoDataTemp = json.toString();
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


    //————————————————————————————————————————————————————————————————————————————————工具方法————————————————————————————————————————————————————————————————
    public static void refreshCatch() {
        energyDataTemp = "";
        areaDataTemp = "";
        sensorDataTemp = "";
        sensorInfoDataTemp = "";
    }
}
