package com.example.iot_controlhost.utils.control.temperature.strategy;

import com.blankj.utilcode.util.StringUtils;
import com.example.iot_controlhost.utils.control.infrared.MyInfraredUtils;
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.Variable;
import com.example.iot_controlhost.utils.log.MyLog;
import com.example.iot_controlhost.utils.log.UserLog;
import com.xuexiang.rxutil2.rxbus.RxBusUtils;

/**
 * 所有控制逻辑算法的通用操作
 */
public abstract class ControlStrategy {
    /**
     * 空调模式 -1时表示不控制
     */
    int mode = -1;
    /**
     * 空调温度 -1时表示不控制
     */
    int temp = -1;
    /**
     * 地暖档位 0时表示不控制
     */
    int gear = 0;
    /**
     * 提示信息，用于防止重复发送相同的提示日志
     */
    private String tipsTempStr = "";
    /**
     * 地暖已经相同操作的次数
     * 初始化为最大次数，即第一次可以执行
     */
    private int sameOperateTimesFloor = Variable.SAME_OPERATE_TIMES;
    /**
     * 空调已经相同操作的次数
     * 初始化为最大次数，即第一次可以执行
     */
    private int sameOperateTimes = Variable.SAME_OPERATE_TIMES;

    /**
     * 温控模式
     *
     * @param curTemperature 当前温度
     * @param tarTemperature 目标温度
     * @return 主界面提示信息
     */
    protected abstract void controlAlgorithm(double curTemperature, double tarTemperature);

    /**
     * 外部控制
     */
    public void control(double curTemperature, double tarTemperature) {
        init();
        controlAlgorithm(curTemperature, tarTemperature);
        operate();
    }

    /**
     * 初始化控制方式
     * 均不控制
     */
    public void init() {
        mode = -1;
        temp = -1;
        gear = 0;
    }

    boolean canOperateFloor() {
        if (gear == RoomController.floor.getGear()) {
            if (sameOperateTimesFloor >= Variable.SAME_OPERATE_TIMES) {
                sameOperateTimesFloor = 0;
            } else {
                sameOperateTimesFloor++;
//                MyLog.test("地暖相同控制，无需再发送指令");
                return false;
            }
        } else {
            sameOperateTimesFloor = 0;
        }
        if (gear > RoomController.floor.getMaxGear()) {
            //自动模式控制算法要求的地暖档位大于地暖设定档位 重定向档位
            MyLog.auto("温控算法需要的" + RoomSetting.getFloorName() + "档位大于预设最大档位，现重定档至" + RoomController.floor.getMaxGear() + "档");
            gear = RoomController.floor.getMaxGear();
        }
        if (!RoomSensor.dynamicFloorTSensorList.isEmpty() && RoomSensor.getFloorTemperature() > AutoModelSet.getAutoFlorMaxTemp()) {
            //地面温度过高 重定向至档位0
            MyLog.autoError(RoomSetting.getFloorName() + "地面温度过高，大于" + AutoModelSet.getAutoFlorMaxTemp() + "℃，停止操作");
            gear = 0;
        }
        return true;
    }

    boolean canOperateAir() {
        boolean state = mode != -1 && temp != -1;
        if (!state && !MyInfraredUtils.getInstances().isPowerSupply() ||
                state && MyInfraredUtils.getInstances().isPowerSupply()
                        && MyInfraredUtils.getInstances().getMode() == mode
                        && MyInfraredUtils.getInstances().getTemperature() == temp) {
            //一样的操作
            if (!RoomSetting.isAirRecycleControl()) {
                // 相同操作，不需要重复发送的情况
                return false;
            }
            // 相同操作，需要重复发送的情况
            if (sameOperateTimes >= Variable.SAME_OPERATE_TIMES) {
                //已经大于可重复操作的次数，开始操作
//                MyLog.test("空调相同控制，已经大于可重复操作的次数");
                sameOperateTimes = 0;
            } else {
                sameOperateTimes++;
//                MyLog.test("空调相同控制，无需再发送指令");
                return false;
            }
        } else {
            // 不一样的操作
            sameOperateTimes = 0;
        }
        return true;
    }

    public void operate() {
        StringBuffer tips = new StringBuffer("");
        boolean operateSuccess = true;
        boolean needSentLog = canSentLog();
        if (canOperateAir()) {
            if (mode == -1 || temp == -1) {
                tips.append("关闭空调\t");
                operateSuccess = MyInfraredUtils.getInstances().setPowerSupply(false) && operateSuccess;
            } else {
                operateSuccess = MyInfraredUtils.getInstances().setAirCondition(mode, temp) && operateSuccess;
                tips.append("空调" + MyInfraredUtils.getInstances().getState() + "\t");
            }
        }
        if (canOperateFloor()) {
            if (gear == 0) {
                tips.append(" 关闭" + RoomSetting.getFloorName());
                operateSuccess = RoomController.floor.setPowerSupply(false) && operateSuccess;
            } else {
                tips.append(" 开启" + RoomSetting.getFloorName() + gear + "档");
                operateSuccess = RoomController.floor.setGear(gear) && operateSuccess;
            }
        }
        if (!StringUtils.isEmpty(tips) && needSentLog) {
            //更新自动模式-温控-界面UI
            RxBusUtils.get().post(RxTag.UPDATE_AUTO, 2);
            if (operateSuccess) {
                if (!tipsTempStr.equals(tips.toString())) {
                    //防止重复发送相同的提示日志
                    tipsTempStr = tips.toString();
                    MyLog.auto("自动温控：" + tips);
                    UserLog.system("自动控制", "温度控制状态变化：" + tips.toString().trim());
                }
            } else {
                if (mode != -1 && temp != -1 && RoomSetting.isAirConditionForceClose()) {
                    tips.append("，在消毒期间无法开启空调");
                }
                MyLog.autoError("自动温控操作失败：" + tips);
                UserLog.systemError("自动控制", "温度控制操作失败：" + tips.toString().trim());
            }
        }
    }


    /**
     * 能否发送用户日志
     *
     * @return 只有在空调地暖状态改变时才发送true，即如果命令一直相同，则不发送false
     */
    private boolean canSentLog() {
        return !(//地暖
                //地暖一直关着
                (gear == -1 || gear == 0) && !RoomController.floor.isPowerSupply()
                        //地暖一直开的
                        || gear > 0 && gear == RoomController.floor.getGear())
                || !(//空调
                //空调一直关着
                (mode == -1 || temp == -1) && !MyInfraredUtils.getInstances().isPowerSupply()
                        //空调一直开着 并且温度模式相同
                        || mode == MyInfraredUtils.getInstances().getMode()
                        && temp == MyInfraredUtils.getInstances().getTemperature()
                        && MyInfraredUtils.getInstances().isPowerSupply()
        );
    }

}
