package com.ruoyi.tdengine.service.impl;

import com.ruoyi.common.core.constant.TdEngineConstants;
import com.ruoyi.tdengine.api.domain.*;
import com.ruoyi.tdengine.mapper.DeviceStatusMapper;
import com.ruoyi.tdengine.mapper.TdEngineMapper;
import com.ruoyi.tdengine.service.ITdEngineService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @ClassDescription: TdEngine业务实现逻辑
 * @ClassName: TdEngineServiceImpl
 * @Author: xins
 * @Date: 2023-08-25 15:55:50
 * @Version 1.0
 */
@Service
//@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public class TdEngineServiceImpl implements ITdEngineService {
    private static final String DEFAULT_FIRST_FIELD_NAME = "ts";

    @Autowired
    private TdEngineMapper tdEngineMapper;

//    @Autowired
//    private RedisService redisService;

    /**
     * @param databaseName
     * @description:创建数据库
     * @author xins
     * @date 2023-08-28 11:32
     */
    @Override
    public void createDatabase(String databaseName) throws Exception {
        this.tdEngineMapper.createDatabase(databaseName);
    }

    /**
     * @param databaseName
     * @param superTableName
     * @param firstFieldName
     * @param schemaFields
     * @param tagsFields
     * @description 创建超级表
     * @author xins
     * @date 2023-08-28 13:18
     */
    @Override
    public void createSuperTable(String databaseName, String superTableName, String firstFieldName, List<TdFieldVo> schemaFields, List<TdFieldVo> tagsFields) throws Exception {
        if (StringUtils.isBlank(firstFieldName)) {
            firstFieldName = DEFAULT_FIRST_FIELD_NAME;
        }
        this.tdEngineMapper.createSuperTable(databaseName, superTableName, firstFieldName, schemaFields, tagsFields);
    }

    /**
     * @param: databaseName
     * @param: superTableName
     * @param: tableName
     * @param: tagsFieldValues
     * @description 创建子表
     * @author xins
     * @date 2023-08-28 16:16
     */
    @Override
    public void createTable(String databaseName, String superTableName, String tableName, List<TdField> tagsFieldValues) throws Exception {
        this.tdEngineMapper.createTable(databaseName, superTableName, tableName, tagsFieldValues);

    }

    /**
     * @param: databaseName
     * @param: superTableName
     * @param: addFieldsVo
     * @description 增加超级表的列
     * @author xins
     * @date 2023-08-28 17:12
     */
    @Override
    public void addSuperTableColumn(String databaseName, String superTableName, TdFieldVo addFieldsVo) throws Exception {
        this.tdEngineMapper.addSuperTableColumn(databaseName, superTableName, addFieldsVo);
    }

    /**
     * @param: databaseName
     * @param: superTableName
     * @param: dropFieldsVo
     * @description 删除超级表的列
     * @author xins
     * @date 2023-08-28 17:13
     */
    public void dropSuperTableColumn(String databaseName, String superTableName, TdField dropField) throws Exception {
        this.tdEngineMapper.dropSuperTableColumn(databaseName, superTableName, dropField);
    }

    /**
     * @param: databaseName
     * @param: tableName
     * @param: tagName
     * @param: tagValue
     * @description 修改子表的tagValue
     * @author xins
     * @date 2023-08-30 11:03
     */
    @Override
    public void alterTableTag(String databaseName, String tableName, String tagName, Object tagValue) {
        this.tdEngineMapper.alterTableTag(databaseName, tableName, tagName, tagValue);
    }

    /**
     * @param: databaseName
     * @param: tableName
     * @param: schemaFields
     * @description 插入数据
     * @author xins
     * @date 2023-08-29 10:10
     */
    @Override
    public void insertTable(String databaseName, String tableName, List<TdField> schemaFields) throws Exception {
        this.tdEngineMapper.insertTable(databaseName, tableName, schemaFields);
    }

    /**
     * @return List<Map < Object>>
     * @param: tdSelectDto
     * @description 查询具体某个子表最新数据，适用于设备监测页面，先根据监控单元获取设备信息，再根据设备来获取最新的数据
     * @author xins
     * @date 2023-08-29 11:28
     */
    @Override
    public List<Map<String, Object>> getLatestData(TdSelectDto tdSelectDto) throws Exception {
        List<Map<String, Object>> latestMaps = this.tdEngineMapper.getLatestData(tdSelectDto);

        List<Map<String, Object>> filterMaps = new ArrayList<>();

//        String i18nKey = "tdengine_supertable1_";
        String i18nKey = "";//todo：国际化看在哪处理
        /**
         * 由于通过last(*)获取则获取的key为last(key),所以需要以下过滤，需要获取括号中间的真正key
         */
        for (Map<String, Object> latestMap : latestMaps) {
            Map<String, Object> filterMap = latestMap.entrySet()
                    .stream()
                    .filter(entry -> entry.getValue() != null)
                    .collect(HashMap::new, (m, v) ->
                            m.put(i18nKey + v.getKey().substring(v.getKey().indexOf("(") + 1,
                                    v.getKey().indexOf(")")), v.getValue()), HashMap::putAll);
            filterMaps.add(filterMap);
        }
        return filterMaps;
    }

    /**
     * @return List<Map < String, Object>>
     * @param: tdSelectDto
     * @description 根据tagsname获取超级表最新信息，适用于设备汇总页面，先分页获取设备信息，再获取所有此物模型下的最新信息（冗余，但每页只获取一次，不需要每个设备都获取一次
     * *     如果需要根据时间周期获取最新的数据，则需要用select last_row()
     * @author xins
     * @date 2023-08-29 14:47
     */
    @Override
    public List<Map<String, Object>> getLatestDataByTags(TdSuperTableSelectVo tdSuperTableSelectVo) {
        List<Map<String, Object>> latestMaps = this.tdEngineMapper.getLatestDataByTags(tdSuperTableSelectVo);
        latestMaps.replaceAll(latestMap -> {
            return latestMap.entrySet()
                    .stream()
                    .filter(entry -> entry.getValue() != null)
                    .collect(HashMap::new, (m, v) ->
                            m.put(v.getKey().substring(v.getKey().indexOf("(") + 1,
                                    v.getKey().indexOf(")")), v.getValue()), HashMap::putAll);
        });
        //        Map<String, Map<String, Object>> tagsMap = new HashMap<>();
//        for (Map<String, Object> latestMap : latestMaps) {
//            Map<String, Object> filterMap = latestMap.entrySet()
//                    .stream()
//                    .filter(entry -> entry.getValue() != null)
//                    .collect(HashMap::new, (m, v) ->
//                            m.put(v.getKey().substring(v.getKey().indexOf("(") + 1,
//                                    v.getKey().indexOf(")")), v.getValue()), HashMap::putAll);
//            tagsMap.put(filterMap.get(tdSuperTableSelectVo.getTagsName()).toString(), filterMap);
//        }
        return latestMaps;
    }


    /**
     * @return List<Map < Object>>
     * @param: tdHistorySelectDto
     * @description 获取历史数据
     * @author xins
     * @date 2023-08-29 15:52
     */
    @Override
    public List<Map<String, Object>> getHistoryData(TdHistorySelectDto tdHistorySelectDto) {
//        if (StringUtils.isBlank(tdHistorySelectDto.getOrderByFieldName())) {
//            tdHistorySelectDto.setOrderByFieldName(TdEngineConstants.DEFAULT_FIRST_FIELD_NAME);
//        }
//        if (StringUtils.isBlank(tdHistorySelectDto.getOrderByMode())) {
//            tdHistorySelectDto.setOrderByMode(TdEngineConstants.DEFAULT_ORDER_BY_MODE);
//        }

        List<Map<String, Object>> historyDataMaps = this.tdEngineMapper.getHistoryData(tdHistorySelectDto);
        return historyDataMaps;
    }


    /**
     * @return Long
     * @param: tdHistorySelectDto
     * @description 获取历史记录的数量
     * @author xins
     * @date 2023-08-29 16:54
     */
    @Override
    public Long getCountOfHistoryData(TdHistorySelectDto tdHistorySelectDto) throws Exception {
        Map<String, Long> countMap = this.tdEngineMapper.getCountOfHistoryData(tdHistorySelectDto);
        if (countMap == null) {
            return 0L;
        }
        return countMap.get("dataCount");
    }

//
//    /**
//     * 检查数据库表是否存在
//     *
//     * @param dataBaseName 数据库名
//     * @param tableName    tableName 可以为超级表名或普通表名
//     * @return
//     */
//    public boolean checkTableExists(String dataBaseName, String tableName) throws Exception {
//        try {
//            Integer count = tdEngineMapper.checkTableExists(dataBaseName, tableName);
//            return count == 1;
//        } catch (Exception e) {
//            log.warn("{},{} 数据库表不存在", dataBaseName, tableName);
//            return false;
//        }
//    }
//
//    @Override
//    public void initSTableFrame(String msg) throws Exception {
//        final SuperTableDto superTableDto = JSONObject.toJavaObject(JSONObject.parseObject(msg), SuperTableDto.class);
//        //从入参对象获取列字段（超级表结构）对象集合
//        List<Fields> schemaFields = superTableDto.getSchemaFields();
//        //从入参对象获取标签字段对象集合
//        List<Fields> tagsFields = superTableDto.getTagsFields();
//        //从入参获取数据库名称
//        String dataBaseName = superTableDto.getDataBaseName();
//        //从入参获取超级表名称
//        String superTableName = superTableDto.getSuperTableName();
//        final boolean tableExists = this.checkTableExists(dataBaseName, superTableName);
//        if (tableExists) {
//            log.info("超级表{}已存在", superTableName);
//            return;
//        }
//        //获取列字段对象集合的第一个对象的字段数据类型
//        DataTypeEnum dataType = schemaFields.get(0).getDataType();
//        //如果该数据类型不是时间戳，打印和返回报错信息
//        if (dataType == null || !"timestamp".equals(dataType.getDataType())) {
//            log.error("invalid operation: first column must be timestamp");
//            return;
//        }
//        //将列字段对象集合和标签字段对象集合转码为字段Vo类对象集合
//        List<FieldsVo> schemaFieldsVoList = FieldsVo.fieldsTranscoding(schemaFields);
//        List<FieldsVo> tagsFieldsVoList = FieldsVo.fieldsTranscoding(tagsFields);
//        //创建超级表
//        this.createSuperTable(schemaFieldsVoList, tagsFieldsVoList, dataBaseName, superTableName);
//        log.info("create {} super table success", superTableName);
//    }
//

//
//    /**
//     * @param tagsSelectDao
//     * @return
//     */
//    @Override

//
//

//
//    @Override
//    public List<Map<String, Object>> getRealtimeData(SelectVisualDto selectVisualDto) {
//        List<Map<String, Object>> maps = this.tdEngineMapper.getRealtimeData(selectVisualDto);
//        return maps;
//    }
//
//    @Override
//    public List<Map<String, Object>> getAggregateData(SelectVisualDto selectVisualDto) {
//        List<Map<String, Object>> maps = this.tdEngineMapper.getAggregateData(selectVisualDto);
//        return maps;
//    }

}
