package cn.iocoder.yudao.module.mes.controller.admin.mqtt;

import cn.hutool.core.util.RandomUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.iot.controller.admin.mqttdatarecord.MqttDataService;
import cn.iocoder.yudao.module.iot.controller.admin.mqttdatarecord.vo.MqttDataRecordPageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.mqttrecord.vo.MqttRecordSaveReqVO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.formula.FormulaRecordDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.mqttdatarecord.MqttDataRecordDO;
import cn.iocoder.yudao.module.iot.dal.mysql.formula.FormulaRecordMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.mqttdatarecord.MqttDataRecordMapper;
import cn.iocoder.yudao.module.iot.service.device.DeviceService;
import cn.iocoder.yudao.module.iot.service.mqttrecord.MqttRecordService;
import com.alibaba.fastjson.JSON;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 数采记录")
@RestController
@RequestMapping("/iot/mqtt-server")
@Validated
public class MqttServerDataController {

    @Resource
    private MqttDataRecordMapper mqttDataRecordMapper;
    @Resource
    private MqttRecordService mqttRecordService;
    @Resource
    private DeviceService deviceService;
    @Resource
    private MqttDataService mqttDataService;

    @PostMapping("/create")
    @Operation(summary = "创建设备数据记录")
    public CommonResult<Long> createMqttDataRecord(@RequestBody MqttDataSaveVO saveVO) {
        System.out.println(saveVO.toString());
        if(StringUtils.isNotEmpty(saveVO.getTopic()) && saveVO.getPayload()!=null){
            List<MqttDataRecordDO> list = new ArrayList<>();
            boolean valid = false;
            for (String key: saveVO.getPayload().keySet()) {
                String value = saveVO.getPayload().get(key);
                //检查值是否有效，有可能都是空值那就不存
                if(StringUtils.isNotBlank(value))
                    valid = true;
                else continue;

                MqttDataRecordDO recordDO = new MqttDataRecordDO().setDeviceName(saveVO.getTopic())
                        .setAttribute(key).setAttrValue(value);
                list.add(recordDO);

            }
            if(list.size()>0 && valid){
                //保存单个值
                mqttDataRecordMapper.insertBatch(list);
                //保存原值
                MqttRecordSaveReqVO createReqVO = new MqttRecordSaveReqVO();
                //createReqVO.setDeviceCode(saveVO.getTopic());
                createReqVO.setDeviceName(saveVO.getTopic());
                createReqVO.setGatewayCode("");
                createReqVO.setDeviceDataTime(LocalDateTime.now());
                createReqVO.setDeviceData(JSON.toJSONString(saveVO.getPayload()));
                mqttRecordService.createMqttRecord(createReqVO);

                DeviceDO deviceDO = deviceService.getDeviceByTopic(saveVO.getTopic());
                if(deviceDO!=null){
                    //告警检测
                    mqttDataService.checkDeviceAlert(saveVO.getPayload(), deviceDO);
                    //更新iot设备在线状态
                    mqttDataService.updateDeviceStatus(deviceDO);
                }
            }
        }
        return success(1L);
    }

    @GetMapping("/getValue")
    @Operation(summary = "获得设备数据最新值")
    public CommonResult<String> getByDeviceAndAttr(@RequestParam("deviceName") String deviceName
            ,@RequestParam("attribute") String attribute) {
        MqttDataRecordPageReqVO reqVO = new MqttDataRecordPageReqVO().setDeviceName(deviceName).setAttribute(attribute);

        MqttDataRecordDO mqttDataRecord = mqttDataRecordMapper.selectLastOne(reqVO);
        return success(mqttDataRecord.getAttrValue());
    }
    @GetMapping("/getList")
    @Operation(summary = "获得设备数据列表默认十条")
    public CommonResult<List<MqttDataRecordDO>> getList(MqttDataRecordPageReqVO reqVO) {
        return success(mqttDataRecordMapper.select(reqVO));
    }
    @GetMapping("/getSum")
    @Operation(summary = "获得设备数据汇总")
    public CommonResult<BigDecimal> getSum(MqttDataRecordPageReqVO reqVO) {
        return success(mqttDataRecordMapper.selectSum(reqVO));
    }
    @Resource
    private FormulaRecordMapper formulaRecordMapper;
    @PostMapping("/getSimulateValue")
    @Operation(summary = "模拟数据最新值")
    public CommonResult<Double> getSimulateValue(@RequestParam("random")int random,@RequestParam("type")String type
            ,@RequestParam("id")Long id,@RequestParam("plusValue") double plusValue) {
        if(id!=null){
            FormulaRecordDO recordDO = formulaRecordMapper.selectById(id);
            if(recordDO==null)return success(BigDecimal.ZERO.doubleValue());
            if(random == 1){
                if(type.equals("int")){
                    int i = RandomUtil.randomInt(1,10);
                    recordDO.setDataValue(recordDO.getDataValue().add(BigDecimal.valueOf(i)));
                }
                if(type.equals("double")){
                    double i = RandomUtil.randomDouble(1,10);
                    recordDO.setDataValue(recordDO.getDataValue().add(BigDecimal.valueOf(i)));
                }
            }
            else{
               recordDO.setDataValue(recordDO.getDataValue().add(BigDecimal.valueOf(plusValue)));
            }
            formulaRecordMapper.updateById(recordDO);
            return success(recordDO.getDataValue().doubleValue());
        }
        return success(BigDecimal.ZERO.doubleValue());
    }
    @GetMapping("/setSimulateValue")
    @Operation(summary = "设置模拟数据默认值")
    public CommonResult<String> setSimulateValue(@RequestParam("id")Long id,@RequestParam("resetValue") double resetValue) {
        if(id!=null){
            FormulaRecordDO recordDO = formulaRecordMapper.selectById(id);
            if(recordDO==null)return success("操作失败");

            recordDO.setDataValue(BigDecimal.valueOf(resetValue));
            formulaRecordMapper.updateById(recordDO);
            return success("操作失败");
        }
        return success("操作失败");
    }
}