package com.ho.datacollect.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.ho.business.entity.ModelDeviceColComp;
import com.ho.business.service.ModelDeviceService;
import com.ho.business.service.TopologyService;
import com.ho.business.vo.DeviceTransfer;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.service.RedisService;
import com.ho.common.tools.util.UpdateObjectUtil;
import com.ho.datacollect.api.constant.DataCollectConstant;
import com.ho.datacollect.api.vo.req.add.DataSetParam;
import com.ho.datacollect.api.vo.req.add.TdUniversalMeterReq;
import com.ho.datacollect.feignclient.DataCollectTdFeignClient;
import com.ho.datacollect.service.DataCollectService;
import com.ho.datacollect.service.ModelConvertService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @Description 通用电表
 * Author yule
 * Date 2022/10/11 10:09
 */
@Service(DataCollectConstant.KEY_MAP.UNIVERSAL_METER)
@Slf4j
public class UniversalMeterDataCollectServiceImpl implements DataCollectService {

    @Autowired
    TopologyService topologyService;

    @Autowired
    DataCollectTdFeignClient tdFeignClient;

    @Autowired
    RedisService redisService;

    @Autowired
    UpdateObjectUtil updateObjectUtil;

    @Autowired
    ModelConvertService modelConvertService;

    @Autowired
    ModelDeviceService modelDeviceService;

    @Override
    public void doService(DataSetParam dataSetParam) {
        String deviceType = null;
        try {
            //
            log.info("UniversalMeterDataCollectServiceImpl: dataSetParam:{}" ,dataSetParam);
            //拼接表名
            Integer groupId = dataSetParam.getGroupId();
            Integer stationId = dataSetParam.getStationId();
            Integer srcId = dataSetParam.getSrcId();
            //设备类型
            deviceType  =dataSetParam.getDeviceType();
            //时间送过来是个字符串,要转成Date类型
            String freezeTime = dataSetParam.getFreezeTime();
            //捕获异常,如果时间转换出错,就使用现在的时间
            DateTime ts = new DateTime();
            Date createTime = new Date();
            Date updateTime = Convert.toDate(freezeTime);
            try {
                ts = DateUtil.parse(freezeTime, CommonConstant.DATE_YMD_HMSS);
            } catch (Exception e) {
                log.error("freezeTime 格式转换时出错");
            }
            String tableName = new StringBuilder().append(groupId).append(DataCollectConstant.TABLE_LINK)
                    .append(stationId).append(DataCollectConstant.TABLE_LINK).append(srcId).toString();
            log.info("产生的tableName: {}" ,tableName);
            //创建新增对象
            TdUniversalMeterReq tdUniversalMeterReq = new TdUniversalMeterReq();
            //共通属性
            tdUniversalMeterReq.setGroupId(groupId);
            tdUniversalMeterReq.setStationId(stationId);
            tdUniversalMeterReq.setSrcId(srcId);
            tdUniversalMeterReq.setTableName(tableName);
            tdUniversalMeterReq.setDeviceType(deviceType);
            JSONObject dataSet = dataSetParam.getDataSet();
            log.info("deviceType: {}" ,deviceType);
            log.info("dataSet: {} " ,dataSet);

            //从设备定义表中得到需要哪些数据，不是所有数据都要入库
            //需要入库的字段是根据外部设备模型查出来的字段集合
            //dataSet赋值6个
            if(dataSet==null){
                dataSet= new JSONObject();
            }
            JSONObject modifyDataObject = new JSONObject();
            dataSet.forEach((k, v) -> {
                DeviceTransfer deviceTransfer = new DeviceTransfer();
                deviceTransfer.setValue(new BigDecimal(String.valueOf(v)));
                deviceTransfer.setUpdateTime(updateTime);
                //通讯故障保持原有状态
                if(DataCollectConstant.COMMUNICATION_STATUS.equals(k)){
                    modifyDataObject.put(k,v);
                }else{
                    modifyDataObject.put(k,deviceTransfer);
                }
            });
            List<ModelDeviceColComp> compList = modelDeviceService.getCompListByType(CommonConstant.ModelDeviceType.DEVICE, deviceType,null);
//            if (compList.isEmpty()) {
//                log.error("该设备未配置映射字段");
//                return;
//            }
            //入库的数据是设备原始格式,但需要经过一轮匹配,匹配到才入库不是每个字段都入库
            JSONObject inputData = modelConvertService.getInputDataByDeviceType(dataSet, compList, deviceType);
//            if (inputData.isEmpty()) {
//                log.error("转换后无匹配的数据字段 ,无需入库");
//                return;
//            }
            //时序数据对象, 把两个时间字段放进去
            inputData.put(DataCollectConstant.TS, ts);
            inputData.put(DataCollectConstant.CREATE_TIME, createTime);
            //将设备数据格式转换为平台数据格式(注意这个是平台数据格式)
            JSONObject modelObject = modifyDataObject;
            modelObject.put(DataCollectConstant.TS, ts);
            //最后更新时间
            modelObject.put(DataCollectConstant.UPDATE_TIME,createTime);
            JSONObject convertInputData = modelConvertService.convertModelFromDevice(modifyDataObject, compList, deviceType);
            log.info("映射的字段 convertInputData:" + convertInputData);
            if(!convertInputData.isEmpty()){
                modelObject.putAll(convertInputData);
            }
            //先判断缓存中是否存在
            String redisKey = deviceType + ":" + stationId + ":" + srcId;
            Boolean flag = redisService.hasKey(redisKey);
            //缓存的数据是转换后的平台模型
            if (!flag) {
                //没数据新建一个createTime
                modelObject.put(DataCollectConstant.CREATE_TIME, createTime);
                //设备类型塞进去
                modelObject.put(DataCollectConstant.DEVICE_TYPE, deviceType);
            }
            log.info("modelObject: {}", modelObject);
            redisService.hmset(redisKey, modelObject);
            //入库时候调用不同逆变器入库方法，因为数据格式不同
            inputData.putAll(dataSet);
            log.info("inputData:{},", inputData);
            tdUniversalMeterReq.setUniversalMeter(inputData);
            tdFeignClient.insertUniversalMeterOne(tdUniversalMeterReq);
        } catch (Exception e) {
            log.error("添加通用电表:{}  失败: {}" ,deviceType,  e.getMessage());
        }
    }
}
