package com.example.iot_controlhost.ui.activity;

import android.content.Intent;
import android.os.Build;
import android.provider.Settings;
import android.widget.TextView;

import androidx.recyclerview.widget.LinearLayoutManager;

import com.blankj.utilcode.util.StringUtils;
import com.example.iot_controlhost.R;
import com.example.iot_controlhost.adapter.SetAdapter;
import com.example.iot_controlhost.base.BaseActivity;
import com.example.iot_controlhost.databinding.ActivitySetBinding;
import com.example.iot_controlhost.databinding.ItemSetBinding;
import com.example.iot_controlhost.model.Device;
import com.example.iot_controlhost.model.Set;
import com.example.iot_controlhost.model.controller.AirConditionInfrared;
import com.example.iot_controlhost.model.controller.Dehumidifier485;
import com.example.iot_controlhost.model.controller.DehumidifierInfrared;
import com.example.iot_controlhost.model.controller.Floor;
import com.example.iot_controlhost.model.net.AirConditionList;
import com.example.iot_controlhost.model.sensor.ConsumptionSensor;
import com.example.iot_controlhost.model.sensor.FloorTSensor;
import com.example.iot_controlhost.model.sensor.GasSensor;
import com.example.iot_controlhost.model.sensor.Sensor;
import com.example.iot_controlhost.model.sensor.THSensor;
import com.example.iot_controlhost.model.thread.QueueIOTask;
import com.example.iot_controlhost.ui.dialog.AirConditionAddDialog;
import com.example.iot_controlhost.ui.dialog.AirDialog;
import com.example.iot_controlhost.ui.dialog.ConfirmDialog;
import com.example.iot_controlhost.ui.dialog.DehumidityAddDialog;
import com.example.iot_controlhost.ui.dialog.Dehumidifier485Dialog;
import com.example.iot_controlhost.ui.dialog.PasswordDialog;
import com.example.iot_controlhost.ui.dialog.SetDeviceBaseDialog;
import com.example.iot_controlhost.ui.dialog.SetPWMDialog;
import com.example.iot_controlhost.ui.dialog.SetPortDialog;
import com.example.iot_controlhost.ui.dialog.SetSensorDialog;
import com.example.iot_controlhost.ui.dialog.SpinnerDialog;
import com.example.iot_controlhost.ui.dialog.TextViewDialog;
import com.example.iot_controlhost.utils.AppUpdateUtil;
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.database.dynamicSensor.IndoorAmmoniaSensorUtil;
import com.example.iot_controlhost.utils.database.dynamicSensor.IndoorCO2SensorUtil;
import com.example.iot_controlhost.utils.database.dynamicSensor.IndoorFloorTSensorUtil;
import com.example.iot_controlhost.utils.database.dynamicSensor.IndoorTHSensorUtil;
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.SpinnerList;
import com.example.iot_controlhost.utils.log.UserLog;
import com.example.iot_controlhost.utils.log.MyLog;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import es.dmoral.toasty.Toasty;

public class SetActivity extends BaseActivity<ActivitySetBinding, SetActivityPresenter> {

    /**
     * 当前菜单是否在主菜单
     */
    private int toMain;
    List<Set> setList;
    SetAdapter setAdapter;

    @Override
    public void initView() {
        setList = new ArrayList<>();
        setAdapter = new SetAdapter(setList, ItemSetBinding.class);
        binding.rvSet.setLayoutManager(new LinearLayoutManager(mContext));
        binding.rvSet.setAdapter(setAdapter);
        setMain();
        presenter.getRefreshLiveData().observe(this, integer -> {
            switch (integer) {
                case 0 -> setFloor();
                case 1 -> MyUtil.relaunchApp();
                case 2 -> setAirCondition();
                case 3 -> setAdvanced();
                case 4 -> setDeHumidity();
            }
        });
        presenter.getShowImportAirConditionInstructionDialogLiveData().observe(this,
                pair -> showImportAirConditionInstructionDialog(pair.first, pair.second));
        presenter.getShowImportHumidifierInstructionDialogLiveData().observe(this,
                this::showImportDehumidifierInstructionDialog);
    }

    @Override
    public void initListener() {
        //返回按钮
        binding.btnBack.setOnClickListener(view -> {
            if (toMain == -1) {
                // 重启APP以应用最新配置
                presenter.uploadSet();
            } else if (toMain == 0) {
                setMain();
            } else if (toMain == 1) {
                setSensor();
            } else if (toMain == 2) {
                setAirCondition();
            } else if (toMain == 3) {
                setDeHumidity();
            }
        });
    }

    /**
     * 主菜单
     */
    private void setMain() {
//        输出每个继电器下设备的端口情况
//        for (Relay controller : RoomController.getAllRelayDevice()) {
//            System.out.print(controller.getName() + "：");
//            for (int controllerPort : controller.getPorts()) {
//                System.out.print("\t端口" + controllerPort);
//            }
//            System.out.println();
//        }
        toMain = -1;
        setList.clear();
        binding.tvTitle.setText(getText(R.string.set));
        setList.add(new Set(getString(R.string.set_app), view -> setApp()));
        setList.add(new Set(getString(R.string.set_controller), view -> setController()));
        if (HardwareSetting.getWorkMode().equals(HardwareSetting.CONTROLLER_WORK_MODE[0])) {
            //控制版本-从机模式
            setList.add(new Set(getString(R.string.set_relay), view -> setRelay()));
            setList.add(new Set(getString(R.string.set_sensor), view -> setSensor()));
            setList.add(new Set(getString(R.string.set_air_condition), view -> setAirCondition()));
            setList.add(new Set("除湿机配置", view -> setDeHumidity()));
            setList.add(new Set(RoomSetting.getFloorName() + "配置", view -> setFloor()));
        } else {
            //显示版本-主机模式
        }
        setList.add(new Set(getString(R.string.set_advanced), view -> new PasswordDialog(mContext, "请输入运维密码",
                ti -> presenter.checkDevOpsPassword(ti.getText().toString())).show()));
        setList.add(new Set(getString(R.string.device_info), view -> info()));
        setAdapter.setDataList(setList);
    }

    /**
     * 显示设备信息
     */
    private void info() {
        toMain = 0;
        binding.tvTitle.setText(getText(R.string.set) + " > " + getText(R.string.device_info));
        setList.clear();
        setList.add(new Set(getString(R.string.device_model), Build.MODEL));
        setList.add(new Set(getString(R.string.device_manufacturer), Build.MANUFACTURER));
        setList.add(new Set(getString(R.string.device_brand), Build.BRAND));
        setList.add(new Set(getString(R.string.device_serial), Build.SERIAL));
        setList.add(new Set(getString(R.string.android_version), Build.VERSION.RELEASE));
        setList.add(new Set(getString(R.string.api_level), String.valueOf(Build.VERSION.SDK_INT)));
        setList.add(new Set(getString(R.string.product_name), Build.PRODUCT));
        setList.add(new Set(getString(R.string.board_name), Build.BOARD));
        setList.add(new Set(getString(R.string.imei), HardwareSetting.getImei()));
        setList.add(new Set(getString(R.string.device_id), HardwareSetting.getHostId()));
        setList.add(new Set(getString(R.string.version), MyUtil.getVersionId(this) + "-" + MyUtil.getVersionName(this)));
        setList.add(new Set(getString(R.string.check_update), view -> AppUpdateUtil.updateAPP(mContext, false, false)));
        setAdapter.setDataList(setList);
    }

    /**
     * 系统配置
     */
    private void setApp() {
        toMain = 0;
        binding.tvTitle.setText(getText(R.string.set) + " > " + getText(R.string.set_app));
        setList.clear();
        setList.add(new Set(getString(R.string.set_password), "******", view ->
                new PasswordDialog(mContext, getString(R.string.set_password), null, ti -> {
                    MMKVUtil.put(RoomSetting.SET_PASSWORD, ti.getText().toString());
                    UserLog.operate("本机屏幕", "系统设置密码修改成功（密码内容未记录）");
                }).show()));
        setList.add(new Set(getString(R.string.set_password_main_lock), "******", view -> new PasswordDialog(mContext, getString(R.string.set_password_main_lock),
                null, ti -> {
            if (ti.getText().toString().length() != 6) {
                new ConfirmDialog(mContext, "提示", "设置失败，锁屏密码长度为6位，请重新设置", null).show();
                return;
            }
            MMKVUtil.put(RoomSetting.MAIN_ACTIVITY_LOCK, ti.getText().toString());
            UserLog.operate("本机屏幕", "锁屏密码修改成功（密码内容未记录）");
        }).show()));
        setList.add(new Set("导入配置", view -> new SpinnerDialog(mContext, "导入配置", "请选择配置来源",
                new String[]{"预设", "基地", "会东", "旧版本", "兴文石海", "主干继电器-从机模式"},
                selection -> presenter.importSet(selection)).show()));
        setList.add(new Set("上传日志", v -> {
            Toasty.warning(mContext, "正在开发中").show();
//            presenter.uploadLog();
        }));
        setAdapter.setDataList(setList);
    }

    /**
     * 控制器配置
     */
    private void setController() {
        toMain = 0;
        binding.tvTitle.setText(getText(R.string.set) + " > " + getText(R.string.set_controller));
        setList.clear();
//        setList.add(new Set(getString(R.string.set_controller_type), Controller.getControllerModel(), view ->
//                new SpinnerDialog(mContext, getString(R.string.set_controller), "请选择控制器类别", Controller.CONTROLLER_MODEL, selection -> {
//                    Controller.setControllerModel(selection);
//                    setController();
//                }).show()));
//        if (Device.isIntegratedController()) {
////            选择——集成控制器-集成控制器工作方式有主机模式、从机模式
//            setList.add(new Set(getString(R.string.work_mode), HardwareSetting.getWorkMode(), view ->
//                    new SpinnerDialog(mContext, getString(R.string.work_mode), "请选择工作模式", HardwareSetting.CONTROLLER_WORK_MODE, selection -> {
//                        HardwareSetting.setWorkMode(selection);
//                        setController();
//                    }).show()));
//            setList.add(new Set(getString(R.string.serial_port_common), HardwareSetting.getControllerSerialCom() + "\t:\t" + HardwareSetting.getControllerSerialBaud(), view ->
//                    showSetBaseDialog(mContext, getString(R.string.serial_port_common), SpinnerList.SERIAL_ADDRESS, getString(R.string.serial_port_common),
//                            SpinnerList.BAUD, getString(R.string.baud), (serial, baud) -> {
//                                HardwareSetting.setControllerSerialCom(serial);
//                                HardwareSetting.setSensorSerialCom(serial);
//                                HardwareSetting.setControllerSerialBaud(baud);
//                                HardwareSetting.setSensorSerialComBaud(baud);
//                                setController();
//                            })));
//            setList.add(new Set(getString(R.string.serial_address_common), HardwareSetting.getCommonAddress(), view ->
//                    new SpinnerDialog(mContext, getString(R.string.serial_address_common), "请选择通用地址", SpinnerList.ADDRESS, selection -> {
//                        HardwareSetting.setCommonAddress(selection);
//                        setController();
//                    }).show()));
//        } else {
////            选择——装配式控制器-拼装式控制器工作方式只有从机模式
//            HardwareSetting.setWorkMode(HardwareSetting.CONTROLLER_WORK_MODE[0]);
//            setList.add(new Set(getString(R.string.work_mode), HardwareSetting.getWorkMode()));

//            //非集成控制器则需要设置传感器串口
        setList.add(new Set(getString(R.string.serial_port_sensor), HardwareSetting.getSensorSerialCom() + "\t:\t" + HardwareSetting.getSensorSerialComBaud(), view ->
                new SetDeviceBaseDialog(mContext, getString(R.string.serial_port_sensor),
                        SpinnerList.SERIAL_ADDRESS, getString(R.string.serial_port_sensor), HardwareSetting.getSensorSerialCom(),
                        SpinnerList.BAUD, getString(R.string.baud), HardwareSetting.getSensorSerialComBaud(), (serial, baud) -> {
                    HardwareSetting.setSensorSerialCom(serial);
                    HardwareSetting.setSensorSerialComBaud(baud);
                    setController();
                }).show()));
        setList.add(new Set(getString(R.string.serial_port_controller), HardwareSetting.getControllerSerialCom() + "\t:\t" + HardwareSetting.getControllerSerialBaud(), view ->
                new SetDeviceBaseDialog(mContext, getString(R.string.serial_port_controller),
                        SpinnerList.SERIAL_ADDRESS, getString(R.string.serial_port_sensor), HardwareSetting.getControllerSerialCom(),
                        SpinnerList.BAUD, getString(R.string.baud), HardwareSetting.getControllerSerialBaud(), (serial, baud) -> {
                    HardwareSetting.setControllerSerialCom(serial);
                    HardwareSetting.setControllerSerialBaud(baud);
                    setController();
                }).show()));
//        }
        setAdapter.setDataList(setList);
    }

    /**
     * 继电器配置
     */
    private void setRelay() {
        toMain = 0;
        binding.tvTitle.setText(getText(R.string.set) + " > " + getText(R.string.set_relay));
        setList.clear();
        if (!Device.isIntegratedController()) {
            //装配式控制器
            setList.add(new Set(getString(R.string.enable_relay), RoomController.relay.isEnable(), (compoundButton, b) -> {
                boolean oldValue = RoomController.relay.isEnable();
                RoomController.relay.setEnable(b);
                logSettingChanged("继电器启用状态", oldValue, b);
                setRelay();
            }));
            setList.add(new Set(getString(R.string.set_base), RoomController.relay.toString(), view -> new SetDeviceBaseDialog(mContext, getString(R.string.set_relay), RoomController.relay.getModels(),
                    getString(R.string.mode), RoomController.relay.getModel(), SpinnerList.ADDRESS, getString(R.string.address), RoomController.relay.getAddress(), (model, address) -> {
                RoomController.relay.setModel(model);
                RoomController.relay.setAddress(address);
                setRelay();
            }).show()));
        }
        for (int i = 1; i <= 8; i++) {
            setList.add(new Set(getString(R.string.port) + i, MyUtil.getPortToDeviceName(i),
                    v -> new SetPortDialog(mContext,
                            Integer.parseInt(((TextView) v.findViewById(R.id.tv_set_title)).getText().toString().substring(2)),
                            () -> setRelay()).show()));
        }
        setAdapter.setDataList(setList);
    }

    /**
     * 除湿机配置
     */
    void setDeHumidity() {
        toMain = 0;
        binding.tvTitle.setText(getText(R.string.set) + " > 除湿机配置");
        setList.clear();
        setList.add(new Set("485除湿机配置", RoomController.dehumidifier485.toString(), view -> setDehumidifier485()));
        setList.add(new Set("红外除湿机配置", RoomController.dehumidifierInfrared.toString(), view -> setDeHumidityInfrared()));
        setAdapter.setDataList(setList);
    }

    void setDehumidifier485() {
        toMain = 3;
        Dehumidifier485 dehumidifier485 = RoomController.dehumidifier485;
        binding.tvTitle.setText(getText(R.string.set) + " > 除湿机配置 > 485除湿机");
        setList.clear();
        setList.add(new Set("启用485除湿机", dehumidifier485.isEnable(), (compoundButton, b) -> {
            boolean oldValue = dehumidifier485.isEnable();
            dehumidifier485.setEnable(b);
            logSettingChanged("485除湿机启用状态", oldValue, b);
            setDehumidifier485();
        }));
        setList.add(new Set("基础配置", dehumidifier485.toString(), view ->
                new SetDeviceBaseDialog(mContext, "485除湿机基础配置", dehumidifier485.getModels(),
                        getString(R.string.select_model), dehumidifier485.getModel(), Dehumidifier485.ADDRESS_LIST,
                        getString(R.string.select_address), dehumidifier485.getAddress(), (model, address) -> {
                    dehumidifier485.setModel(model);
                    dehumidifier485.setAddress(address);
                    setDehumidifier485();
                }).show()));
        setList.add(new Set("控制测试", dehumidifier485.getState(), view -> new Dehumidifier485Dialog(mContext, dehumidifier485).show()));
        setAdapter.setDataList(setList);
    }

    void setDeHumidityInfrared() {
        toMain = 3;
        DehumidifierInfrared deHumidityInfrared = RoomController.dehumidifierInfrared;
        binding.tvTitle.setText(getText(R.string.set) + " > 除湿机配置");
        setList.clear();
        setList.add(new Set(getString(R.string.enable_air_condition_infrared), deHumidityInfrared.isEnable(), (compoundButton, b) -> {
            boolean oldValue = deHumidityInfrared.isEnable();
            deHumidityInfrared.setEnable(b);
            logSettingChanged("红外除湿机启用状态", oldValue, b);
            setDeHumidityInfrared();
        }));
        setList.add(new Set(getString(R.string.set_base_infrared), deHumidityInfrared.toString(), view ->
                new SetDeviceBaseDialog(mContext, getString(R.string.set_base_infrared), deHumidityInfrared.getModels(),
                        getString(R.string.select_model), deHumidityInfrared.getModel(), SpinnerList.ADDRESS,
                        getString(R.string.select_address), deHumidityInfrared.getAddress(), (model, address) -> {
                    deHumidityInfrared.setModel(model);
                    deHumidityInfrared.setAddress(address);
                    setDeHumidityInfrared();
                }).show()));
        setList.add(new Set("导入除湿机指令", "除湿机指令集", view ->
                presenter.getAirConditionModelList(-1)));
        setAdapter.setDataList(setList);
    }
    /**
     * 空调配置
     */
    void setAirCondition() {
        toMain = 0;
        binding.tvTitle.setText(getText(R.string.set) + " > " + getText(R.string.set_air_condition));
        setList.clear();
        setList.add(new Set("配置" + getText(R.string.set_air_condition1), view -> setAirConditionDetail(1, RoomController.airConditionInfrared)));
        setList.add(new Set("配置" + getText(R.string.set_air_condition2), view -> setAirConditionDetail(2, RoomController.airConditionInfrared2)));
        setList.add(new Set(getString(R.string.set_time_air_auto_stop_relay), RoomSetting.getTimeOfAirStopRelay() + "秒", view ->
                new PasswordDialog(mContext, "关闭物理电源的等待时间", null, false, ti -> {
                    try {
                        int seconds = Integer.parseInt(ti.getText().toString());
                        if (seconds < 3) {
                            new ConfirmDialog(mContext, "提示", "设置失败，等待时间不可少于3秒", null).show();
                            return;
                        }
                        long oldSeconds = RoomSetting.getTimeOfAirStopRelay();
                        MMKVUtil.put(RoomSetting.TIME_OF_AIR_STOP_RELAY, seconds);
                        logSettingChanged("空调关闭物理电源等待时间", oldSeconds + "秒", seconds + "秒");
                        setAirCondition();
                    } catch (Exception e) {
                        new ConfirmDialog(mContext, "提示", "设置失败，等待时间必须为整数", null).show();
                    }
                }, true).show()));
        setList.add(new Set("手动/自动控制时：先开物理开关，再切换温度", RoomSetting.isAirStartFirst(), (compoundButton, b) -> {
            boolean oldValue = RoomSetting.isAirStartFirst();
            MMKVUtil.put(RoomSetting.CONTROL_AIR_START_FIRST, b);
            logSettingChanged("空调先开物理开关", oldValue, b);
            setAirCondition();
        }));
        setList.add(new Set("自动控制时：循环发送控制指令", RoomSetting.isAirRecycleControl(), (compoundButton, b) -> {
            boolean oldValue = RoomSetting.isAirRecycleControl();
            MMKVUtil.put(RoomSetting.AIR_RECYCLE_CONTROL, b);
            logSettingChanged("空调循环发送控制指令", oldValue, b);
            setAirCondition();
        }));
        setAdapter.setDataList(setList);
    }

    /**
     * 设置空调1
     */
    void setAirConditionDetail(int airId, AirConditionInfrared airConditionInfrared) {
        toMain = 2;
        binding.tvTitle.setText(getText(R.string.set) + " > " + getText(R.string.set_air_condition) + " > " + airConditionInfrared.getName());
        setList.clear();
        setList.add(new Set(getString(R.string.enable_air_condition_infrared), airConditionInfrared.isEnable(), (compoundButton, b) -> {
            boolean oldValue = airConditionInfrared.isEnable();
            airConditionInfrared.setEnable(b);
            logSettingChanged(airConditionInfrared.getName() + "启用状态", oldValue, b);
            setAirConditionDetail(airId, airConditionInfrared);
        }));
        setList.add(new Set(getString(R.string.set_base_infrared), airConditionInfrared.toString(), view ->
                new SetDeviceBaseDialog(mContext, getString(R.string.set_base_infrared), airConditionInfrared.getModels(),
                        getString(R.string.select_model), airConditionInfrared.getModel(), SpinnerList.ADDRESS,
                        getString(R.string.select_address), airConditionInfrared.getAddress(), (model, address) -> {
                    airConditionInfrared.setModel(model);
                    airConditionInfrared.setAddress(address);
                    setAirConditionDetail(airId, airConditionInfrared);
                }).show()));
        String airInstruction = airId == 1 ? RoomController.airCondition.getAirConditionModel() : RoomController.airCondition.getAirConditionModel2();
        setList.add(new Set(getString(R.string.import_air_condition_instruction), airInstruction + "指令集", view ->
                presenter.getAirConditionModelList(airId)));
        setList.add(new Set(getString(R.string.air_conditioning_test), null, view -> new AirDialog(mContext, airConditionInfrared).show()));
        setAdapter.setDataList(setList);
    }

    /**
     * 空调型号选择弹窗
     */
    void showImportAirConditionInstructionDialog(int airId, List<AirConditionList.DataDTO> list) {
        String[] models = list.stream()
                .map(data -> data.getBrand() + "-" + data.getModel())
                .toArray(String[]::new);
        new SpinnerDialog(mContext, "空调型号", "请选择空调型号", models, selection -> {
            //从服务器读取空调指令json，并导入至红外控制器
            presenter.importAirConditionInstruction(list, selection, airId);
        }).show();
    }
    /**
     * 除湿机型号选择弹窗
     */
    void showImportDehumidifierInstructionDialog( List<AirConditionList.DataDTO> list) {
        String[] models = list.stream()
                .map(data -> data.getBrand() + "-" + data.getModel())
                .toArray(String[]::new);
        new SpinnerDialog(mContext, "除湿机型号（注意区别空调）", "请选择型号", models, selection -> {
            //从服务器读取空调指令json，并导入至红外控制器
            presenter.importDehumidifierInstruction(list, selection);
        }).show();
    }

    /**
     * 地暖配置
     */
    void setFloor() {
        toMain = 0;
        binding.tvTitle.setText(getText(R.string.set) + " > " + RoomSetting.getFloorName() + "配置");
        setList.clear();
        setList.add(new Set("开启" + RoomSetting.getFloorName(), RoomController.floor.isEnable(), (compoundButton, b) -> {
            boolean oldValue = RoomController.floor.isEnable();
            RoomController.floor.setEnable(b);
            logSettingChanged(RoomSetting.getFloorName() + "启用状态", oldValue, b);
            setFloor();
        }));
        setList.add(new Set("地暖别名", RoomSetting.getFloorName(), view ->
                new SpinnerDialog(mContext, "地暖别名", "请选择显示名称", new String[]{"地暖", "升温板"}, str -> {
                    String oldValue = RoomSetting.getFloorName();
                    MMKVUtil.put(RoomSetting.FLOOR_NAME, str);
                    logSettingChanged("地暖显示名称", oldValue, str);
                    setFloor();
                }).show()));
        setList.add(new Set(getString(R.string.max_gear), RoomController.floor.getMaxGear() + "档", v1 ->
                new SpinnerDialog(mContext, getString(R.string.max_gear), "请选择" + RoomSetting.getFloorName() + "最大档位", new String[]{"1", "2", "3", "4", "5"}, selection -> {
                    int oldValue = RoomController.floor.getMaxGear();
                    RoomController.floor.setMaxGear(Integer.parseInt(selection));
                    logSettingChanged(RoomSetting.getFloorName() + "最大档位", oldValue, selection);
                    setFloor();
                    successTips("最大档位已设置为：" + Integer.parseInt(selection) + "档");
                }).show()));
        if (!Device.isIntegratedController() //集成式控制器
                && !RoomController.relay.getModel().equals(RoomController.relay.getModels()[1])//型号为中胜0-10V模拟量控制的继电器
                && !RoomController.relay.getModel().equals(RoomController.relay.getModels()[2])) {//型号为BBIT-H-v1.0的继电器
            //需要配置地暖型号与地址
            setList.add(new Set(getString(R.string.set_base), RoomController.floor.toString(), view ->
                new SetDeviceBaseDialog(mContext, "地暖" + RoomSetting.getFloorName(), RoomController.floor.getModels(),
                        getString(R.string.mode), RoomController.floor.getModel(), SpinnerList.ADDRESS,
                        getString(R.string.address), RoomController.floor.getAddress(), (model, address) -> {
                        RoomController.floor.setModel(model);
                        RoomController.floor.setAddress(address);
                        setFloor();
                    }).show()));
        }
        for (int i = 1; i <= 5; i++) {
            int finalI = i;
            setList.add(new Set(i + getString(R.string.gear), RoomController.floor.getPwm(i).toString(), view ->
                    new SetPWMDialog(mContext, finalI, () -> setFloor()).show()));
        }
        setList.add(new Set("导入预设PWM", view -> {
            if (StringUtils.isEmpty(RoomController.floor.getModel())) {
                Toasty.info(mContext, "请先配置" + RoomSetting.getFloorName() + "型号").show();
                new ConfirmDialog(mContext, getString(R.string.error), RoomSetting.getFloorName() + "型号尚未配置", null).show();
            } else {
                new ConfirmDialog(mContext, getString(R.string.set_pwm), "确定导入" + RoomSetting.getFloorName() + "预设配置吗？", () -> {
                    Floor.importDefaultPWMToFloor();
                    setFloor();
                    successTips("成功导入预设配置");
                }).show();
            }
        }));
        if (RoomSensor.consumptionSensor.isAvailable()) {
            //只有能耗传感器可用，才可自动设置PWM
            setList.add(new Set("自动匹配" + RoomSetting.getFloorName() + "功率", view ->
                    new ConfirmDialog(mContext, getString(R.string.set_pwm), "是否开始自动设置PWM与功率？\n此过程需要能耗传感器支持且耗时较长", () -> presenter.autoSetFloorPWM()).show()));
        }
        setAdapter.setDataList(setList);
    }

    /**
     * 传感器配置
     */
    private void setSensor() {
        toMain = 0;
        binding.tvTitle.setText(getText(R.string.set) + " > " + getText(R.string.set_sensor));
        setList.clear();
        setList.add(new Set("动态配置-室内温湿传感器", view -> setIndoorSensor(0)));
        setList.add(new Set("动态配置-室内CO2传感器", view -> setIndoorSensor(1)));
        setList.add(new Set("动态配置-室内氨气传感器", view -> setIndoorSensor(2)));
        setList.add(new Set("动态配置-地面温度传感器", view -> setIndoorSensor(3)));
        boolean needHideConsumptionSensor = RoomController.relay.getModel().equals(RoomController.relay.getModels()[2]);
        List<Sensor> devices = new ArrayList<>();
        Collections.addAll(devices, RoomSensor.outdoorTHSensor, RoomSensor.consumptionSensor, RoomSensor.airTHSensor, RoomSensor.co2OutdoorSensor);
        for (Sensor sensor : devices) {
            if (!needHideConsumptionSensor || !(sensor instanceof ConsumptionSensor)) {
                setList.add(new Set(sensor.getName(), sensor.getBaseInfo(), view -> new SetSensorDialog(mContext, sensor, s -> setSensor()).show()));
            }
        }
        setAdapter.setDataList(setList);
    }

    /**
     * 室内温湿度传感器设置
     *
     * @param type 0 温湿度传感器,1 CO2传感器, 2 氨气传感器 3 地面温度传感器
     */
    private void setIndoorSensor(int type) {
        toMain = 1;
        String typeStr = type == 0 ? "温湿度" : type == 1 ? "CO2" : type == 2 ? "氨气" : "地面温度";
        String title = "动态配置-" + typeStr;
        binding.tvTitle.setText(getText(R.string.set) + " > " + getText(R.string.set_sensor) + " > " + title + "传感器");
        setList.clear();
        setList.add(new Set("新增", view -> new TextViewDialog(mContext, "请输入" + title + "传感器名称", typeStr + "传感器", str -> {
            if (StringUtils.isEmpty(str)) {
                Toasty.error(mContext, "传感器名称不能为空").show();
                return;
            }
            String message = "新增传感器" + str + "成功";
            boolean success = type == 0 ? IndoorTHSensorUtil.insert(new THSensor(str)) :
                    type == 1 ? IndoorCO2SensorUtil.insert(new GasSensor(str)) :
                            type == 2 ? IndoorAmmoniaSensorUtil.insert(new GasSensor(str)) : IndoorFloorTSensorUtil.insert(new FloorTSensor(str));
            if (success) {
                Toasty.success(mContext, message).show();
            } else {
                Toasty.error(mContext, message.replace("成功", "失败，已存在同名传感器")).show();
            }
            setIndoorSensor(type);
        }, false).show()));
        setList.add(new Set("删除", view -> new SpinnerDialog(mContext, "删除" + title + "传感器", "请选择要删除的传感器",
                type == 0 ? IndoorTHSensorUtil.getAllNames() : type == 1 ? IndoorCO2SensorUtil.getAllNames() : type == 2 ?
                        IndoorAmmoniaSensorUtil.getAllNames() : IndoorFloorTSensorUtil.getAllNames(), str -> {
            if (type == 0) {
                IndoorTHSensorUtil.deleteByName(str);
            } else if (type == 1) {
                IndoorCO2SensorUtil.deleteByName(str);
            } else if (type == 2) {
                IndoorAmmoniaSensorUtil.deleteByName(str);
            } else if (type == 3) {
                IndoorFloorTSensorUtil.deleteByName(str);
            }
            Toasty.success(mContext, "删除传感器" + str + "成功").show();
            setIndoorSensor(type);
        }).show()));
        List<? extends Sensor> sensors = type == 0 ? IndoorTHSensorUtil.getAllSensors() :
                type == 1 ? IndoorCO2SensorUtil.getAllSensors() : type == 2 ? IndoorAmmoniaSensorUtil.getAllSensors() : IndoorFloorTSensorUtil.getAllSensors();
        if (sensors != null) {
            for (Sensor sensor : sensors) {
                setList.add(new Set(sensor.getName(), sensor.getBaseInfo(), view -> new SetSensorDialog(mContext, sensor, s -> {
                    IndoorTHSensorUtil.update(s);
                    setIndoorSensor(type);
                }).show()));
            }
        }
        setAdapter.setDataList(setList);
    }

    /**
     * 高级配置，需要运维密码
     */
    public void setAdvanced() {
        toMain = 0;
        binding.tvTitle.setText(getText(R.string.set) + " > " + getText(R.string.set_advanced));
        setList.clear();
        setList.add(new Set("恢复出厂设置", view -> new ConfirmDialog(mContext, getString(R.string.error), "确定恢复出厂设置吗？\n设备将在初始化后重启", () -> {
            UserLog.operate("本机屏幕", "已确认恢复出厂设置，设备即将重置并重启");
            MMKVUtil.clear();
            //清空数据后需要恢复主机码 否则无法上传最新配置
            MMKVUtil.put(HardwareSetting.HOST_ID, Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID));
            presenter.uploadSet();
        }).show()));
        setList.add(new Set("调试工具", view -> startActivity(new Intent(mContext, DebugActivity.class))));
        setList.add(new Set("指令设置——" + RoomController.airConditionInfrared.getName(), null, view -> {
            MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> RoomController.airCondition.setPowerSupply(true)));
            new AirConditionAddDialog(mContext, RoomController.airConditionInfrared).show();
        }));
        setList.add(new Set("指令设置——" +RoomController.airConditionInfrared2.getName(), null, view -> {
            MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> RoomController.airCondition.setPowerSupply(true)));
            new AirConditionAddDialog(mContext, RoomController.airConditionInfrared2).show();
        }));
        setList.add(new Set("指令设置——" +RoomController.dehumidifierInfrared.getName(), null, view -> {
            MyQueue.getInstance(MyQueue.TYPE_CONTROLLER).addTask(new QueueIOTask(() -> RoomController.dehumidifierInfrared.setPowerSupply(true)));
            new DehumidityAddDialog(mContext, RoomController.dehumidifierInfrared).show();
        }));
        setAdapter.setDataList(setList);
    }

    private void logSettingChanged(String name, Object oldValue, Object newValue) {
        UserLog.operate("本机屏幕", "设备设置变化：" + name + "=" + oldValue + " → " + newValue);
        MyLog.app("设备设置修改：" + name + "=" + oldValue + "→" + newValue);
    }

}
