package com.example.iot_controlhost.model.controller;

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.log.MyLog;

import java.util.List;

/**
 * 地暖
 *
 * @Author DuanKaiji
 */
public class Floor extends Controller {
    /**
     * 地暖档位设置
     * 1-5 0关闭
     */
    int gear;
    /**
     * 地暖最大档位
     */
    public static String MAX_GEAR = "地暖最大档位";
    /**
     * 各档位
     */
    private PWM pwm0 = new PWM("地暖0档", 0);
    private PWM pwm1 = new PWM("地暖1档");
    private PWM pwm2 = new PWM("地暖2档");
    private PWM pwm3 = new PWM("地暖3档");
    private PWM pwm4 = new PWM("地暖4档");
    private PWM pwm5 = new PWM("地暖5档");

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

    @Override
    public boolean setPowerSupply(boolean state) {
        return setGear(state ? 3 : 0);
    }

    @Override
    public boolean isPowerSupply() {
        return getGear() != 0;
    }

    @Override
    public boolean isAvailable() {
        //当开关、地址、PWM均已设置，则为可用
        if (!super.isAvailable()) {
            return false;
        }
        for (int i = 1; i < 6; i++) {
            if (getPwm(i).getPwm() == -1) {
                //只要有一个档位没配置 即-1 则不可用
                return false;
            }
        }
        return true;
    }

    /**
     * 设置地暖档位
     * 当档位为0时，等同于设置电源关 setPowerSupply(false)，
     * 关闭电源无需配置，但调节1-5档位需要先配置
     *
     * @param gear 档位
     * @return 设置成功与否
     */
    public boolean setGear(int gear) {
        if (gear > getMaxGear() || gear < 0) {
            return false;
        }
        int pwm = getPwm(gear).getPwm();
        if (setGearByPWM(pwm)) {
            this.gear = gear;
            //继电器下的地暖与此处同步
            RoomController.relayFloor.setPowerSupply(gear != 0);
            return true;
        } else {
            return false;
        }
    }

    public boolean setGearByPWM(int pwm) {
        if (!isAvailable()) {
            return false;
        }
        String str = null;
        if (isIntegratedController()) {
            //集成式控制器
            str = HardwareSetting.getCommonAddress();
        } else {
            //装配式控制器
            if (getModel().equals(getModels()[0])) {
                //能工RS458控制模式
                str = getAddress() + "060002";
            } else if (getModel().equals(getModels()[1]) || getModel().equals(getModels()[2])) {
                //中胜0-5V模拟量控制/克能0-10V模拟量控制
                str = getAddress() + "06000A";
            }
            str = str + String.format("%04X", pwm);
            str = str + getCRC(str);
        }
        boolean result = true;
        if (RoomController.relay.getModel().equals(RoomController.relay.getModels()[1]) || RoomController.relay.getModel().equals(RoomController.relay.getModels()[2])) {
            //继电器使用中胜0-10V模拟量 / BBIT-H-v1.0 控制，则1.地暖使用继电器的地址；2.存在多个端口的情况；
            List<Integer> ports = RoomController.relayFloor.getPorts();
            if (ports.size() == 0) {
                MyLog.controllerError("使用 中盛0-10V模拟量 / BBIT-H-v1.0 型号继电器控制，但未配置" + RoomSetting.getFloorName() + "端口");
                return false;
            }
            for (int port : ports) {
                if (RoomController.relay.getModel().equals(RoomController.relay.getModels()[1])) {
                    //继电器和地暖地址相同，不需要再次设置继电器地址
                    str = RoomController.relayFloor.getAddress() + "0600" + String.format("%02X", 9 + port) + String.format("%04X", pwm);
                } else if (RoomController.relay.getModel().equals(RoomController.relay.getModels()[2])) {
                    //继电器使用BBIT-H-v1.0型号
                    str = RoomController.relayFloor.getAddress() + "01" + String.format("%02X", port) + String.format("%04X", pwm);
                }
                str = str + getCRC(str);
                boolean temp = executeInstructions(str, "控制第" + port + "号" + RoomSetting.getFloorName() + "端口PWM为:" + pwm);
                //只要有一个失败，则结果为失败
                result = result ? temp : false;
            }
        } else {
            result = executeInstructions(str, "控制" + RoomSetting.getFloorName() + "端口PWM为:" + pwm);
        }
        return result;
    }

    /**
     * 根据不同型号的地暖来获得最大电压
     *
     * @return 十进制的电压 后续使用需要转为4位长的16进制并拼接在
     */
    public int getMaxPower() {
        int result = 0;
        if (RoomController.relay.getModel().equals(RoomController.relay.getModels()[1])
                || RoomController.relay.getModel().equals(RoomController.relay.getModels()[2])
                || getModel().equals(getModels()[2])) {
            //先判断继电器中盛0-10V模拟量 || BBIT继电器 || 克能0-10V模拟量控制
            result = 10000;
        } else if (getModel().equals(getModels()[0]) || RoomController.relay.getModel().equals(RoomController.relay.getModels()[2])) {
            //能工RS458控制模式 || BBIT-H-v1.0
            result = 4096;
        } else if (getModel().equals(getModels()[1])) {
            //中胜0-5V模拟量控制
            result = 5000;
        }
        return result;
    }

    public int getMinPower() {
        return 900;
    }

    @Override
    public String[] getModels() {
        return new String[]{"能工RS485", "中盛0-5V模拟量", "中盛0-10V模拟量"};
    }

    public String getState() {
        return !isAvailable() ? "未正确配置" : (isPowerSupply() ? getGear() + "档升温中" : "未启动");
    }

    /**
     * 功率档位记录
     */
    public class PWM {
        /**
         * PWM名称
         */
        private String pwmName;
        /**
         * 功率
         */
        private String power;
        /**
         * PWM参数
         */
        private String pwm;

        public PWM(String pwmName) {
            this.pwmName = pwmName;
            this.pwm = pwmName + "PWM";
            this.power = pwmName + "功率";
        }

        public PWM(String pwmName, int pwm) {
            this.pwmName = pwmName;
            this.pwm = pwmName + "PWM";
            this.power = pwmName + "功率";
            setPwm(pwm);
        }

        public double getPower() {
            return MMKVUtil.get(power, 0.0);
        }

        public void setPower(double power) {
            MyLog.controller("设置" + pwmName + "档位功率为" + power);
            MMKVUtil.put(this.power, power);
        }

        public int getPwm() {
            return MMKVUtil.get(pwm, -1);
        }

        public void setPwm(int pwm) {
            MyLog.controller("设置" + pwmName + "档位PWM为" + pwm);
            MMKVUtil.put(this.pwm, pwm);
        }

        @Override
        public String toString() {
            return "PWM：" + (getPwm() == -1 ? "未配置" : getPwm()) + "\t\t功率：" + String.format("%.2f\t", getPower());
        }
    }

    public PWM getPwm(int i) {
        switch (i) {
            case 0:
            default:
                return pwm0;
            case 1:
                return pwm1;
            case 2:
                return pwm2;
            case 3:
                return pwm3;
            case 4:
                return pwm4;
            case 5:
                return pwm5;
        }
    }

    public int getGear() {
        return gear;
    }

    /**
     * 导入已有配置
     * 方便没有功耗传感器的用户
     */
    public static void importDefaultPWMToFloor() {
        String model = RoomController.floor.getModel();
        RoomController.floor.getPwm(0).setPwm(0);
        if (RoomController.relay.getModel().equals(RoomController.relay.getModels()[1])
                || RoomController.floor.getModels()[2].equals(model)
                || RoomController.relay.getModel().equals(RoomController.relay.getModels()[2])) {
            //先判断中盛0-10V模拟量 || 克能0-10V模拟量控制 || BBIT-H-v1.0
            RoomController.floor.getPwm(1).setPwm(2500);
            RoomController.floor.getPwm(2).setPwm(4000);
            RoomController.floor.getPwm(3).setPwm(6000);
            RoomController.floor.getPwm(4).setPwm(8000);
            RoomController.floor.getPwm(5).setPwm(10000);
        } else if (RoomController.floor.getModels()[0].equals(model)) {
            //能工RS458控制模式
            RoomController.floor.getPwm(1).setPwm(2500);
            RoomController.floor.getPwm(2).setPwm(2817);
            RoomController.floor.getPwm(3).setPwm(3500);
            RoomController.floor.getPwm(4).setPwm(3900);
            RoomController.floor.getPwm(5).setPwm(4096);
        } else if (RoomController.floor.getModels()[1].equals(model)) {
            //中胜0-5V模拟量控制
            RoomController.floor.getPwm(1).setPwm(2500);
            RoomController.floor.getPwm(2).setPwm(3000);
            RoomController.floor.getPwm(3).setPwm(3500);
            RoomController.floor.getPwm(4).setPwm(4000);
            RoomController.floor.getPwm(5).setPwm(5000);
        }
        RoomController.floor.getPwm(0).setPower(0);
        RoomController.floor.getPwm(1).setPower(0);
        RoomController.floor.getPwm(2).setPower(0);
        RoomController.floor.getPwm(3).setPower(0);
        RoomController.floor.getPwm(4).setPower(0);
        RoomController.floor.getPwm(5).setPower(0);
    }

    public int getMaxGear() {
        return MMKVUtil.get(MAX_GEAR, 5);
    }

    public void setMaxGear(int maxGear) {
        MMKVUtil.put(MAX_GEAR, maxGear);
    }
}
