package com.example.iot_controlhost.model.controller;

import com.example.iot_controlhost.base.SetAddress;
import com.example.iot_controlhost.utils.MMKVUtil;
import com.example.iot_controlhost.utils.global.HardwareSetting;
import com.example.iot_controlhost.utils.global.RoomController;
import com.example.iot_controlhost.utils.global.RoomSetting;
import com.example.iot_controlhost.utils.global.Variable;
import com.example.iot_controlhost.utils.log.MyLog;

/**
 * 除湿机红外控制器
 * 此类的port为除湿机的，而非红外的
 */
public class DehumidifierInfrared extends Controller implements SetAddress {

    public DehumidifierInfrared(String name) {
        super(name);
    }

    /**
     * 使用红外遥控器调节
     *
     * @param state 开/关
     * @return 调节电源成功与否
     *
     *
     * 注意：此方法不可直接调用，相关操作已移至RoomController.dehumidifier.setPowerSupply()，请从那里间接调用以确保除湿机物理电源和红外电源的正确配合
     */
    @Override
    public boolean setPowerSupply(boolean state) {
        if (!isAvailable()) {
            MyLog.controllerError("除湿机红外：未配置但尝试开关");
            this.powerSupply = false;
            return false;
        }
        this.powerSupply = state;
        return state;
    }

    @Override
    public boolean isPowerSupply() {
        //当除湿机物理电源和红外电源同时开时，才为开
        return super.isPowerSupply() && RoomController.dehumidifier.isPowerSupply();
    }

    /**
     * 学习指令
     * 执行后，红外控制器灯亮，在人工发送红外指令后，会熄灯
     * 之后可以通过“读取”操作查看是否学习成功
     *
     * @param type 配置文件-红外编号 0为取消学习
     * @return 学习指令是否发送成功
     */
    public boolean learnInstruction(int type) {
        String instruction = getAddress() + "06000000" + String.format("%02X", type);
        instruction = instruction + getCRC(instruction);
        return executeInstructions(instruction, "学习");
    }

    /**
     * 执行指令
     *
     * @param type 指令类型，见最下方指令对应表
     */
    public boolean executeInstruction(int type) {
        String instruction = getAddress() + "06000100" + String.format("%02X", type);
        instruction = instruction + getCRC(instruction);
        return executeInstructions(instruction, "执行");
    }

    /**
     * 读取对应红外编号的指令
     *
     * @return 对应红外编号的指令
     */
    public String readInstruction(int type) {
        try {
            String instruction = getAddress() + "4103E800" + String.format("%02X", type);
            instruction = instruction + getCRC(instruction);
            String result = serialPortUtil.sendAndReceiveSerialData(this, instruction);
            //截取result的第7位到倒数第3位
            if (result != null) {
                return result.substring(6, result.length() - 4);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 手动写入对应红外编号的指令
     *
     * @return 写入成功与否
     */
    public boolean writeInstruction(int type, String ins) {
        String instruction = getAddress() + "4203E800" + String.format("%02X", type) + ins;
        instruction = instruction + getCRC(instruction);
        //截取result的第7位到倒数第3位
        String successIns = getAddress() + "4203E800" + String.format("%02X", type);
        successIns = successIns + getCRC(successIns);
        if (executeInstructions(instruction, successIns, "导入红外指令")) {
            return true;
        }
        return false;
    }

    /**
     * 获取当前除湿机状态的介绍
     */
    public String getState() {
        return !isAvailable() ? "未正确配置" : (isPowerSupply() ? "已开启" : "未启动");
    }

    @Override
    public String[] getModels() {
        return new String[]{"标准Modbus-RTU型"};
    }

    @Override
    public String getAddress() {
        if (isIntegratedController()) {
            return HardwareSetting.getCommonAddress();
        } else {
            return super.getAddress();
        }
    }

    boolean temp;

    @Override
    public boolean setAddressToNewAddress(String model, String oldAddress, String oldBaud, String newAddress) {
        boolean result = false;
        if (model.equals(getModels()[0])) {
            //需要改地址
            String editAddress = oldAddress + "06000200" + newAddress;
            editAddress = editAddress + getCRC(editAddress);
            executeInstructions(editAddress, "改地址");
            //除湿机改地址不返回，默认成功 红外改地址 直接生效
            result = true;
        }
        return result;
    }

    @Override
    public boolean setBaudToNewBaud(String model, String oldAddress, String newBaud) {
        boolean result = false;
        if (model.equals(getModels()[0])) {
            switch (newBaud) {
                case "1200":
                    newBaud = "000C";
                    break;
                case "2400":
                    newBaud = "0018";
                    break;
                case "4800":
                    newBaud = "0030";
                    break;
                case "9600":
                    newBaud = "0060";
                    break;
                case "19200":
                    newBaud = "00C0";
                    break;
                case "38400":
                    newBaud = "0180";
                    break;
                case "57600":
                    newBaud = "0240";
                    break;
                case "115200":
                    newBaud = "0480";
                    break;
                default:
                    return false;
            }
            String editBaud = oldAddress + "060003" + newBaud;
            editBaud = editBaud + getCRC(editBaud);
            //重启后生效
            result = executeInstructions(editBaud, "改波特率");
        }
        return result;
    }

    @Override
    public boolean test(String deviceModel, String deviceAddress) {
        if (deviceModel.equals(getModels()[0])) {
            String str = deviceAddress + (!temp ? "0600010002" : "0600010001");
            str = str + getCRC(str);
            temp = !temp;
            return executeInstructions(str, !temp ? "关电源" : "开电源");
        }
        return false;
    }

    @Override
    public String getTestState() {
        return "除湿机" + (temp ? "开启" : "关闭") + "指令已尝试发送";
    }

/**
 * 指令对应表
 *
 * 200-除湿机开  C8
 * 201-除湿机关  C9
 */
}
