package org.security.trans.dataStatistics.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.security.common.Constant;
import org.security.trans.assessment.entity.AssessmentDetail;
import org.security.trans.assessment.service.IAssessmentDetailService;
import org.security.trans.assessment.service.IAssessmentService;
import org.security.trans.dataStatistics.dto.AssessmentDataDTO;
import org.security.trans.dataStatistics.service.AssessmentDataService;
import org.security.trans.dataStatistics.util.CalculationRatioUtil;
import org.security.trans.dataStatistics.vo.AssessmentDataVO;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ：wzf
 * @since ：Created in 2022/11/24 11:34
 */
@Service
@Slf4j
@AllArgsConstructor
public class AssessmentDataServiceImpl implements AssessmentDataService {

	private final InspectionDataServiceImpl inspectionDataService;
	private final IAssessmentService assessmentService;
	private final IAssessmentDetailService assessmentDetailService;


	@Override
	public IPage<AssessmentDataVO> getTableData(AssessmentDataDTO assessmentDataDTO, IPage<AssessmentDataVO> page) {
		log.info("---------------------考核评价数据统计列表数据获取开始---------------------");
		List<AssessmentDataVO> vos = new ArrayList<>();
		//获取查询部门的ids
		List<String> aimDepts = inspectionDataService.setDeptIds(assessmentDataDTO.getEvaluated(), assessmentDataDTO.getIncludeChildren());
		//判断需要统计哪一类型的考核数据（1-机构考核统计，2-相关方考核统计，3-项目考核统计）
		List<String> aimType = new ArrayList<>();
		//获取统计数据
		List<AssessmentDataVO> baseData = getStatisticsData(assessmentDataDTO, aimDepts, aimType);
		if (Func.isNotEmpty(baseData)) {
			log.info("考核评价统计数据[{}]", baseData);
			//赋值统计基础值
			setBaseData(baseData);
			//根据deptId和evaluatedName分组计算统计值
			setResultData(assessmentDataDTO, vos, baseData);
		}
		//计算出一条总计值
		setTotalData(assessmentDataDTO, vos);
		log.info("---------------------考核评价数据统计列表数据获取结束---------------------");
		return page.setRecords(vos);
	}

	/**
	 * 获取统计数据
	 */
	private List<AssessmentDataVO> getStatisticsData(AssessmentDataDTO assessmentDataDTO, List<String> aimDepts, List<String> aimType) {
		List<AssessmentDataVO> baseData = new ArrayList<>();
		//机构考核统计
		if (Func.isNotEmpty(assessmentDataDTO.getDataType()) && Constant.STATISTICS_ASSESSMENT_TYPE_ONE.equals(assessmentDataDTO.getDataType())) {
			aimType.add(Constant.ASSESSMENT_TYPE_ONE);
			aimType.add(Constant.ASSESSMENT_TYPE_TWO);
			aimType.add(Constant.ASSESSMENT_TYPE_THREE);
			baseData = assessmentService.getAimStatisticsData(assessmentDataDTO, aimDepts, aimType);
		}
		//相关方考核
		if (Func.isNotEmpty(assessmentDataDTO.getDataType()) && Constant.STATISTICS_ASSESSMENT_TYPE_TWO.equals(assessmentDataDTO.getDataType())) {
			aimType.add(Constant.ASSESSMENT_TYPE_FOUR);
			baseData = assessmentService.getAimStatisticsData(assessmentDataDTO, aimDepts, aimType);
		}
		//项目考核
		if (Func.isNotEmpty(assessmentDataDTO.getDataType()) && Constant.STATISTICS_ASSESSMENT_TYPE_THREE.equals(assessmentDataDTO.getDataType())) {
			aimType.add(Constant.ASSESSMENT_TYPE_FIVE);
			baseData = assessmentService.getProjectStatisticsData(assessmentDataDTO, aimType);
		}
		return baseData;
	}

	/**
	 * 赋值统计基础值
	 */
	private void setBaseData(List<AssessmentDataVO> baseData) {
		baseData.forEach(item -> {
			item.setTotalNum(1);
			List<AssessmentDetail> list = assessmentDetailService.list(new QueryWrapper<AssessmentDetail>().lambda()
				.eq(Func.isNotEmpty(item.getId()), AssessmentDetail::getParentId, item.getId())
				.eq(AssessmentDetail::getScoreType, "2"));
			item.setProblemNum((Func.isNotEmpty(list) && list.size() > 0) ? list.size() : 0);
		});
	}

	/**
	 * 根据deptId和evaluatedName分组计算统计值
	 */
	private void setResultData(AssessmentDataDTO assessmentDataDTO, List<AssessmentDataVO> vos, List<AssessmentDataVO> baseData) {
		Map<String, List<AssessmentDataVO>> collect = baseData.stream().collect(Collectors.groupingBy(item -> item.getDeptId().concat("-").concat(item.getEvaluatedName())));
		if (Func.isNotEmpty(collect)) {
			collect.forEach(((key, value) -> {
				AssessmentDataVO assessmentDataVO = new AssessmentDataVO();
				assessmentDataVO.setBeginDate(assessmentDataDTO.getBeginDate());
				assessmentDataVO.setEndDate(assessmentDataDTO.getEndDate());
				assessmentDataVO.setDeptId(key.split("-")[0]);
				assessmentDataVO.setEvaluatedName(key.split("-")[1]);
				assessmentDataVO.setTotalNum(value.stream().mapToInt(AssessmentDataVO::getTotalNum).sum());
				assessmentDataVO.setProblemNum(value.stream().mapToInt(AssessmentDataVO::getProblemNum).sum());
				BigDecimal totalScore = value.stream().map(AssessmentDataVO::getFinalScore).reduce(BigDecimal.ZERO, BigDecimal::add);
				assessmentDataVO.setFinalScore(totalScore);
				assessmentDataVO.setAverage(CalculationRatioUtil.getAimBigDecimal(totalScore, BigDecimal.valueOf(assessmentDataVO.getTotalNum())));
				vos.add(assessmentDataVO);
			}));
		}
	}

	/**
	 * 计算出一条总计值
	 */
	private void setTotalData(AssessmentDataDTO assessmentDataDTO, List<AssessmentDataVO> vos) {
		if (Func.isNotEmpty(vos)) {
			AssessmentDataVO vo = new AssessmentDataVO();
			vo.setBeginDate(assessmentDataDTO.getBeginDate());
			vo.setEndDate(assessmentDataDTO.getEndDate());
			vo.setEvaluatedName("总计");
			vo.setDeptId(null);
			vo.setTotalNum(vos.stream().mapToInt(AssessmentDataVO::getTotalNum).sum());
			vo.setProblemNum(vos.stream().mapToInt(AssessmentDataVO::getProblemNum).sum());
			vo.setFinalScore(vos.stream().map(AssessmentDataVO::getFinalScore).reduce(BigDecimal.ZERO, BigDecimal::add));
			vo.setAverage(CalculationRatioUtil.getAimBigDecimal(vo.getFinalScore(), BigDecimal.valueOf(vo.getTotalNum())));
			vos.add(0, vo);
		}
	}
}
