package org.jeecg.modules.stm.audit.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 
 
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.jeecg.modules.stm.audit.entity.AuditCriteria;
import org.jeecg.modules.stm.audit.entity.AuditCriteriaConfig;
import org.jeecg.modules.stm.audit.entity.AuditCriteriaScores;
import org.jeecg.modules.stm.audit.service.IAuditCriteriaConfigService;
import org.jeecg.modules.stm.audit.service.IAuditCriteriaScoresService;
import org.jeecg.modules.stm.audit.service.IAuditCriteriaService;

import jakarta.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

  
@RestController
@RequestMapping("/audit/auditCriteriaScores")
@Slf4j
public class AuditCriteriaScoresController extends JeecgController<AuditCriteriaScores, IAuditCriteriaScoresService> {
	@Autowired
	private IAuditCriteriaScoresService auditCriteriaScoresService;
	@Autowired
	private IAuditCriteriaService auditCriteriaService;
	@Autowired
	private IAuditCriteriaConfigService auditCriteriaConfigService;

	  
	@GetMapping(value = "/list")
	public Result<List<AuditCriteriaScores>> queryPageList(AuditCriteriaScores auditCriteriaScores,
														   HttpServletRequest req) {
		QueryWrapper<AuditCriteriaScores> queryWrapper = QueryGenerator.initQueryWrapper(auditCriteriaScores, req.getParameterMap());
		List<AuditCriteriaScores> list = auditCriteriaScoresService.list(queryWrapper);
		return Result.OK(list);
	}

	@AutoLog(value = "audit_criteria_scores-添加")
	  
	@PostMapping(value = "/add")
	public Result<String> add(@RequestBody AuditCriteriaScores auditCriteriaScores) {
		auditCriteriaScoresService.save(auditCriteriaScores);
		return Result.OK("添加成功！");
	}

	@AutoLog(value = "audit_criteria_scores-编辑")
	  
	@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
	public Result<String> edit(@RequestBody AuditCriteriaScores auditCriteriaScores) {
		setLevel(auditCriteriaScores);
		auditCriteriaScoresService.updateById(auditCriteriaScores);
		return Result.OK("编辑成功!");
	}

	@AutoLog(value = "audit_criteria_scores-通过id删除")
	  
	@DeleteMapping(value = "/delete")
	public Result<String> delete(@RequestParam(name="id",required=true) String id) {
		auditCriteriaScoresService.removeById(id);
		return Result.OK("删除成功!");
	}

	@AutoLog(value = "audit_criteria_scores-批量删除")
	  
	@DeleteMapping(value = "/deleteBatch")
	public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.auditCriteriaScoresService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功!");
	}

	  
	@GetMapping(value = "/queryById")
	public Result<AuditCriteriaScores> queryById(@RequestParam(name="id",required=true) String id) {
		AuditCriteriaScores auditCriteriaScores = auditCriteriaScoresService.getById(id);
		if(auditCriteriaScores==null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(auditCriteriaScores);
	}

	@GetMapping(value = "/computeData")
	public Result<String> handleComputeData(@RequestParam(name="tp",required=true) Integer tp) {
		List<AuditCriteria> listCriteris = auditCriteriaService.list();
		List<AuditCriteriaConfig> listConfig = auditCriteriaConfigService.list();
		List<AuditCriteriaScores> dataList = processDimensions(listConfig, listCriteris);

		QueryWrapper<AuditCriteriaScores> queryWrapper = new QueryWrapper<>();
		auditCriteriaScoresService.remove(queryWrapper);
		setLevel(dataList);
		auditCriteriaScoresService.saveBatch(dataList);

		return Result.OK("操作成功");
	}

	public List<AuditCriteriaScores> processDimensions(List<AuditCriteriaConfig> data, List<AuditCriteria> criteriaList) {
		try {
			// 创建 criteriaId 到 AuditCriteria 的映射
			Map<Integer, AuditCriteria> criteriaMap = criteriaList.stream()
					.collect(Collectors.toMap(AuditCriteria::getCode, criteria -> criteria));

			Map<Integer, List<AuditCriteriaConfig>> dimensionMap = data.stream()
					.collect(Collectors.groupingBy(AuditCriteriaConfig::getCriteriaId));
			List<Integer> criteriaIds = new ArrayList<>(dimensionMap.keySet());
			Collections.sort(criteriaIds);
			return generateCombinations(dimensionMap, criteriaIds, criteriaMap);
		} catch (Exception e) {
			e.printStackTrace();
			return Collections.emptyList();
		}
	}

	private static List<AuditCriteriaScores> generateCombinations(
			Map<Integer, List<AuditCriteriaConfig>> dimensionMap,
			List<Integer> criteriaIds,
			Map<Integer, AuditCriteria> criteriaMap) {

		List<AuditCriteriaScores> resultList = new ArrayList<>();
		List<List<AuditCriteriaConfig>> combinations = new ArrayList<>();
		combinations.add(new ArrayList<>());

		// 生成所有组合
		for (int criteriaId : criteriaIds) {
			List<AuditCriteriaConfig> currentDimension = dimensionMap.get(criteriaId);
			List<List<AuditCriteriaConfig>> newCombinations = new ArrayList<>();
			for (List<AuditCriteriaConfig> existingCombination : combinations) {
				for (AuditCriteriaConfig data : currentDimension) {
					List<AuditCriteriaConfig> newCombination = new ArrayList<>(existingCombination);
					newCombination.add(data);
					newCombinations.add(newCombination);
				}
			}
			combinations = newCombinations;
		}

		// 为每个组合创建 AuditCriteriaScores 对象
		for (List<AuditCriteriaConfig> combination : combinations) {
			if (!combination.isEmpty()) {
				// 生成 code (使用编码)
				String code = combination.stream()
						.map(config -> config.getCriteriaId() + "_" + config.getCode())
						.collect(Collectors.joining("-"));

				// 生成 codeName (使用名称)
				String codeName = combination.stream()
						.map(config -> {
							AuditCriteria criteria = criteriaMap.get(config.getCriteriaId());
							String criteriaName = (criteria != null) ? criteria.getName() : String.valueOf(config.getCriteriaId());
							return criteriaName + "_" + config.getName();
						})
						.collect(Collectors.joining("-"));

				double minMinVal = combination.stream()
						.mapToDouble(AuditCriteriaConfig::getMinval)
						.min()
						.orElse(Double.MAX_VALUE);

				AuditCriteriaScores scores = new AuditCriteriaScores();
				scores.setCode(code);
				scores.setCodeName(codeName);
				scores.setVal(minMinVal);

				resultList.add(scores);
			}
		}
		return resultList;
	}

	private void setLevel(List<AuditCriteriaScores> data) {
		for(AuditCriteriaScores scores : data) {
			setLevel(scores);
		}
	}
	private void setLevel(AuditCriteriaScores scores) {
		try {
				if(scores.getVal()!=null) {
					if(scores.getVal()<=2){
						scores.setLevel(2);
					} else if(scores.getVal()<=3) {
						scores.setLevel(3);
					} else if(scores.getVal()<=4) {
						scores.setLevel(4);
					} else {
						scores.setLevel(5);
					}
				} else {
					scores.setLevel(0);
				}


		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}