package com.sckw.slope.detection.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sckw.core.exception.BusinessException;
import com.sckw.core.exception.SystemException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.constant.NumberConstant;
import com.sckw.core.model.enums.DeviceEnum;
import com.sckw.core.model.enums.DictEnum;
import com.sckw.core.model.enums.DictItemEnum;
import com.sckw.core.model.enums.MessageLogEnum;
import com.sckw.core.model.page.PageRes;
import com.sckw.core.utils.IdWorker;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.constant.HttpStatus;
import com.sckw.core.web.response.HttpResult;
import com.sckw.slope.detection.dao.mysql.*;
import com.sckw.slope.detection.dao.tdengine.InsTablesMapper;
import com.sckw.slope.detection.dao.tdengine.SlopeDataMapper;
import com.sckw.slope.detection.model.dos.mysql.*;
import com.sckw.slope.detection.model.dos.tdengine.InsTables;
import com.sckw.slope.detection.model.dos.tdengine.SlopeData;
import com.sckw.slope.detection.model.dto.*;
import com.sckw.slope.detection.model.param.*;
import com.sckw.slope.detection.model.vo.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lfdc
 * @description 设备service
 * @date 2023-10-31 10:10:27
 */
@Slf4j
@Service
public class DeviceService {

    private static final Long equatorial_circumference = 40075020000L;

    @Autowired
    CommonService commonService;

    @Autowired
    KwsDeviceMapper deviceMapper;

    @Autowired
    KwsAlarmMapper alarmMapper;

    @Autowired
    SlopeDataMapper slopeDataMapper;

    @Autowired
    InsTablesMapper insTablesMapper;

    @Autowired
    KwsDeviceModelMapper deviceModelMapper;

    @Autowired
    KwsProjectMapper projectMapper;

    @Autowired
    KwsIntegrationMapper integrationMapper;

    @Autowired
    KwsProjectDeviceMapper projectDeviceMapper;

    @Autowired
    KwsDeviceModelPartMapper deviceModelPartMapper;

    @Autowired
    KwsDeviceIntegrationMapper deviceIntegrationMapper;

    @Autowired
    KwsDeviceReferenceMapper deviceReferenceMapper;


    @Transactional
    public HttpResult dels(String ids, HttpServletRequest response) {
        KwsDevice device = deviceMapper.selectOne(new LambdaQueryWrapper<KwsDevice>()
                .eq(KwsDevice::getId, ids));
        if (Objects.isNull(device)) {
            throw new SystemException(HttpStatus.QUERY_FAIL_CODE, HttpStatus.DEVICE_NOT_EXISTS);
        }
        //验证设备存在与项目关联管理 设备不允许删除
        List<KwsProjectDevice> projectDevices = projectDeviceMapper.selectList(
                new LambdaQueryWrapper<KwsProjectDevice>()
                        .eq(KwsProjectDevice::getDeviceId, ids)
                        .eq(KwsProjectDevice::getDelFlag, NumberConstant.ZERO)
        );
        if (!CollectionUtils.isEmpty(projectDevices) && projectDevices.size()>0){
            return HttpResult.error(HttpStatus.GLOBAL_EXCEPTION_CODE,"设备与项目存在关联,解除关联后,可允许删除");
        }
        HeaderData headerData = commonService.getHeaderData(response);
        //List<Long> list = StringUtils.splitStrToList(ids, Long.class);
        int update = deviceMapper.update(null, new LambdaUpdateWrapper<KwsDevice>()
                .in(KwsDevice::getId, ids)
                .eq(KwsDevice::getMountainId, headerData.getMountainId())
                .set(KwsDevice::getDelFlag, NumberConstant.ONE));
        if (update < 1) {
            throw new BusinessException("删除设备异常");
        }
        //获取新增设备的型号

        KwsDeviceModel model = deviceModelMapper.selectOne(new LambdaQueryWrapper<KwsDeviceModel>()
                .eq(KwsDeviceModel::getId, device.getModelId()));
        Map<String, Object> logMap = new HashMap<>(NumberConstant.SIXTEEN);
        logMap.put("name", device.getName());
        logMap.put("type", model.getName());
        commonService.insertLog(MessageLogEnum.DEVICE_DELETE, headerData, logMap, Long.parseLong(headerData.getUpdateBy()));
        return HttpResult.ok("删除设备成功");
    }

    public HttpResult deviceAll(String projectId,HttpServletRequest request) {
        //设备至关联多只支持两层结构，因此子级设备不能在【所属设备名称】中被查询出来
        HeaderData headerData = commonService.getHeaderData(request);
        List<DeviceDataDTO> list = deviceMapper.selectDeviceAllNotDeviceRelation(projectId,headerData.getCompanyId());
        return HttpResult.ok(list);
    }

    /**
     * 设备管理分页查询
     *
     * @param deviceQuery 请求分页
     * @param response    http流
     * @return 返回值
     */
    public PageRes select(DeviceQuery deviceQuery, HttpServletRequest response) {
        PageHelper.startPage(deviceQuery.getPage(), deviceQuery.getPageSize());
        HeaderData headerData = commonService.getHeaderData(response);
        deviceQuery.setMountainId(headerData.getMountainId());
        List<DeviceVo> list = deviceMapper.selectByDeviceParam(deviceQuery);
        PageInfo<DeviceVo> pageInfo = new PageInfo<>(list);
        if (CollectionUtils.isEmpty(list)) {
            return PageRes.build(pageInfo, list);
        }
        List<Long> devicesId = list.stream().map(DeviceVo::getId).toList();
        List<Map<String, Long>> alarmData = alarmMapper.selectByDevicesId(devicesId);
        List<Map<String, Object>> dataError = alarmMapper.selectDataByDevicesId(devicesId);

        Map<String, SystemDict> deviceType = commonService.getDictList(null, new HashMap<>() {{
            put("code", DictEnum.DEVICE_TYPE.getCodeType());
            put("type", "1");
        }});
        /*for (SystemDict value : deviceType.values()) {
            if (vo.getDeviceType().toString().equals(value.getValue())) {
                vo.setDeviceTypeName(value.getLabel());
            }
        }*/

        for (DeviceVo vo : list) {
            vo.setStatusText(DeviceEnum.getName(vo.getStatus()));
            vo.setDeviceErrorCount(0L);
            vo.setDataErrorCount(0L);
            if (!CollectionUtils.isEmpty(alarmData)) {
                for (int i = 0; i < alarmData.size(); i++) {
                    Map<String, Long> map = alarmData.get(i);
                    if (map.get("device_id").toString().equals(vo.getId().toString())) {
                        //vo.setDataErrorCount(map.get("count"));
                        String count = map.get("count").toString();
                        vo.setDeviceErrorCount(Long.parseLong(count));
                    }
                }
            }
            if (!CollectionUtils.isEmpty(dataError)) {
                for (int i = 0; i < dataError.size(); i++) {
                    Map<String, Object> map = dataError.get(i);
                    if (map.get("device_id").toString().equals(vo.getId().toString())) {
                        String count = map.get("count").toString();

                        vo.setDataErrorCount(Long.parseLong(count));
                        //vo.setDeviceErrorCount(map.get("count"));
                    }
                }
            }
            if(Objects.nonNull(vo.getDeviceType())){
                for (SystemDict value : deviceType.values()) {
                    if (vo.getDeviceType().toString().equals(value.getValue())) {
                        vo.setDeviceTypeName(value.getLabel());
                    }
                }
            }

            KwsDeviceReference deviceHas = deviceReferenceMapper.selectOne(new LambdaQueryWrapper<KwsDeviceReference>()
                    .eq(KwsDeviceReference::getDeviceId, vo.getId())
                    .eq(KwsDeviceReference::getDelFlag, NumberConstant.ZERO)
                    .last("LIMIT 1")
                    .orderByDesc(KwsDeviceReference::getId)
            );
            if (!Objects.isNull(deviceHas)) {
                vo.setChangeBy(deviceHas.getCreateBy());
                vo.setChangeTime(deviceHas.getCreateTime());
            }
        }
        return PageRes.build(pageInfo, list);
    }

    /**
     * 新增设备
     *
     * @param deviceAdd 请求参数
     * @param request   http流
     * @return 返回值
     */
    @Transactional
    public HttpResult add(DeviceAdd deviceAdd, HttpServletRequest request) {
        KwsDevice deviceHas = deviceMapper.selectOne(new LambdaQueryWrapper<KwsDevice>()
                .eq(KwsDevice::getSnCode, deviceAdd.getSnCode()));
        if (!Objects.isNull(deviceHas)) {
            throw new SystemException(HttpStatus.QUERY_FAIL_CODE, HttpStatus.DEVICE_SN_EXISTS);
        }
        HeaderData headerData = commonService.getHeaderData(request);
        KwsDevice device = new KwsDevice();
        BeanUtils.copyProperties(deviceAdd, device);
        LocalDateTime now = LocalDateTime.now();
        long id = new IdWorker(NumberConstant.ONE).nextId();
        device.setId(id);
        String newStr = deviceAdd.getSnCodeFullName().replace("-", "").toLowerCase();
        device.setSnCode(newStr);
        device.setCreateBy(Long.parseLong(headerData.getCreateBy()));
        device.setCreateTime(now);
        device.setStatus(DeviceEnum.IDENTIFYING.getCode());
        device.setOnline(NumberConstant.ZERO);
        device.setUpdateBy(Long.parseLong(headerData.getUpdateBy()));
        device.setUpdateTime(now);
        device.setMountainId(headerData.getMountainId());
        deviceMapper.insert(device);
        //新增到数据表kws_device_Integration
        KwsDeviceIntegration deIntergration = new KwsDeviceIntegration();
        String[] temp;//接收分割后的数组
        if(Objects.nonNull(deviceAdd.getIntegrationId())){
            temp = deviceAdd.getIntegrationId().split(Global.COMMA);
            for (int i = 0; i < temp.length; i++) {
                long interId = new IdWorker(NumberConstant.ONE).nextId();
                deIntergration.setId(interId);
                deIntergration.setDeviceId(id);
                deIntergration.setMountainId(headerData.getMountainId());
                deIntergration.setIntegrationId(Long.parseLong(temp[i]));
                deIntergration.setCreateBy(Long.parseLong(headerData.getCreateBy()));
                deIntergration.setCreateTime(now);
                deIntergration.setStatus(NumberConstant.ZERO);
                deIntergration.setUpdateBy(Long.parseLong(headerData.getUpdateBy()));
                deIntergration.setUpdateTime(now);
                deviceIntegrationMapper.insert(deIntergration);
            }
        }
        //新增log
        //获取新增设备的型号
        KwsDeviceModel model = deviceModelMapper.selectOne(new LambdaQueryWrapper<KwsDeviceModel>()
                .eq(KwsDeviceModel::getId, device.getModelId()));
        Map<String, Object> logMap = new HashMap<>(NumberConstant.SIXTEEN);
        logMap.put("name", device.getName());
        logMap.put("type", model.getName());
        commonService.insertLog(MessageLogEnum.DEVICE_ADD, headerData, logMap, Long.parseLong(headerData.getUpdateBy()));
        return HttpResult.ok();
    }

    public HttpResult detail(Long id, HttpServletRequest response) {
        KwsDevice device = deviceMapper.selectOne(new LambdaQueryWrapper<KwsDevice>()
                .eq(KwsDevice::getId, id));
        DeviceVo vo = new DeviceVo();
        BeanUtils.copyProperties(device, vo);

        KwsDeviceModel deviceModel = deviceModelMapper.selectOne(new LambdaQueryWrapper<KwsDeviceModel>()
                .eq(KwsDeviceModel::getId, vo.getModelId()));
        if (deviceModel != null) {
            vo.setDeviceType(Integer.parseInt(deviceModel.getDeviceType()));
            vo.setMName(deviceModel.getName());
            vo.setManufacturer(deviceModel.getManufacturer());
            vo.setManufacturerContacts(deviceModel.getManufacturerContacts());
            vo.setManufacturerPhone(deviceModel.getManufacturerPhone());
        }
        //获取字典
        Map<String, SystemDict> dictList = commonService.getDictList(null, new HashMap<>() {{
            put("code", DictEnum.MODEL_PART.getCodeType());
            put("type", "1");
        }});
        //获取设备基准信息
        HeaderData headerData = commonService.getHeaderData(response);
        List<KwsDeviceReference> references = deviceReferenceMapper.selectList(new LambdaQueryWrapper<KwsDeviceReference>()
                .eq(KwsDeviceReference::getDeviceId, id)
                .eq(KwsDeviceReference::getDelFlag, NumberConstant.ZERO)
        );
        String snCode = device.getSnCode();
        InsTables insTables = insTablesMapper.selectTableIsExit("device_" + snCode);
        //if (insTables == null) {
            //insTablesMapper.createTable("device_" + snCode);
        //}
        //获取基础要数
        List<DevicePartModelVo> partData = new ArrayList<>();
        partData = deviceModelPartMapper.selectByModelId(deviceModel.getId());
        if (!Objects.isNull(partData)) {//首先在kws_device_model_part获取数据，然后到字典中查询
            for (DevicePartModelVo part : partData) {
                for (SystemDict value : dictList.values()) {
                    if (part.getPartName().equals(value.getValue())) {
                        part.setPartNameDesc(value.getLabel());
                        part.setUnit(value.getUrl());
                        part.setUnitNe(value.getRemark());
                    }
                }
                if(insTables != null){
                    SlopeData slopeData = slopeDataMapper.selectListByLine(snCode, part.getPartName());//获取到当前测量值
                    if (!Objects.isNull(slopeData)) {
                        part.setCurrentData(slopeData.getVal());
                        //BigDecimal currentValue = commonService.getValueByOffset(value.toString(), obj.get("item").toString(), reference);
                        //part.setOffset(slopeData.getVal());
                    }
                }
                references.forEach(re -> {
                    if (part.getPartName().equals(re.getItem())) {
                        part.setPartBaseData(re.getOriginalValue().toString());
                        part.setPartCurrentBaseData(re.getCurrentValue().toString());

                        BigDecimal currentValue = commonService.computeOffset(part.getCurrentData(), re.getItem(), re);
                        part.setOffset(String.valueOf(currentValue.doubleValue()));
                    }
                });

            }
            //获取字典
            Map<String, SystemDict> deviceType = commonService.getDictList(null, new HashMap<>() {{
                put("code", DictEnum.DEVICE_TYPE.getCodeType());
                put("type", "1");
            }});
            for (SystemDict value : deviceType.values()) {
                if (vo.getDeviceType().toString().equals(value.getValue())) {
                    vo.setDeviceTypeName(value.getLabel());
                }
            }
            //获取项目详情
            KwsProjectDevice projectDevice = projectDeviceMapper.selectOne(new LambdaQueryWrapper<KwsProjectDevice>()
                    .eq(KwsProjectDevice::getDeviceId, vo.getId())
                    .eq(KwsProjectDevice::getDelFlag, NumberConstant.ZERO)
                    .orderByDesc(KwsProjectDevice::getCreateTime)
                    .last("LIMIT 1")
            );
            if (!Objects.isNull(projectDevice)) {
                vo.setProjectId(projectDevice.getProjectId().toString());
                KwsProject project = projectMapper.selectOne(new LambdaQueryWrapper<KwsProject>()
                        .eq(KwsProject::getId, projectDevice.getProjectId().toString())
                        .eq(KwsProject::getDelFlag, NumberConstant.ZERO)
                );
                if(Objects.nonNull(project)){
                    vo.setProjectName(project.getName().toString());
                }

            }
            vo.setPart(partData);
        }
        //获取集成要素单位
        Map<String, SystemDict> deviceType = commonService.getDictList(null, new HashMap<>() {{
            put("code", DictEnum.INTEGRATION_UNIT.getCodeType());
            put("type", "1");
        }});

        //获取集成要素
        List<DeviceIntegrationVo> intergData = new ArrayList<>();
//        intergData = deviceIntegrationMapper.selectListByParamsAndInterName(vo);
        intergData = deviceIntegrationMapper.selectListParamsAndInterNameByDeviceId(vo.getId());
        if (!Objects.isNull(intergData) && insTables != null) {
            for (DeviceIntegrationVo inter : intergData) {
                List<SlopeData> slopeData = slopeDataMapper.selectListByTwoLine(snCode, inter.getPartNames());//获取到当前测量值--现在只有单一值
                if (!Objects.isNull(slopeData) && slopeData.size()>0) {
                    double data = commonService.returnIntegrationData(snCode,slopeData,inter);
                    inter.setCurrentData(String.valueOf(data));
                    inter.setOffset(String.valueOf(data));
                }
                for (SystemDict value : deviceType.values()) {
                    if (inter.getUnit().toString().equals(value.getValue())) {
                        inter.setUnit(value.getDescription());
                        inter.setUnitNe(value.getDescription());
                    }
                }
                references.forEach(re -> {
                    if (inter.getIntegrationName().equals(re.getItem())) {

                        inter.setIntegrationBaseData(re.getOriginalValue().toString());

                        inter.setIntegrationCurrentBaseData(re.getCurrentValue().toString());
                        //inter.setOffset(re.getOffset().toString());
                    }

                });

            }
            vo.setIntegration(intergData);
        }


        return HttpResult.ok(vo);
    }

    @Transactional
    public HttpResult locationSet(LocationDTO list, HttpServletRequest request) {
        String projectId = list.getProjectId();
        KwsProject project = projectMapper.selectOne(new LambdaQueryWrapper<KwsProject>()
                .eq(KwsProject::getId, Long.parseLong(projectId)));
        HeaderData headerData = commonService.getHeaderData(request);
        List<DeviceLocationDTO> deviceLocationList = list.getDeviceLocationList();
        if (!CollectionUtils.isEmpty(deviceLocationList)) {
            List<String> collect = deviceLocationList.stream().map(DeviceLocationDTO::getDeviceId).collect(Collectors.toList());
            List<KwsDevice> kwsDevices = deviceMapper.selectList(new LambdaQueryWrapper<KwsDevice>()
                    .in(KwsDevice::getId, collect).eq(KwsDevice::getDelFlag, 0));
            deviceLocationList.forEach(device -> {
                deviceMapper.update(null, new LambdaUpdateWrapper<KwsDevice>()
                        .set(KwsDevice::getLogicLng, device.getLogicLng())
                        .set(KwsDevice::getLogicLat, device.getLogicLat())
                        .set(KwsDevice::getLogicAlt, device.getLogicAlt())
                        .set(KwsDevice::getUpdateBy, headerData.getUpdateBy() == null ? null : Long.parseLong(headerData.getUpdateBy()))
                        .set(KwsDevice::getStatus, DeviceEnum.BE_CHECKING.getCode())
                        .eq(KwsDevice::getId, device.getDeviceId())
                );
            });
            List<String> deviceNames = new ArrayList<>();
            if (!CollectionUtils.isEmpty(kwsDevices)) {
                deviceNames = kwsDevices.stream().map(KwsDevice::getName).collect(Collectors.toList());
            }
            StringBuilder deviceName = new StringBuilder();
            if (!CollectionUtils.isEmpty(deviceNames)) {
                for (int i = 0; i < deviceNames.size(); i++) {
                    if (i != deviceNames.size() - 1) {
                        deviceName.append(deviceNames.get(i)).append(",");
                    } else {
                        deviceName.append(deviceNames.get(i));
                    }
                }
            }
            Map<String, Object> logMap = new HashMap<>(NumberConstant.SIXTEEN);
            logMap.put("projectName", project.getName());
            logMap.put("deviceName", deviceName.toString());
            commonService.insertLog(MessageLogEnum.UPDATE_DEVICE_LAY, headerData, logMap, headerData.getUpdateBy() == null ? null : Long.parseLong(headerData.getUpdateBy()));
        }
        return HttpResult.ok();
    }

    @Transactional
    public HttpResult update(DeviceAdd deviceAdd, HttpServletRequest response) {

        KwsDevice deviceHas = deviceMapper.selectOne(new LambdaQueryWrapper<KwsDevice>()
                .eq(KwsDevice::getId, deviceAdd.getId()));
        if (Objects.isNull(deviceHas)) {
            throw new SystemException(HttpStatus.QUERY_FAIL_CODE, HttpStatus.DEVICE_SN_EXISTS);
        }

        KwsDevice device = new KwsDevice();
        BeanUtils.copyProperties(deviceAdd, device);
        device.setId(Long.parseLong(deviceAdd.getId()));
        LocalDateTime now = LocalDateTime.now();
        HeaderData headerData = commonService.getHeaderData(response);
        device.setUpdateBy(Long.parseLong(headerData.getUpdateBy()));
        device.setUpdateTime(now);
        Integer updateStatus = deviceMapper.updateById(device);
        if (updateStatus == 1) {
            int update = deviceIntegrationMapper.update(null, new LambdaUpdateWrapper<KwsDeviceIntegration>()
                    .eq(KwsDeviceIntegration::getDeviceId, deviceAdd.getId())
                    .set(KwsDeviceIntegration::getDelFlag, NumberConstant.ONE)
                    .set(KwsDeviceIntegration::getUpdateBy, Long.parseLong(headerData.getUpdateBy()))
                    .set(KwsDeviceIntegration::getUpdateTime, now));
            //if (update < 1) {
            //throw new BusinessException("删除设备集成要素异常");
            //}

            //新增到数据表kws_device_Integration
            KwsDeviceIntegration deIntergration = new KwsDeviceIntegration();
            String[] temp;//接收分割后的数组
            if (Objects.nonNull(deviceAdd.getIntegrationId())) {
                temp = deviceAdd.getIntegrationId().split(Global.COMMA);

                for (int i = 0; i < temp.length; i++) {
                    long interId = new IdWorker(NumberConstant.ONE).nextId();
                    deIntergration.setId(interId);
                    deIntergration.setDeviceId(Long.parseLong(deviceAdd.getId()));
                    deIntergration.setMountainId(headerData.getCompanyId());
                    deIntergration.setIntegrationId(Long.parseLong(temp[i]));
                    deIntergration.setCreateBy(Long.parseLong(headerData.getCreateBy()));
                    deIntergration.setCreateTime(now);
                    deIntergration.setStatus(NumberConstant.ZERO);
                    deIntergration.setUpdateBy(Long.parseLong(headerData.getUpdateBy()));
                    deIntergration.setUpdateTime(now);
                    deviceIntegrationMapper.insert(deIntergration);
                }
            }
            //新增log
            //获取新增设备的型号
            KwsDeviceModel model = deviceModelMapper.selectOne(new LambdaQueryWrapper<KwsDeviceModel>()
                    .eq(KwsDeviceModel::getId, device.getModelId()));
            Map<String, Object> logMap = new HashMap<>(NumberConstant.SIXTEEN);
            logMap.put("name", device.getName());
            logMap.put("type", model.getName());
            commonService.insertLog(MessageLogEnum.DEVICE_UPDATE, headerData, logMap, Long.parseLong(headerData.getUpdateBy()));
            return HttpResult.ok();
        }

        throw new BusinessException("更新异常");

    }

    /**
     * 设备监测值-原始/当前/测量
     *
     * @param projectId 项目id
     * @param deviceId  设备id
     * @param request   请求流
     * @return 设备信息
     */
    public HttpResult outputValue(String projectId, String deviceId, HttpServletRequest request) {
        HeaderData headerData = commonService.getHeaderData(request);
        KwsDevice kwsDevice = deviceMapper.selectByPrimaryKey(Long.parseLong(deviceId));
        if (kwsDevice == null) {
            return HttpResult.ok();
        }
        List<Integer> status = new ArrayList<>();
        status.add(DeviceEnum.ALREADY_REFERRED_TO.getCode());
        //集成要素
        List<DeviceElementDTO> integratedElementList = deviceIntegrationMapper.selectIntegratedElement(projectId,
                headerData.getMountainId(), status, Long.parseLong(deviceId));


        List<ProjectDeviceVO> projectDeviceList = projectMapper.selectDeviceByProjectId(headerData.getMountainId(), Long.parseLong(projectId), Long.parseLong(deviceId), null);
        List<String> deviceIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(projectDeviceList)) {
            deviceIds = projectDeviceList.stream().map(ProjectDeviceVO::getId).distinct().collect(Collectors.toList());
        }
        //基本要素
        List<KwsDeviceReference> references = deviceReferenceMapper.selectList(new LambdaQueryWrapper<KwsDeviceReference>()
                .eq(KwsDeviceReference::getDeviceId, deviceId)
                .eq(KwsDeviceReference::getMountainId, headerData.getMountainId())
                .eq(KwsDeviceReference::getType, 1)
                .eq(KwsDeviceReference::getDelFlag, NumberConstant.ZERO)
        );
        List<Map<String, DeviceOutputValueVO>> mapList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(references)) {
            references.forEach(re -> {
                Map<String, DeviceOutputValueVO> map = new HashMap<>();
                DeviceOutputValueVO vo = new DeviceOutputValueVO();
                String item = re.getItem();
                Map<String, SystemDict> dictList = commonService.getDictList(null, new HashMap<>() {{
                    put("code", DictEnum.MODEL_PART.getCodeType());
                    put("type", "1");
                }});
                String itemName = dictList == null ? item : (dictList.get(item) == null ? item : dictList.get(item).getLabel());
                BigDecimal originalValue = re.getOriginalValue();
                BigDecimal currentValue = re.getCurrentValue();
                BigDecimal offset = re.getOffset();
                //当前基准值
                vo.setCurrentValue(currentValue == null ? null : currentValue.toString());
                //原始基准值
//                HashMap<String, Object> primitive = new HashMap<>();
//                primitive.put(itemName, originalValue);
                vo.setOriginalValue(originalValue == null ? null : originalValue.toString());
                //当前测量值-TD获取
                HashMap<String, Object> currentMeasurement = new HashMap<>();
                String snCode = kwsDevice.getSnCode();
                InsTables insTables = insTablesMapper.selectTableIsExit("device_" + snCode);
                //if (insTables == null) {
                    //insTablesMapper.createTable("device_" + snCode);
                //}
                SlopeData slopeData = null;
                try {
                    slopeData = slopeDataMapper.selectListByLine(snCode, item);
                } catch (Exception e) {
                    log.error("select tdengine devices error :{}", e.getMessage(), e);
                }
                String val = slopeData == null ? null : slopeData.getVal();
                //存在经度纬度海拔等要素 要进行公式计算
                /**
                 * 经度方向的距离 =  L * cos(A) * ( X / 360）
                 其中：L=40075020000毫米（赤道周长）
                 A=基准值的纬度
                 X=测量值经度 - 基准值经度
                 纬度方向的距离 = Y * 111000000
                 其中： Y =测量值纬度 - 基准值纬度*/
                List<String> itemList = new ArrayList<>();
                itemList.add(DictItemEnum.LONGITUDE_X.getValue());
                if (itemList.contains(re.getItem())) {
                    BigDecimal offsetValue = new BigDecimal("0.00");
                    if (Objects.nonNull(currentValue)) {
                        SlopeData selected = null;
                        try {
                            selected = slopeDataMapper.selectListByLine(kwsDevice.getSnCode(), DictItemEnum.LATITUDE_Y.getValue());
                        } catch (Exception e) {
                            log.error("select tdengine devices error :{}", e.getMessage(), e);
                        }
                        double angleInRadians = Math.toRadians(selected == null ? 0L : Double.parseDouble(selected.getVal()));
                        double cosValue = Math.cos(angleInRadians);
                        if (org.apache.commons.lang3.StringUtils.isNotBlank(val)) {
                            double doubleValue = (new BigDecimal(val).subtract(currentValue)).divide(new BigDecimal(360), 9, RoundingMode.HALF_UP).doubleValue();
                            offsetValue = new BigDecimal(equatorial_circumference).multiply(new BigDecimal(cosValue)).multiply(new BigDecimal(doubleValue));
                        }
                    }
//                    currentMeasurement.put(itemName, offsetValue);
                    vo.setCurrentMeasurementValue(offsetValue == null ? null : offsetValue.toString());
                    if (slopeData != null) {
                        Date date = slopeData.getTs();
                        if (date != null) {
                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss");
                            vo.setCurrentMeasurementTime(simpleDateFormat.format(date));
                        }
                    }
                }
                itemList.clear();
                itemList.add(DictItemEnum.LATITUDE_Y.getValue());
                if (itemList.contains(re.getItem())) {
//                    BigDecimal offsetValue = new BigDecimal("0.00");
//                    if (org.apache.commons.lang3.StringUtils.isNotBlank(val)) {
//                        offsetValue = new BigDecimal(val).subtract(currentValue);
//                    }
//                    currentMeasurement.put(itemName, offsetValue);
//                    vo.setCurrentMeasurementValue(offsetValue == null ? null : offsetValue.toString());
                    vo.setCurrentMeasurementValue(val);
                    if (slopeData != null) {
                        Date date = slopeData.getTs();
                        if (date != null) {
                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss");
                            vo.setCurrentMeasurementTime(simpleDateFormat.format(date));
                        }
                    }

                }
                itemList.clear();
                itemList.add(DictItemEnum.ALTITUDE_Z.getValue());
                if (itemList.contains(re.getItem())) {
//                    BigDecimal offsetValue = new BigDecimal("0.00");
//                    if (org.apache.commons.lang3.StringUtils.isNotBlank(val)) {
//                        offsetValue = new BigDecimal(val).divide(new BigDecimal(1000), 12, BigDecimal.ROUND_HALF_UP);
//                    }
//                    currentMeasurement.put(itemName, offsetValue);
//                    vo.setCurrentMeasurementValue(offsetValue == null ? null : offsetValue.toString());
                    vo.setCurrentMeasurementValue(val);
                    if (slopeData != null) {
                        Date date = slopeData.getTs();
                        if (date != null) {
                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss");
                            vo.setCurrentMeasurementTime(simpleDateFormat.format(date));
                        }
                    }
                }
                map.put(itemName, vo);
                mapList.add(map);
            });
        }
        //集成要素-测量值计算
        List<KwsDeviceIntegration> deviceIntegrations = deviceIntegrationMapper.selectList(new LambdaQueryWrapper<KwsDeviceIntegration>()
                .eq(KwsDeviceIntegration::getMountainId, headerData.getMountainId())
                .eq(KwsDeviceIntegration::getDeviceId, deviceId)
        );
        List<Long> longList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(deviceIntegrations)) {
            longList = deviceIntegrations.stream().map(KwsDeviceIntegration::getIntegrationId).collect(Collectors.toList());
        }
        if (!CollectionUtils.isEmpty(longList)) {
            List<KwsIntegration> kwsIntegrations = integrationMapper.selectList(new LambdaQueryWrapper<KwsIntegration>().in(KwsIntegration::getId, longList));
            if (!CollectionUtils.isEmpty(kwsIntegrations) && kwsIntegrations.size() > 0) {
                kwsIntegrations.forEach(integration -> {
                    String integrationName = integration.getIntegrationName();
                    String partNames = integration.getPartNames();
                    KwsDeviceReference reference = deviceReferenceMapper.selectOne(new LambdaQueryWrapper<KwsDeviceReference>()
                            .eq(KwsDeviceReference::getMountainId, headerData.getMountainId())
                            .eq(KwsDeviceReference::getDeviceId, Long.parseLong(deviceId))
                            .eq(KwsDeviceReference::getDelFlag, 0)
                            .eq(KwsDeviceReference::getType, 2)
                    );
                    Map<String, DeviceOutputValueVO> map = new HashMap<>();
                    DeviceOutputValueVO vo = new DeviceOutputValueVO();
                    //当前基准值
//                    HashMap<String, Object> currentMap = new HashMap<>();
//                    currentMap.put(integrationName, reference == null ? null : reference.getCurrentValue());
                    vo.setCurrentValue(reference == null ? null : (reference.getCurrentValue() == null ? null : reference.getCurrentValue().toString()));
                    //原始基准值
//                    HashMap<String, Object> primitive = new HashMap<>();
//                    primitive.put(integrationName, reference == null ? null : reference.getOriginalValue());
                    vo.setOriginalValue(reference == null ? null : (reference.getOriginalValue() == null ? null : reference.getOriginalValue().toString()));
                    //当前测量值-TD获取
                    HashMap<String, Object> currentMeasurement = new HashMap<>();
                    String formula = integration.getFormula();
                    List<String> stringList = StringUtils.splitStrToList(partNames, String.class);
                    BigDecimal decimal = new BigDecimal("0.00");
                    String currentMeasurementTime = "";
                    if (!CollectionUtils.isEmpty(stringList)) {
                        for (int i = 0; i < stringList.size(); i++) {
                            String snCode = kwsDevice.getSnCode();
                            InsTables insTables = insTablesMapper.selectTableIsExit("devices" + snCode);
                            if (insTables == null) {
                                continue;
                            }
//                            if (insTables == null) {
//                                insTablesMapper.createTable("devices_" + snCode);
//                            }
                            List<SlopeData> selected = slopeDataMapper.selectListByLineOrderByCreateTime(snCode, stringList.get(i));
                            if (!CollectionUtils.isEmpty(selected)) {
                                if (selected.size() == 2) {
                                    SlopeData currSlopeData = selected.get(0);
                                    SlopeData lastSlopeData = selected.get(1);
                                    Date date = currSlopeData.getTs();
                                    if (date != null) {
                                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss");
                                        currentMeasurementTime = simpleDateFormat.format(date);
                                    }
                                    Date date1 = lastSlopeData.getTs();
//                                    long epochMilli = date.toInstant(ZoneOffset.of("+8")).toEpochMilli();
                                    long epochMilli = date.getTime();
                                    long epochMilli1 = date1.getTime();
//                                    long epochMilli1 = date1.toInstant(ZoneOffset.of("+8")).toEpochMilli();
                                    long t = (epochMilli - epochMilli1) / (60 * 60 * 1000);
                                    long val = Long.parseLong(currSlopeData.getVal()) - Long.parseLong(lastSlopeData.getVal());
                                    decimal = BigDecimal.valueOf(val).divide((new BigDecimal(t).multiply(new BigDecimal(t))), 12, BigDecimal.ROUND_HALF_UP);
                                }
                            }
                        }
                    }
//                    currentMeasurement.put(integrationName, decimal);
                    vo.setCurrentMeasurementValue(decimal.toString());
                    vo.setCurrentMeasurementTime(currentMeasurementTime);
                    map.put(integrationName, vo);
                    mapList.add(map);
                });
            }
        }
        return HttpResult.ok(mapList);
    }

    @DSTransactional
    public HttpResult referenceEdit(DeviceReferenceAdd deviceReference, HttpServletRequest response) {

        HeaderData headerData = commonService.getHeaderData(response);
        String listData = deviceReference.getReferceData();
        Long deviceId = deviceReference.getDeviceId();
        String type = deviceReference.getType();
        JSONArray array = JSON.parseArray(listData);
        LocalDateTime now = LocalDateTime.now();
        BigDecimal zero = new BigDecimal("0");
        KwsDevice deviceHas = deviceMapper.selectOne(new LambdaQueryWrapper<KwsDevice>()
                .eq(KwsDevice::getId, deviceId));
        String logDesc = "";
        Integer isHas = 0;
        Map<String, SystemDict> modelPart = commonService.getDictList(null, new HashMap<>() {{
            put("code", DictEnum.MODEL_PART.getCodeType());
            put("type", "1");
        }});

        Map<String, SystemDict> unit = commonService.getDictList(null, new HashMap<>() {{
            put("code", DictEnum.INTEGRATION_UNIT.getCodeType());
            put("type", "1");
        }});

        //获取集成要素信息
        List<DeviceIntegrationVo> intergData = new ArrayList<>();
        intergData = deviceIntegrationMapper.selectListParamsAndInterNameByDeviceId(deviceId);
        for (Object object : array) {
            JSONObject obj = (JSONObject) object;
            if(modelPart.containsKey(obj.get("item"))){
                logDesc += modelPart.get(obj.get("item")).getLabel()+ ":" +obj.get("value")+modelPart.get(obj.get("item")).getUrl()+",";
            }else{
                for(DeviceIntegrationVo vo : intergData){
                    if(obj.get("item").equals(vo.getIntegrationName())){

                        logDesc += obj.get("item")+ ":" +obj.get("value")+unit.get(vo.getUnit()).getDescription()+",";
                    }
                }

            }


            KwsDeviceReference reference = deviceReferenceMapper.selectOne(new LambdaQueryWrapper<KwsDeviceReference>()
                    .eq(KwsDeviceReference::getMountainId, headerData.getMountainId())
                    .eq(KwsDeviceReference::getDeviceId, deviceId)
                    .eq(KwsDeviceReference::getDelFlag, 0)
                    .eq(KwsDeviceReference::getItem, obj.get("item"))
            );
            long interId = new IdWorker(NumberConstant.ONE).nextId();
            KwsDeviceReference kwsDeviceReference = new KwsDeviceReference();
            BigDecimal value = new BigDecimal(obj.get("value").toString());

            if (Objects.isNull(reference)) {
                kwsDeviceReference.setOffset(zero);
                kwsDeviceReference.setOriginalValue(value);
                kwsDeviceReference.setCurrentValue(value);
                kwsDeviceReference.setValue(value);
            } else {
                isHas = 1;
                //如果有数据，则先删除原有数据。
                deviceReferenceMapper.update(null, new LambdaUpdateWrapper<KwsDeviceReference>()
                        .eq(KwsDeviceReference::getMountainId, headerData.getMountainId())
                        .eq(KwsDeviceReference::getDeviceId, deviceId)
                        .eq(KwsDeviceReference::getDelFlag, 0)
                        .eq(KwsDeviceReference::getItem, obj.get("item"))
                        .set(KwsDeviceReference::getDelFlag, NumberConstant.ONE)
                );
                //BigDecimal offset = value.subtract(reference.getValue());
                kwsDeviceReference.setOriginalValue(reference.getOriginalValue());//原始基准不变
                //调整经纬度
                if (type.equals(String.valueOf(NumberConstant.ONE))) {
                    BigDecimal offset = commonService.computeOffset(value.toString(), obj.get("item").toString(), reference);
                    kwsDeviceReference.setOffset(offset);//当前位置-上一次的位置的距离的距离
                    kwsDeviceReference.setCurrentValue(value);
                    kwsDeviceReference.setValue(reference.getCurrentValue());

                } else {

                    BigDecimal currentValue = commonService.getValueByOffset(value.toString(), obj.get("item").toString(), reference,deviceHas.getSnCode());
                    kwsDeviceReference.setValue(reference.getCurrentValue());
                    kwsDeviceReference.setOffset(value);
                    kwsDeviceReference.setCurrentValue(currentValue);//原始位置+偏移的坐标
                }

                //调整偏移量
            }
            kwsDeviceReference.setId(interId);
            kwsDeviceReference.setDeviceId(deviceId);
            kwsDeviceReference.setMountainId(headerData.getCompanyId());
            kwsDeviceReference.setType(Integer.parseInt(obj.get("type").toString()));
            kwsDeviceReference.setItem(obj.get("item").toString());


            kwsDeviceReference.setCreateBy(Long.parseLong(headerData.getCreateBy()));
            kwsDeviceReference.setCreateTime(now);
            kwsDeviceReference.setStatus(NumberConstant.ONE);
            kwsDeviceReference.setUpdateBy(Long.parseLong(headerData.getUpdateBy()));
            kwsDeviceReference.setUpdateTime(now);
            deviceReferenceMapper.insert(kwsDeviceReference);
        }
        deviceMapper.update(null, new LambdaUpdateWrapper<KwsDevice>()
                .eq(KwsDevice::getId, deviceId)
                .set(KwsDevice::getStatus, NumberConstant.FOUR)
        );
        //获取新增设备的型号
        Map<String, Object> logMap = new HashMap<>(NumberConstant.SIXTEEN);
        logMap.put("name", deviceHas.getName());
        logMap.put("desc", logDesc);
        logMap.put("projectName", "");
        //List<DeviceVo> list = deviceMapper.selectProjectByDeviceId(String.valueOf(deviceId));
        KwsProjectDevice device = projectDeviceMapper.selectOne(new LambdaQueryWrapper<KwsProjectDevice>()
                .eq(KwsProjectDevice::getDeviceId, deviceId)
                .eq(KwsProjectDevice::getDelFlag,NumberConstant.ZERO)
                .last("LIMIT 1")
                .orderByDesc(KwsProjectDevice::getCreateTime));

        if(Objects.nonNull(device)){
            KwsProject project = projectMapper.selectOne(new LambdaQueryWrapper<KwsProject>()
                    .eq(KwsProject::getId, device.getProjectId())
                    .eq(KwsProject::getDelFlag,NumberConstant.ZERO));

            logMap.put("projectName", project.getName());
        }

        if(isHas == 1){
            commonService.insertLog(MessageLogEnum.REFERENCE_EDIT, headerData, logMap, Long.parseLong(headerData.getUpdateBy()));
        }else{
            commonService.insertLog(MessageLogEnum.REFERENCE_ADD, headerData, logMap, Long.parseLong(headerData.getUpdateBy()));
        }


        return HttpResult.ok();
    }


    public HttpResult monitorItem(String id, HttpServletRequest request) {
        String companyId = commonService.getHeaderData(request).getCompanyId();
        //查询基本要素
        List<BaseItemDTO> baseItem = projectDeviceMapper.selectDataByDeviceId(Long.parseLong(id));
        Map<String, SystemDict> dictByDictCode = commonService.getDictByDictCode(DictEnum.MODEL_PART);
        if (!CollectionUtils.isEmpty(baseItem)) {
            for (BaseItemDTO baseItemDTO : baseItem) {
                baseItemDTO.setPartNameLabel(baseItemDTO.getPartName() == null ? null :
                        (dictByDictCode == null ? baseItemDTO.getPartName() :
                                (dictByDictCode.get(baseItemDTO.getPartName()) == null ?
                                        (baseItemDTO.getPartName()) : dictByDictCode.get(baseItemDTO.getPartName()).getLabel())));
            }
        }
        List<IntegrationItemVO> integrationItem = projectDeviceMapper.selectIntegrationItemByDeviceId(Long.parseLong(id));
        com.alibaba.fastjson2.JSONObject jsonObject = new com.alibaba.fastjson2.JSONObject();
        jsonObject.put("baseItem", baseItem);
        jsonObject.put("integrationItem", integrationItem);
        return HttpResult.ok(jsonObject);
    }

    /**
     * 查询设备型号数据
     *
     * @param query
     * @param request
     * @return
     */
    public HttpResult findProjectAndModelAndDeviceList(ProjectAndModelAndDeviceQuery query, HttpServletRequest request) {
        List<KwsDeviceModel> kwsDeviceModels = deviceModelMapper.selectList(new LambdaQueryWrapper<KwsDeviceModel>()
                .eq(KwsDeviceModel::getDelFlag, NumberConstant.ZERO)
                .eq(KwsDeviceModel::getStatus, NumberConstant.ZERO)
        );
        return HttpResult.ok(kwsDeviceModels);
    }

    public HttpResult findDeviceListByModelType(String modelType, HttpServletRequest request) {
        String companyId = commonService.getHeaderData(request).getCompanyId();
        List<Map<String, String>> map = deviceMapper.selectListByModelType(modelType,companyId);
        return HttpResult.ok(map);
    }
}
