package com.casic.missiles.service.listeners.register.data.site;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.casic.missiles.dto.business.file.FilePrintRegister;
import com.casic.missiles.enums.notifyevent.PrintFileDataBeanNameAliasEnum;
import com.casic.missiles.mapper.meter.MeterStaffMapper;
import com.casic.missiles.model.business.BusinessSiteExecutiveEquipmentRelation;
import com.casic.missiles.model.business.BusinessSiteExecutiveLog;
import com.casic.missiles.model.equipment.EquipmentFixedAssets;
import com.casic.missiles.service.equipment.IEquipmentFixedAssetsService;
import com.casic.missiles.service.listeners.register.data.PrintFileDataGeneric;
import com.casic.missiles.service.listeners.register.data.PrintFileDataSupport;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

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

/**
 * @author cz
 * @date 2023-04-18
 */
@Slf4j
@Component(PrintFileDataBeanNameAliasEnum.EXTERNAL_ENVIRONMENTAL_RECORD_BEAN)
public class EnvironmentalRecordData extends PrintFileDataSupport implements PrintFileDataGeneric {
    @Resource
    private MeterStaffMapper meterStaffMapper;
    @Resource
    private IEquipmentFixedAssetsService equipmentFixedAssetsService;
    @Value("${casic.template.environmental}")
    private String environmentalTemplateName;

    @Override
    public FilePrintRegister CustomizedPrintFileRegister(Object object, String templateFileDir) {
        BusinessSiteExecutiveLog metaData = (BusinessSiteExecutiveLog) object;
        //初始化，生成模板文件
        FilePrintRegister filePrintRegister = initialization(templateFileDir, metaData.getId(), getTemplateName(environmentalTemplateName));
//        preparePopulateParams(metaData);
        //关联数据
        this.equipmentRelation(filePrintRegister, metaData)
                //填充环境参数
                .populateEnvironmentParam(filePrintRegister, metaData)
                //测量设备数据
                .equipmentFixedAssetsByLog(filePrintRegister, metaData.getSiteExecutiveEquipmentRelationList())
                //按约定规则处理测量设备人员和日期
                .resolveSiteEquipmentsStatus(filePrintRegister, metaData.getSiteExecutiveEquipmentRelationList());
        return filePrintRegister;
    }

    /**
     * 填充环境记录单内容信息
     */
    private EnvironmentalRecordData populateEnvironmentParam(FilePrintRegister filePrintRegister, BusinessSiteExecutiveLog metaData) {
        Map<String, Object> environmentDataParams = new HashMap<>();
        environmentDataParams.put("logNo", metaData.getLogNo());
        environmentDataParams.put("executiveAddress", metaData.getExecutiveAddress());
        environmentDataParams.put("voltage", metaData.getOutputVoltage());
        environmentDataParams.put("zeroVoltage", metaData.getZeroGroundVoltage());
        environmentDataParams.put("temp", metaData.getTemperature());
        environmentDataParams.put("humi", metaData.getHumidity());
        environmentDataParams.put("laboratoryName", metaData.getLaboratoryName());
        filePrintRegister.getParams().putAll(environmentDataParams);
        return this;
    }

    /**
     * 处理人员时间
     */
    private Map<String, Object> resolveRecordTime(String recorderDateStr, int index) {
        Map<String, Object> filePrintDataParams = new HashMap<>();
        if(StringUtils.isNotEmpty(recorderDateStr)){
            Date recordDate = DateUtil.parse(recorderDateStr, "yyyy-MM-dd HH:mm:ss");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(recordDate);
            filePrintDataParams.put("y" + index, calendar.get(Calendar.YEAR));
            filePrintDataParams.put("m" + index, calendar.get(Calendar.MONTH) + 1);
            filePrintDataParams.put("d" + index, calendar.get(Calendar.DAY_OF_MONTH));
        }
        return filePrintDataParams;
    }

    /**
     * 处理人员工作信息
     */
    private Map<String, Object> resolveRecordUser(List<Long> workUserIds, String realUserNameField) {
        String realUserNameValues = "";
        //获取人员ids
        for (Long userId : workUserIds) {
            if (ObjectUtils.isNotEmpty(userId)) {
                realUserNameValues += meterStaffMapper.selectById(userId).getName() + ",";
            }
        }
        //处理人员后缀多余逗号
        if (!StringUtils.isEmpty(realUserNameValues)) {
            realUserNameValues = realUserNameValues.substring(0, realUserNameValues.length() - 1);
        }
        Map<String, Object> filePrintDataParams = new HashMap<>();
        filePrintDataParams.put(realUserNameField, realUserNameValues);
        return filePrintDataParams;
    }

    /**
     * 环境检测单和测量设备关系
     */
    private EnvironmentalRecordData equipmentRelation(FilePrintRegister filePrintRegister, BusinessSiteExecutiveLog metaData) {
        List<Map<String, Object>> siteEquipments = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        for (BusinessSiteExecutiveEquipmentRelation equipmentRelation : metaData.getSiteExecutiveEquipmentRelationList()) {
            Map<String, Object> equipmentFixedAssetsMap = new HashMap<>();
            equipmentFixedAssetsMap.put("beforeWorkResult ", equipmentRelation.getBeforeWorkCheck());
            equipmentFixedAssetsMap.put("beforeWorkResult", equipmentRelation.getBeforeWorkResult());
            equipmentFixedAssetsMap.put("afterWorkCheck", equipmentRelation.getAfterWorkCheck());
            equipmentFixedAssetsMap.put("afterWorkResult", equipmentRelation.getAfterWorkResult());
            siteEquipments.add(equipmentFixedAssetsMap);
        }
        params.put("siteEquipments", siteEquipments);
        filePrintRegister.setParams(params);
        return this;
    }


    /**
     * 1、处理测量设备工作状态相关人员及日期信息
     * 2、处理人员信息，存在多人，用逗号分割
     * 2、处理日期信息，取第一个日期进行处理填充
     *
     * @param equipmentRelationList
     */
    private EnvironmentalRecordData resolveSiteEquipmentsStatus(FilePrintRegister filePrintRegister, List<BusinessSiteExecutiveEquipmentRelation> equipmentRelationList) {
        //处理测量设备前人员equipmentRelationList = {ArrayList@16172}  size = 1
        filePrintRegister.getParams().putAll(resolveRecordUser(equipmentRelationList.stream()
                .map(BusinessSiteExecutiveEquipmentRelation::getBeforeWorkRecorderId).distinct().collect(Collectors.toList()), "beforeWorkUsers"));
        //处理测量设备后人员
        filePrintRegister.getParams().putAll(resolveRecordUser(equipmentRelationList.stream()
                .map(BusinessSiteExecutiveEquipmentRelation::getAfterWorkRecorderId).distinct().collect(Collectors.toList()), "afterWorkUsers"));
        Optional<BusinessSiteExecutiveEquipmentRelation> optionalMap = equipmentRelationList.stream().findFirst();
        if (optionalMap.isPresent()) {
            //处理测量设备前日期信息
            resolveRecordTime(optionalMap.get().getBeforeWorkRecorderDate(), 0);
            //处理测量设备后日期信息
            resolveRecordTime(optionalMap.get().getAfterWorkRecorderDate(), 1);
        }
        return this;
    }

    /**
     * 环境记录查询测量设备
     */
    private EnvironmentalRecordData equipmentFixedAssetsByLog(FilePrintRegister filePrintRegister, List<BusinessSiteExecutiveEquipmentRelation> equipmentRelationList) {
        List<Map<String, Object>> assetList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(equipmentRelationList)) {
            List<EquipmentFixedAssets> equipmentFixedAssetList = equipmentFixedAssetsService.list(equipmentRelationList.stream().map(BusinessSiteExecutiveEquipmentRelation::getEquipmentId).collect(Collectors.toList()));
            equipmentFixedAssetList.forEach(
                    equipmentFixedAsset -> {
                        Map<String, Object> equipmentFixedAssetsMap = new HashMap<>();
                        equipmentFixedAssetsMap.put("assetName ", equipmentFixedAsset.getAssetNo());
                        equipmentFixedAssetsMap.put("assetNo", equipmentFixedAsset.getAssetNo());
                        equipmentFixedAssetsMap.put("assetModel", equipmentFixedAsset.getModelNo());
                        equipmentFixedAssetsMap.put("validDate", equipmentFixedAsset.getValidDate());
                        assetList.add(equipmentFixedAssetsMap);
                    }
            );
        }
        filePrintRegister.getParams().put("assetList", assetList);
        return this;
    }

}
