package com.example.iot_controlhost.utils.global;

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.LightSensor;
import com.example.iot_controlhost.model.sensor.Sensor;
import com.example.iot_controlhost.model.sensor.THSensor;
import com.example.iot_controlhost.utils.PollingTask;
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 java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import android_serialport_api.SerialPortUtil;

/**
 * 所有传感器
 */
public class RoomSensor {

    public static List<THSensor> dynamicTHSensorList = new ArrayList<>();
    public static List<GasSensor> dynamicCO2SensorList = new ArrayList<>();
    public static List<GasSensor> dynamicAmmoniaSensorList = new ArrayList<>();
    public static List<FloorTSensor> dynamicFloorTSensorList = new ArrayList<>();

    /**
     * 所有传感器
     */
    public static final String[] SENSOR_NAME = {"能耗传感器", "光照传感器", "噪音传感器", "室内CO2传感器", "氨气传感器",
            "地面温度传感器", "室外温湿传感器", "室内温湿传感器1", "室内温湿传感器2", "空调温度传感器", "室外CO2传感器"};

    /**
     * 能耗传感器
     */
    public static ConsumptionSensor consumptionSensor = new ConsumptionSensor(SENSOR_NAME[0]);
    /**
     * 光照传感器
     */
    public static LightSensor lightSensor = new LightSensor(SENSOR_NAME[1]);
    /**
     * 噪音传感器    已修改为动态传感器
     */
//    public static NoiseSensor noiseSensor = new NoiseSensor(SENSOR_NAME[2]);
    /**
     * CO2传感器    已修改为动态传感器
     */
//    public static GasSensor co2IndoorSensor = new GasSensor(SENSOR_NAME[3]);
    /**
     * 氨气传感器    已修改为动态传感器
     */
//    public static GasSensor ammoniaSensor = new GasSensor(SENSOR_NAME[4]);
    /**
     * 温度传感器——地面    已修改为动态传感器
     */
//    public static FloorTSensor floorTSensor = new FloorTSensor(SENSOR_NAME[5]);
    /**
     * 温湿传感器——室外
     */
    public static THSensor outdoorTHSensor = new THSensor(SENSOR_NAME[6]);
    /**
     * 温湿传感器——空调
     */
    public static FloorTSensor airTHSensor = new FloorTSensor(SENSOR_NAME[9]);
    /**
     * 温湿传感器——室外CO2
     */
    public static GasSensor co2OutdoorSensor = new GasSensor(SENSOR_NAME[10]);

    /**
     * 传感器初始化
     */
    public static void init() {
        dynamicTHSensorList = new ArrayList<>();
        dynamicCO2SensorList = new ArrayList<>();
        dynamicAmmoniaSensorList = new ArrayList<>();
        dynamicFloorTSensorList = new ArrayList<>();

        if (SerialPortUtil.getInstance(SerialPortUtil.TYPE_SENSOR).openSerialPort()) {
            for (THSensor sensor : IndoorTHSensorUtil.getAllSensors()) {
                if (sensor.isAvailable()) {
                    dynamicTHSensorList.add(sensor);
                }
            }
            for (GasSensor sensor : IndoorCO2SensorUtil.getAllSensors()) {
                if (sensor.isAvailable()) {
                    dynamicCO2SensorList.add(sensor);
                }
            }
            for (GasSensor sensor : IndoorAmmoniaSensorUtil.getAllSensors()) {
                if (sensor.isAvailable()) {
                    dynamicAmmoniaSensorList.add(sensor);
                }
            }
            for (FloorTSensor sensor : IndoorFloorTSensorUtil.getAllSensors()) {
                if (sensor.isAvailable()) {
                    dynamicFloorTSensorList.add(sensor);
                }
            }
            // 每隔半天清理一次过去的历史数据 防止数据堆积导致IO时间过长  后因采集数据暂停，所以该功能暂时关闭
//            RxJavaUtils.polling(5, 12 * 60 * 60,
//                    aLong -> RxJavaUtils.doInIOThread(new RxIOTask<Object>(null) {
//                        @Override
//                        public Void doInIOThread(Object i) {
//                            for (Sensor sensor : RoomSensor.getAllAvailableSensors()) {
//                                sensor.clearHistoryData();
//                            }
//                            return null;
//                        }
//                    }));
            //持续采集各种传感器数据
            PollingTask.getInstance().startPollingTaskOnIOThread(RxTag.TAG_COLLECT_SENSOR, Variable.SENSOR_REFRESH_TIME, () -> {
                for (Sensor sensor : getAllAvailableSensors()) {
                    sensor.getAllSensorData();
                }
            });
        }
    }

    /**
     * 获得所有传感器
     */
    public static List<Sensor> getAllSensors() {
        List<Sensor> devices = new ArrayList<>();
        Collections.addAll(devices, outdoorTHSensor, consumptionSensor, airTHSensor, co2OutdoorSensor);
        devices.addAll(IndoorTHSensorUtil.getAllSensors());
        devices.addAll(IndoorCO2SensorUtil.getAllSensors());
        devices.addAll(IndoorAmmoniaSensorUtil.getAllSensors());
        devices.addAll(IndoorFloorTSensorUtil.getAllSensors());
        return devices;
    }

    /**
     * 获得所有传感器名字
     */
    public static List<String> getAllSensorNames() {
        List<String> names = new ArrayList<>();
        for (Sensor sensor : getAllSensors()) {
            names.add(sensor.getName());
        }
        return names;
    }

    /**
     * 获得所有可用传感器
     */
    public static List<Sensor> getAllAvailableSensors() {
        List<Sensor> devices = new ArrayList<>();
        Collections.addAll(devices, outdoorTHSensor, consumptionSensor, airTHSensor, co2OutdoorSensor);
        Iterator<Sensor> iterator = devices.iterator();
        while (iterator.hasNext()) {
            if (!iterator.next().isAvailable()) {
                iterator.remove();
            }
        }
        devices.addAll(dynamicCO2SensorList);
        devices.addAll(dynamicAmmoniaSensorList);
        devices.addAll(dynamicFloorTSensorList);
        devices.addAll(dynamicTHSensorList);
        return devices;
    }

    /**
     * 获取室内平均温度
     */
    public static double getAverageIndoorTemperature() {
        double sumOfTemperatures = 0;
        int numberOfEnabledSensors = 0;
        for (THSensor sensor : dynamicTHSensorList) {
            if (sensor.temperature == 0) {
                continue;
            }
            sumOfTemperatures += sensor.temperature;
            numberOfEnabledSensors++;
        }
        for (GasSensor sensor : dynamicCO2SensorList) {
            if (sensor.getTemperature() == 0) {
                continue;
            }
            sumOfTemperatures += sensor.getTemperature();
            numberOfEnabledSensors++;
        }
        for (GasSensor sensor : dynamicAmmoniaSensorList) {
            if (sensor.getTemperature() == 0) {
                continue;
            }
            sumOfTemperatures += sensor.getTemperature();
            numberOfEnabledSensors++;
        }
        if (numberOfEnabledSensors == 0 || sumOfTemperatures == 0) {
            return 0.0;
        }
        return Math.round((sumOfTemperatures / numberOfEnabledSensors + RoomSetting.getBiasTemp()) * 10.0) / 10.0;
    }

    /**
     * 获取未叠加校准偏差的室内平均湿度，供湿度上限安全保护使用。
     */
    public static double getBeforeCalibratedIndoorHumidity() {
        double sumOfHumidities = 0.0;
        int numberOfEnabledSensors = 0;

        for (THSensor sensor : dynamicTHSensorList) {
            if (sensor.humidity <= 0 || sensor.humidity > 100) {
                continue;
            }
            sumOfHumidities += sensor.humidity;
            numberOfEnabledSensors++;
        }

        for (GasSensor sensor : dynamicCO2SensorList) {
            if (sensor.getHumidity() <= 0 || sensor.getHumidity() > 100) {
                continue;
            }
            sumOfHumidities += sensor.getHumidity();
            numberOfEnabledSensors++;
        }

        for (GasSensor sensor : dynamicAmmoniaSensorList) {
            if (sensor.getHumidity() <= 0 || sensor.getHumidity() > 100) {
                continue;
            }
            sumOfHumidities += sensor.getHumidity();
            numberOfEnabledSensors++;
        }

        if (numberOfEnabledSensors == 0) {
            return 0.0;
        }

        return Math.round(sumOfHumidities / numberOfEnabledSensors * 10.0) / 10.0;
    }
    /**
     * 获取叠加校准偏差后的室内平均湿度，供自动控制、界面显示和上报使用。
     */
    public static double getAverageIndoorHumidity() {
        double averageHumidity = getBeforeCalibratedIndoorHumidity();

        if (averageHumidity == 0.0) {
            return 0.0;
        }
        return Math.min(
                Math.round((averageHumidity + RoomSetting.getBiasHumidity()) * 10.0) / 10.0,
                99.9
        );
    }

    /**
     * 获取平均室温
     * 面向用户 使当前温度趋于目标温度
     * 2026年5月3日 10点36分 已废弃该算法
     */
    public static double getAverageIndoorTemperatureForUser() {
        double realValue = getAverageIndoorTemperature();
        if (RoomSetting.getType() == 4) {
            // 如果是催青室，直接返回平均温度 不进行调整
            return realValue;
        }
        if (realValue == 0) {
            return 0;
        }
        double targetTemperature = AutoModelSet.getTargetTemperature();
        double setBias = Variable.AUTO_DO_NOTHING_TEMPERATURE_FULL;
        double unRealValue;
        if (realValue > targetTemperature + setBias) {
            // 当前温度高于目标温度 使当前温度趋于目标温度
            unRealValue = realValue - setBias;
        } else if (realValue < targetTemperature - setBias) {
            // 当前温度低于目标温度 使当前温度趋于目标温度
            unRealValue = realValue + setBias;
        } else {
            // 当前温度在目标温度灵活值域内 使当前温度等于目标温度
            unRealValue = targetTemperature;
        }
        return Math.round(unRealValue * 10.0) / 10.0;
    }

    /**
     * 获得地面平均温度
     *
     * @return
     */
    public static double getFloorTemperature() {
        if (dynamicFloorTSensorList.isEmpty()) {
            return 0;
        }
        double result = 0;
        for (FloorTSensor sensor : dynamicFloorTSensorList) {
            result += sensor.getTemperature();
        }
        return Math.round(result / dynamicFloorTSensorList.size() * 100.0) / 100.0;
    }
}
