package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.business.domain.HwDeviceModeFunction;
import com.ruoyi.business.domain.VO.DeviceDataColumnVo;
import com.ruoyi.business.domain.VO.DeviceHistoryDataVo;
import com.ruoyi.business.domain.VO.DeviceLatestDataVo;
import com.ruoyi.business.mapper.HwDeviceModeFunctionMapper;
import com.ruoyi.business.service.IHwMonitorPlatformService;
import com.ruoyi.common.core.constant.HwDictConstants;
import com.ruoyi.common.core.constant.TdEngineConstants;
import com.ruoyi.tdengine.api.RemoteTdEngineService;
import com.ruoyi.tdengine.api.domain.TdField;
import com.ruoyi.tdengine.api.domain.TdHistorySelectDto;
import com.ruoyi.tdengine.api.domain.TdReturnDataVo;
import com.ruoyi.tdengine.api.domain.TdSuperTableSelectVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 监控平台数据处理接口
 * @ClassName: HwMonitorPlatformServiceImpl
 * @Author : xins
 * @Date :2023-09-16  14:50
 * @Version :1.0
 */
@Service
public class HwMonitorPlatformServiceImpl implements IHwMonitorPlatformService {
    @Resource
    private RemoteTdEngineService remoteTdEngineService;

    @Autowired
    private HwDeviceModeFunctionMapper deviceModeFunctionMapper;

    /**
     * @return JSONObject
     * @param: deviceLatestDataVo
     * @description 根据设备模型获取最新数据
     * @author xins
     * @date 2023-09-16 14:49
     */
    @Override
    public JSONObject selectLatestDataByTags(DeviceLatestDataVo deviceLatestDataVo) {
        JSONObject returnObj = new JSONObject();
        Long deviceModeId = deviceLatestDataVo.getDeviceModeId();
        HwDeviceModeFunction queryModeFunction = new HwDeviceModeFunction();
        queryModeFunction.setDeviceModeId(deviceModeId);
        queryModeFunction.setFunctionMode(HwDictConstants.FUNCTION_MODE_ATTRIBUTE);
        List<HwDeviceModeFunction> deviceModeFunctions = deviceModeFunctionMapper.selectHwDeviceModeFunctionList(queryModeFunction);
        Map<String, String> functionIndentifierName = deviceModeFunctions.stream().collect(
                Collectors.toMap(HwDeviceModeFunction::getFunctionIdentifier, HwDeviceModeFunction::getFunctionName));
        functionIndentifierName.putAll(TdEngineConstants.DEVICE_DATA_COLUMN_MAP);

        TdSuperTableSelectVo tdSuperTableSelectVo = new TdSuperTableSelectVo();
        String databaseName = TdEngineConstants.getDatabaseName(deviceLatestDataVo.getSceneId());
        String superTableName = TdEngineConstants.getSuperTableName(deviceModeId);
        tdSuperTableSelectVo.setDatabaseName(databaseName);
        tdSuperTableSelectVo.setSuperTableName(superTableName);
        tdSuperTableSelectVo.setGroupByTagsName(TdEngineConstants.ST_TAG_DEVICECODE);//todo,换成deviceid
        if (deviceLatestDataVo.getStartTime() != 0 || deviceLatestDataVo.getEndTime() != 0) {
            tdSuperTableSelectVo.setFirstFieldName(TdEngineConstants.DEFAULT_FIRST_FIELD_NAME);
        }
        tdSuperTableSelectVo.setDeviceCode(deviceLatestDataVo.getDeviceCode());
        tdSuperTableSelectVo.setDeviceName(deviceLatestDataVo.getDeviceName());
        tdSuperTableSelectVo.setStartTime(deviceLatestDataVo.getStartTime());
        tdSuperTableSelectVo.setEndTime(deviceLatestDataVo.getEndTime());
        tdSuperTableSelectVo.setOffset(deviceLatestDataVo.getOffset());
        tdSuperTableSelectVo.setLimit(deviceLatestDataVo.getLimit());

        List<TdField> schemaFieldValues = new ArrayList<TdField>();
        List<HwDeviceModeFunction> modeFunctions = new ArrayList<>();

        deviceModeFunctions.forEach(mf -> {
                TdField field = new TdField();
                field.setFieldName(mf.getFunctionIdentifier());
                schemaFieldValues.add(field);

        });
        tdSuperTableSelectVo.setSchemaFieldValues(schemaFieldValues);

        List<Map<String, Object>> latestDataMaps =
                this.remoteTdEngineService.getLatestDataByTags(tdSuperTableSelectVo).getData();


        List<DeviceDataColumnVo> deviceDataColumnVos = new ArrayList<DeviceDataColumnVo>();
        if (latestDataMaps != null && latestDataMaps.size() > 0) {
            Map<String, Object> latestDataMap = latestDataMaps.get(0);
            for (Map.Entry<String, Object> entry : latestDataMap.entrySet()) {
                DeviceDataColumnVo deviceDataColumnVo = new DeviceDataColumnVo();
                String columnKey = entry.getKey();
                if(!columnKey.equalsIgnoreCase(TdEngineConstants.ST_TAG_DEVICEID)
                        && !columnKey.equalsIgnoreCase(TdEngineConstants.ST_TAG_DEVICEMODEID)){
                    deviceDataColumnVo.setColumnKey(columnKey);
                    deviceDataColumnVo.setColumnName(functionIndentifierName.get(columnKey) == null
                            ? columnKey : functionIndentifierName.get(columnKey));
                    deviceDataColumnVos.add(deviceDataColumnVo);
                }
            }
        }

        returnObj.put("deviceDataColumns", deviceDataColumnVos);
        returnObj.put("latestData", latestDataMaps);
        return returnObj;
    }


    /**
     * @return TdReturnDataVo
     * @param: deviceHistoryDataVo
     * @description 获取设备历史数据
     * @author xins
     * @date 2023-09-16 15:14
     */
    @Override
    public TdReturnDataVo getHistoryData(DeviceHistoryDataVo deviceHistoryDataVo) {
        TdHistorySelectDto tdHistorySelectDto = new TdHistorySelectDto();
        tdHistorySelectDto.setDatabaseName(TdEngineConstants.getDatabaseName(deviceHistoryDataVo.getSceneId()));
        tdHistorySelectDto.setTableName(TdEngineConstants.getDeviceDataTableName(deviceHistoryDataVo.getDeviceId()));
        tdHistorySelectDto.setOrderByFieldName(TdEngineConstants.DEFAULT_FIRST_FIELD_NAME);
        tdHistorySelectDto.setSort(TdEngineConstants.DEFAULT_ORDER_BY_MODE);
        if (deviceHistoryDataVo.getStartTime() != 0 || deviceHistoryDataVo.getEndTime() != 0) {
            tdHistorySelectDto.setFirstFieldName(TdEngineConstants.DEFAULT_FIRST_FIELD_NAME);
        }
        tdHistorySelectDto.setStartTime(deviceHistoryDataVo.getStartTime());
        tdHistorySelectDto.setEndTime(deviceHistoryDataVo.getEndTime());
        tdHistorySelectDto.setOffset(deviceHistoryDataVo.getOffset());
        tdHistorySelectDto.setLimit(deviceHistoryDataVo.getLimit());

        return this.remoteTdEngineService.getHistoryData(tdHistorySelectDto).getData();
    }


    /**
     * @return List<DeviceDataColumnVo>
     * @param: deviceModeId
     * @param: latestDataMaps
     * @description
     * @author xins
     * @date 2023-09-25 15:40
     */
    @Override
    public List<DeviceDataColumnVo> getDeviceDataColumns(Long deviceModeId, List<Map<String, Object>> latestDataMaps) {
        HwDeviceModeFunction queryModeFunction = new HwDeviceModeFunction();
        queryModeFunction.setDeviceModeId(deviceModeId);
        queryModeFunction.setFunctionMode(HwDictConstants.FUNCTION_MODE_ATTRIBUTE);
        List<HwDeviceModeFunction> deviceModeFunctions = deviceModeFunctionMapper.selectHwDeviceModeFunctionList(queryModeFunction);
        Map<String, String> functionIndentifierName = deviceModeFunctions.stream().collect(
                Collectors.toMap(HwDeviceModeFunction::getFunctionIdentifier, HwDeviceModeFunction::getFunctionName));
        functionIndentifierName.putAll(TdEngineConstants.DEVICE_DATA_COLUMN_MAP);

        List<DeviceDataColumnVo> deviceDataColumnVos = new ArrayList<DeviceDataColumnVo>();
        if (latestDataMaps != null && latestDataMaps.size() > 0) {
            Map<String, Object> latestDataMap = latestDataMaps.get(0);
            for (Map.Entry<String, Object> entry : latestDataMap.entrySet()) {
                DeviceDataColumnVo deviceDataColumnVo = new DeviceDataColumnVo();
                String columnKey = entry.getKey();
                deviceDataColumnVo.setColumnKey(columnKey);
                deviceDataColumnVo.setColumnName(functionIndentifierName.get(columnKey) == null
                        ? columnKey : functionIndentifierName.get(columnKey));
                deviceDataColumnVos.add(deviceDataColumnVo);
            }
        }
        return deviceDataColumnVos;
    }

}
