package vip.xiaonuo.coldchain.modular.qp.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.jfcloud.influxdb.service.JfcloudInfluxDBService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import vip.xiaonuo.coldchain.core.bean.influxdb.SensorData;
import vip.xiaonuo.coldchain.core.event.SensorDataEvent;
import vip.xiaonuo.coldchain.modular.monitortargetregion.entity.MonitorTargetRegion;
import vip.xiaonuo.coldchain.modular.monitortargetregion.service.MonitorTargetRegionService;
import vip.xiaonuo.coldchain.modular.qp.config.QpApi;
import vip.xiaonuo.coldchain.modular.qp.service.QPService;
import vip.xiaonuo.coldchain.modular.qp.vo.QpAlertConfigVo;
import vip.xiaonuo.common.enums.CommonDeleteFlagEnum;

import java.util.List;

@Slf4j
@Service
public class QPServiceImpl implements QPService {

    @Resource
    private JfcloudInfluxDBService jfcloudInfluxDBService;

    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    @Resource
    private QpApi qpApi;

    @Resource
    private MonitorTargetRegionService monitorTargetRegionService;

    @Override
    public void save(String param) {
        log.info("青萍设备数据接收：{}", param);

        SensorData sensorData = new SensorData();
        JSONObject mapJson = JSONUtil.parseObj(param);
        JSONObject payloadJson = mapJson.getJSONObject("payload");
        JSONObject infoJson = payloadJson.getJSONObject("info");
        sensorData.setDeviceId(infoJson.getStr("mac"));
        sensorData.setCreateTime(infoJson.getStr("createAt"));
        JSONObject productJson = infoJson.getJSONObject("product");
        sensorData.setModelName(productJson.getStr("code"));
        JSONArray dataArray = payloadJson.getJSONArray("data");
        List<Object> list = dataArray.stream().toList();
        for (Object o : list) {
            JSONObject dataJson = JSONUtil.parseObj(JSONUtil.toJsonStr(o));
            JSONObject timestampJson = dataJson.getJSONObject("timestamp");
            if (timestampJson != null) {
                String timestamp = timestampJson.getStr("value");
                sensorData.setCreateTime(timestamp);
            }
            JSONObject batteryJson = dataJson.getJSONObject("battery");
            if (batteryJson != null) {
                Float battery = batteryJson.getFloat("value");
                sensorData.setBattery(battery);
            }
            JSONObject temperatureJson = dataJson.getJSONObject("temperature");
            if (temperatureJson != null) {
                Float temperature = temperatureJson.getFloat("value");
                sensorData.setTemperature(temperature);
            }
            JSONObject humidityJson = dataJson.getJSONObject("humidity");
            if (humidityJson != null) {
                Float humidity = humidityJson.getFloat("value");
                sensorData.setHumidity(humidity);
            }
            JSONObject co2Json = dataJson.getJSONObject("co2");
            if (co2Json != null) {
                Float co2 = co2Json.getFloat("value");
                sensorData.setCo2(co2);
            }
        }

        jfcloudInfluxDBService.writePojo(sensorData);
    }

    @Override
    public void triggerEvent(String param) {
        log.info("青萍设备事件接收 ：{}", param);

        JSONObject paramObj = JSONUtil.parseObj(param);
        JSONObject payloadObj = paramObj.getJSONObject("payload");
        String mac = payloadObj.getByPath("info.mac", String.class);

        //根据mac查询deviceId
        MonitorTargetRegion region = monitorTargetRegionService.getOne(new LambdaQueryWrapper<>(MonitorTargetRegion.class)
                .eq(MonitorTargetRegion::getSensorCode, mac)
                .eq(MonitorTargetRegion::getDeleteFlag, CommonDeleteFlagEnum.NOT_DELETE)
                .last("limit 1"));

        JSONArray events = payloadObj.getJSONArray("events");
        for (int i = 0; i < events.size(); i++) {
            JSONObject event = events.getJSONObject(i);
            //触发提醒
            if (!"alert".equals(event.getStr("action"))) {
                continue;
            }

            QpAlertConfigVo alertConfig = event.get("alert_config", QpAlertConfigVo.class);
            SensorData sensorData = new SensorData();
            sensorData.setModelName(mac);
            sensorData.setDeviceId(mac);
            sensorData.setRoads(region.getSensorRoute());

            if (alertConfig.getMetric_name().equals("battery")) {
                log.info("青萍设备电量预警 mac={}", mac);
                sensorData.setBattery(event.getByPath("data.battery.value", Float.class));
            } else if (alertConfig.getMetric_name().equals("temperature")) {
                log.info("青萍设备温度预警 mac={}", mac);
                sensorData.setTemperature(event.getByPath("data.temperature.value", Float.class));
            } else if (alertConfig.getMetric_name().equals("humidity")) {
                log.info("青萍设备湿度预警 mac={}", mac);
                sensorData.setHumidity(event.getByPath("data.humidity.value", Float.class));
            } else if (alertConfig.getMetric_name().equals("co2")) {
                log.info("青萍设备二氧化碳预警 mac={}", mac);
                String co2Str = event.getByPath("data.co2.value", String.class);
                if (StrUtil.isEmpty(co2Str)) {
                    //没有二氧化碳的数据，查询设备列表获取
                    com.alibaba.fastjson.JSONObject jsonObject = qpApi.getDeviceData(mac);
                    co2Str = jsonObject.getJSONObject("co2").getString("value");
                }
                sensorData.setCo2(Float.parseFloat(co2Str));
            }

            log.info("青萍设备发送提醒 mac={} sensorData={}", mac, JSONUtil.toJsonStr(sensorData));
            try {
                applicationEventPublisher.publishEvent(new SensorDataEvent(this, sensorData));
            } catch (Exception e) {
                log.error("保存传感器数据失败: {}", sensorData, e);
            }
        }
    }
}
