package com.persagy.dmp.rwd.simple.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.persagy.dmp.basic.dto.RequestData;
import com.persagy.dmp.common.constant.CommonConstant;
import com.persagy.dmp.common.context.AppContext;
import com.persagy.dmp.common.utils.DateHelper;
import com.persagy.dmp.rwd.basic.constant.DigitalObjectType;
import com.persagy.dmp.rwd.digital.utils.ObjectDigitalCriteriaHelper;
import com.persagy.dmp.rwd.simple.dao.EquipmentReportMapper;
import com.persagy.dmp.rwd.simple.domain.GroupDTO;
import com.persagy.dmp.rwd.simple.entity.CountTypeEquipmentVO;
import com.persagy.dmp.rwd.simple.service.IEquipmentReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 数字孪生 设备统计相关接口实现类
 * @author Charlie Yu
 * @date 2021-09-02
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class EquipmentReportServiceImpl implements IEquipmentReportService {

    @Resource
    private EquipmentReportMapper mapper;

    @Override
    public List<Map<String, Object>> queryExpectScrapCountByProjects(List<String> projectIds) {
        Date date = DateHelper.addMonth(new Date(), 6);
        // 日期格式，标准字典是yyyy-MM-dd，应该不会改。有改动再改为查字典获取格式
        String scrapDate = DateHelper.dateToString(date, "yyyy-MM-dd");
        return mapper.queryExpectScrapCountByProjects(scrapDate, projectIds);
    }

    @Override
    public List<CountTypeEquipmentVO> queryEquipmentCountByType(List<String> projectIds) {
        // TODO 获取专业、系统的code，name对照 - 先不转了，回头再加
        Map<String, String> majorMap = new HashMap<>(16);
        Map<String, String> systemMap = new HashMap<>(16);
        // 项目不为空，把平台级和集团级的加上
        if(CollUtil.isNotEmpty(projectIds)) {
            projectIds.add(CommonConstant.DEFAULT_ID);
            projectIds.add(AppContext.getContext().getGroupCode());
        }
        // 查询统计 - 业务认知：设备类总数不会太多
        List<Map<String, Object>> rsList = mapper.queryEquipmentCountByType(projectIds);
        return mergeCountResult(rsList, majorMap, systemMap);
    }
    /***
     * Description: 根据对象信息点统计数量
     * @param requestData :
     * @return : java.util.List<com.fasterxml.jackson.databind.node.ObjectNode>
     * @author : lijie
     * @date :2021/9/13 21:50
     * Update By lijie 2021/9/13 21:50
     */
    @Override
    public List<Map<String, Object>> queryObjectCountByObjInfos(RequestData requestData) {
        requestData.setGroupCode(AppContext.getContext().getGroupCode());
        requestData.setProjectId(AppContext.getContext().getProjectId());
        Set<String> digitalFields = ObjectDigitalCriteriaHelper.DIGITAL_FIELDS;
        List<String> groups = requestData.getGroups();
        List<GroupDTO> groupDos = new ArrayList<>();
        for (String group : groups) {
            if (digitalFields.contains(group)){
                groupDos.add(GroupDTO.builder().field(group).column(StrUtil.toUnderlineCase(group)).fieldFlag(true).build());
                continue;
            }
            groupDos.add(GroupDTO.builder().field(group).column(group).fieldFlag(false).build());
        }
        return mapper.queryObjectCountByObjInfos(requestData,groupDos);
    }

    /**
     * 查询当前设备类型下的部件分类以及数量
     * @param equipmentId:设备Id
     * @return
     */
    @Override
    public List<Map<String, Object>> queryComponentsCountByEquipId(String equipmentId) {
        // 项目不为空，把平台级和集团级的加上
        List<String> projectIds = new ArrayList<>();
        projectIds.add(CommonConstant.DEFAULT_ID);
        projectIds.add(AppContext.getContext().getGroupCode());
        projectIds.add(AppContext.getContext().getProjectId());
        return mapper.queryComponentsCountByEquipId(projectIds, AppContext.getContext().getProjectId(), equipmentId);
    }

    /**
     * 统计项目下允许创建的部件类型，以及项目下创建的部件数量
     * @param equipmentId 设备ID
     * @param category 设备类
     * @return
     */
    @Override
    public List<Map<String, Object>> queryEquipComponentsByProjectId(String category, String equipmentId) {
        return mapper.queryEquipComponentsByProjectId(category, AppContext.getContext().getProjectId(),equipmentId,AppContext.getContext().getGroupCode());
    }

    /**
     * 项目下所有实例(system/space/equipment..)类型以及名称
     * @param requestData
     * @return
     */
    @Override
    public List<Map<String, Object>> queryDefineInfoByObjType(RequestData requestData) {
        requestData.setGroupCode(AppContext.getContext().getGroupCode());
        requestData.setProjectId(AppContext.getContext().getProjectId());
        return mapper.queryDefineInfoByObjType(requestData);
    }


    /**
     * 累加统计结果，合并为专业-系统-设备类 层级结构
     * @param rsList
     * @return
     */
    private List<CountTypeEquipmentVO> mergeCountResult(List<Map<String, Object>> rsList, Map<String, String> majorMap, Map<String, String> systemMap) {
        if(CollUtil.isEmpty(rsList)) {
            return null;
        }
        // 查询到的是设备类的统计，再做一下计算(单次循环），改造为专业-系统-设备类 层级结构
        List<CountTypeEquipmentVO> reportList = new ArrayList<>();
        Map<String, CountTypeEquipmentVO> reportMap = new HashMap<>(16);
        for(Map<String, Object> info:rsList) {
            String majorCode = MapUtil.getStr(info, "majorCode");
            String systemCode = MapUtil.getStr(info, "systemCode");
            String eqCode = MapUtil.getStr(info, "code");
            int total = MapUtil.getInt(info, "total");
            // 有空就是错误数据，不处理
            if(StrUtil.isBlank(majorCode) || StrUtil.isBlank(systemCode) || StrUtil.isBlank(eqCode)) {
                continue;
            }
            // 创建设备类统计结果
            CountTypeEquipmentVO equipmentVO = CountTypeEquipmentVO.builder()
                    .code(eqCode).name(MapUtil.getStr(info, "name"))
                    .type(DigitalObjectType.EQUIPMENT.getIndex()).count(total).build();
            // 查找专业类统计结果并累加
            CountTypeEquipmentVO majorVO = reportMap.get(majorCode);
            if(majorVO == null) {
                // 没有就创建
                majorVO = CountTypeEquipmentVO.builder()
                        .code(majorCode).name(MapUtil.getStr(majorMap, majorCode))
                        .type("major").count(0).build();
                reportMap.put(majorCode, majorVO);
                // 专业类的放入返回结果中
                reportList.add(majorVO);
            }
            majorVO.addCount(total);
            // 查找系统类统计结果并累加
            CountTypeEquipmentVO systemVO = reportMap.get(systemCode);
            if(systemVO == null) {
                // 没有就创建
                systemVO = CountTypeEquipmentVO.builder()
                        .code(systemCode).name(MapUtil.getStr(systemMap, systemCode))
                        .type(DigitalObjectType.SYSTEM.getIndex()).count(0).build();
                reportMap.put(systemCode, systemVO);
                // 系统类的追加到专业类的子集
                majorVO.addContent(systemVO);
            }
            systemVO.addCount(total);
            // 设备类的追加到系统类的子集
            systemVO.addContent(equipmentVO);
        }
        return reportList;
    }
}
