package com.example.iot_controlhost.utils.control.humidity;

import com.example.iot_controlhost.model.thread.QueueIOTask;
import com.example.iot_controlhost.model.controller.Controller;
import com.example.iot_controlhost.model.controller.Dehumidifier485;
import com.example.iot_controlhost.utils.MyQueue;
import com.example.iot_controlhost.utils.MyUtil;
import com.example.iot_controlhost.utils.control.Control;
import com.example.iot_controlhost.utils.global.AIModelSet;
import com.example.iot_controlhost.utils.global.AutoModelSet;
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.global.SpinnerList;
import com.example.iot_controlhost.utils.global.Variable;
import com.example.iot_controlhost.utils.log.MyLog;
import com.example.iot_controlhost.utils.log.UserLog;

/**
 * @Description 自动模式-控制逻辑-湿度
 * @Author DuanKaiji
 * @CreateTime 2023年11月09日 10:25:43
 */
public class HumidityController extends Control {
    /**
     * 是否需要开启加湿器直到达到目标湿度
     */
    private static boolean needOpenToTarget = false;
    private static boolean needDehumidifyToTarget = false;
    private Boolean lastHumidifierTarget;
    private Boolean lastDehumidifierTarget;
    private boolean invalidHumidityLogged;
    /**
     * 目标湿度
     */
    double target = 50;
    private static HumidityController instance;

    public static HumidityController getInstance() {
        if (instance == null) {
            synchronized (HumidityController.class) {
                if (instance == null) {
                    instance = new HumidityController();
                }
            }
        }
        return instance;
    }

    @Override
    protected boolean startMethod() {
        if (!RoomController.humidifier.isAvailable() && RoomController.getAutoDehumidifier() == null) {
            MyLog.autoError("加湿器不可用，无法自动控制");
            return false;
        }
        pollingTask.startPollingTaskOnIOThread(RxTag.AUTO_HUMIDITY, Variable.AUTO_CHECK_TIME, () -> {
            // 常规控制使用校准后的湿度；校准前湿度仅用于接近饱和时的加湿安全保护。
            double beforeCalibratedHumidity = RoomSensor.getBeforeCalibratedIndoorHumidity();
            double calibratedHumidity = RoomSensor.getAverageIndoorHumidity();
            if (calibratedHumidity <= 0) {
                MyLog.autoError("湿度自动控制跳过：没有有效湿度，校准前湿度="
                        + beforeCalibratedHumidity + "%");
                if (!invalidHumidityLogged) {
                    UserLog.systemError("自动控制", "湿度数据无效，已停止加湿以避免持续运行");
                    invalidHumidityLogged = true;
                }
                needOpenToTarget = false;
                if (RoomController.humidifier.isAvailable() && RoomController.humidifier.isPowerSupply()) {
                    MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() ->
                            MyUtil.autoControlOperateThird(RoomController.humidifier, false)));
                }
                return;
            }
            invalidHumidityLogged = false;
            double min = 0;
            double max = 0;
            if (RoomSetting.getMode() == 1) {
                target = AutoModelSet.getTargetHumidity();
                min = AutoModelSet.getMinHumidity();
                max = AutoModelSet.getMaxHumidity();
            } else if (RoomSetting.getMode() == 2) {
                target = AIModelSet.getTargetHumidity();
                min = target - Variable.AUTO_DO_NOTHING_HUMIDITY;
                max = target + Variable.AUTO_DO_NOTHING_HUMIDITY;
            }
            boolean needHumidify = false;
            boolean needDehumidify = false;
            if (calibratedHumidity < min //当前小于用户规定最小湿度
                    || calibratedHumidity < target - Variable.AUTO_DO_NOTHING_HUMIDITY //小于系统要求最小湿度
                    || calibratedHumidity < target && needOpenToTarget) { // 需要急剧加湿到目标湿度
                needOpenToTarget = true;
                needHumidify = true;
            } else {
                needOpenToTarget = false;
                needHumidify = false;
            }

            // 除湿逻辑（新增）
            if (calibratedHumidity > max || calibratedHumidity > target && needDehumidifyToTarget) {
                needDehumidifyToTarget = true;
                needDehumidify = true;
            } else {
                needDehumidifyToTarget = false;
                needDehumidify = false;
            }
            // 校准前湿度已接近100%时，即使校准后湿度较低，也绝不继续加湿。
            if (beforeCalibratedHumidity >= 99) {
                needHumidify = false;
                needOpenToTarget = false;
            }

            // === 互斥处理 ===
            if (needHumidify && needDehumidify) {
                // 理论不会发生，保险处理
                needDehumidify = false;
                needDehumidifyToTarget = false;
            }
            boolean humidifierState = needHumidify;
            boolean dehumidifierState = needDehumidify;
            if (lastHumidifierTarget == null || lastHumidifierTarget != humidifierState) {
                MyLog.auto("湿度控制决策变化：加湿器=" + formatState(lastHumidifierTarget) + "→"
                        + formatState(humidifierState) + "，校准前湿度=" + beforeCalibratedHumidity + "%"
                        + "，校准后湿度=" + calibratedHumidity + "% ，目标=" + target + "% ，区间=" + min + "~" + max + "%");
                lastHumidifierTarget = humidifierState;
            }
            if (lastDehumidifierTarget == null || lastDehumidifierTarget != dehumidifierState) {
                MyLog.auto("湿度控制决策变化：除湿机=" + formatState(lastDehumidifierTarget) + "→"
                        + formatState(dehumidifierState) + "，校准前湿度=" + beforeCalibratedHumidity + "%"
                        + "，校准后湿度=" + calibratedHumidity + "% ，目标=" + target + "% ，区间=" + min + "~" + max + "%");
                lastDehumidifierTarget = dehumidifierState;
            }
            Controller autoDehumidifier = RoomController.getAutoDehumidifier();
            int dehumidifierTargetHumidity = (int) Math.round(target);
            boolean needRefreshDehumidifierSetting = autoDehumidifier instanceof Dehumidifier485
                    && dehumidifierState
                    && ((Dehumidifier485) autoDehumidifier).getTargetHumidity() != dehumidifierTargetHumidity;
            boolean humidifierKeep = !RoomController.humidifier.isAvailable() || RoomController.humidifier.isPowerSupply() == humidifierState;
            boolean dehumidifierKeep = autoDehumidifier == null
                    || autoDehumidifier.isPowerSupply() == dehumidifierState && !needRefreshDehumidifierSetting;

            if (humidifierKeep && dehumidifierKeep) {
                // 状态维持时不重复输出，避免淹没真正的状态变化和异常日志。
            } else {
                // 加湿器控制
                if (RoomController.humidifier.isAvailable()) {
                    MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> {
                        boolean humidifierResult = MyUtil.autoControlOperateThird(RoomController.humidifier, humidifierState);
                        MyLog.auto("湿度控制执行结果：设备=加湿器，目标=" + formatState(humidifierState)
                                + "，结果=" + (humidifierResult ? "成功" : "失败") + "，校准前湿度="
                                + beforeCalibratedHumidity + "% ，校准后湿度=" + calibratedHumidity + "%");
                        String airExchangeMode = AutoModelSet.getAirExchangeMode();
                        if (RoomController.airExchange.isAvailable() && airExchangeMode.equals(SpinnerList.AIR_EXCHANGE_MODES[2])) {
                            boolean airExchangeResult = MyUtil.autoControlOperateThird(RoomController.airExchange, humidifierState);
                            MyLog.auto("湿度联动执行结果：设备=新风，目标=" + formatState(humidifierState)
                                    + "，结果=" + (airExchangeResult ? "成功" : "失败"));
                        }
                    }));
                }
                // 除湿器控制（新增）
                if (autoDehumidifier != null) {
                    MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> {
                        MyLog.auto("自动：" + (dehumidifierState ? "开启" : "关闭") + "除湿机--");
                        boolean operateResult = MyUtil.autoControlOperateThird(autoDehumidifier, dehumidifierState);
                        if (operateResult && autoDehumidifier instanceof Dehumidifier485 && dehumidifierState) {
                            Dehumidifier485 dehumidifier485 = (Dehumidifier485) autoDehumidifier;
                            dehumidifier485.setWorkMode(Dehumidifier485.MODE_DEHUMIDIFY);
                            dehumidifier485.setTargetHumidity(dehumidifierTargetHumidity);
                        }
                    }));
                }
            }
        });
        return true;
    }

    @Override
    protected void stopMethod() {
        needOpenToTarget = false;
        needDehumidifyToTarget = false;
        lastHumidifierTarget = null;
        lastDehumidifierTarget = null;
        invalidHumidityLogged = false;
        MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> {
            MyUtil.autoControlOperateThird(RoomController.humidifier);
            Controller autoDehumidifier = RoomController.getAutoDehumidifier();
            if (autoDehumidifier != null) {
                MyUtil.autoControlOperateThird(autoDehumidifier, false);
            }
            String airExchangeMode = AutoModelSet.getAirExchangeMode();
            if (RoomController.airExchange.isAvailable() && airExchangeMode.equals(SpinnerList.AIR_EXCHANGE_MODES[2])) {
                MyUtil.autoControlOperateThird(RoomController.airExchange, false);
            }
        }));
        MyLog.auto("停止自动控制湿度————————————————————————————————————————————————————");
    }

    private String formatState(Boolean state) {
        if (state == null) {
            return "未初始化";
        }
        return state ? "开启" : "关闭";
    }

}
