package com.xjrsoft.module.evaluate.service.impl;

import camundajar.impl.scala.runtime.LambdaDeserialize;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xjrsoft.common.enums.DeleteMark;
import com.xjrsoft.common.enums.EnabledMark;
import com.xjrsoft.common.enums.EvaluateTypeEnum;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.base.entity.BaseGrade;
import com.xjrsoft.module.evaluate.dto.*;
import com.xjrsoft.module.evaluate.entity.EvaluateExecuter;
import com.xjrsoft.module.evaluate.entity.EvaluateManage;
import com.xjrsoft.module.evaluate.entity.EvaluateObject;
import com.xjrsoft.module.evaluate.entity.EvaluateTemplate;
import com.xjrsoft.module.evaluate.mapper.EvaluateExecuterMapper;
import com.xjrsoft.module.evaluate.mapper.EvaluateManageMapper;
import com.xjrsoft.module.evaluate.mapper.EvaluateObjectMapper;
import com.xjrsoft.module.evaluate.service.IEvaluateObjectService;
import com.xjrsoft.module.evaluate.vo.EvaluateExecuterVo;
import com.xjrsoft.module.evaluate.vo.EvaluateManageVo;
import com.xjrsoft.module.evaluate.vo.EvaluateObjectGradeListVo;
import com.xjrsoft.module.evaluate.vo.EvaluateObjectListVo;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
* @title: 评价管理
* @Author dzx
* @Date: 2024-01-16
* @Version 1.0
*/
@Service
@AllArgsConstructor
public class EvaluateObjectServiceImpl extends MPJBaseServiceImpl<EvaluateObjectMapper, EvaluateObject> implements IEvaluateObjectService {
    private final EvaluateManageMapper evaluateManageMapper;

    private final EvaluateObjectMapper evaluateObjectMapper;
    private final EvaluateExecuterMapper evaluateExecuterMapper;


    @Override
    public List<EvaluateObjectListVo> getObjectList(EvaluateObjectListDto dto) {
        List<EvaluateObjectListVo> objectList = evaluateObjectMapper.getObjectList(dto);
        List<EvaluateExecuterVo> allExecuterList = evaluateObjectMapper.getExecuterList(dto);

        Map<String, List<EvaluateExecuterVo>> groupEvaluateExecuterByEvaluateObjectId = allExecuterList.stream()
                .collect(Collectors.groupingBy(EvaluateExecuterVo::getEvaluateObjectId));
        for (EvaluateObjectListVo objectVo : objectList) {
            objectVo.setExecuterCount(groupEvaluateExecuterByEvaluateObjectId.get(objectVo.getId()).size());
            objectVo.setExecuterList(groupEvaluateExecuterByEvaluateObjectId.get(objectVo.getId()));
            /*List<EvaluateExecuterVo> executerList = new ArrayList<>();
            for (EvaluateExecuterVo executerVo : allExecuterList) {
                if(objectVo.getId().equals(executerVo.getEvaluateObjectId())){
                    executerList.add(executerVo);
                }
            }

            objectVo.setExecuterCount(executerList.size());
            objectVo.setExecuterList(executerList);*/
        }
        return objectList;
    }

    @Override
    public List<EvaluateObjectGradeListVo> getObjectGradeList(EvaluateObjectGradeListDto dto) {
        /*SELECT
            count(t1.id),
            t1.base_grade_id,
            t2.name,
            count(t4.id)
        FROM evaluate_object t1
                 LEFT JOIN base_grade t2 ON t2.id = t1.base_grade_id
                 LEFT JOIN evaluate_executer t4 ON t4.evaluate_object_id = t1.id
        WHERE t1.delete_mark = 0 and t1.evaluate_manage_id = 1747177686090969089
        group by t1.base_grade_id;*/
        MPJLambdaWrapper<EvaluateObject> evaluateObjectMPJLambdaWrapper = new MPJLambdaWrapper<>();
        evaluateObjectMPJLambdaWrapper
                .selectAs(EvaluateObject::getEvaluateManageId, EvaluateObjectGradeListVo::getEvaluateManageId)
                .select("count(distinct t.id) as objectCount")
                .selectAs(EvaluateObject::getBaseGradeId, EvaluateObjectGradeListVo::getGradeId)
                .selectAs(BaseGrade::getName, EvaluateObjectGradeListVo::getGradeName)
                .selectCount(EvaluateExecuter::getId, EvaluateObjectGradeListVo::getExecuterCount)
                .leftJoin(BaseGrade.class, BaseGrade::getId, EvaluateObject::getBaseGradeId)
                .leftJoin(EvaluateExecuter.class, EvaluateExecuter::getEvaluateObjectId, EvaluateObject::getId)
                .eq(EvaluateObject::getEvaluateManageId, dto.getEvaluateManageId())
                .groupBy(EvaluateObject::getBaseGradeId)
                .disableSubLogicDel();

        return this.selectJoinList(EvaluateObjectGradeListVo.class, evaluateObjectMPJLambdaWrapper);
    }

    @Override
    @Transactional
    public Boolean objectGradeDelete(ObjectGradeDeleteDto dto) {
        //获取当前评价管理的类型
        LambdaQueryWrapper<EvaluateManage> evaluateManageMPJLambdaWrapper = new LambdaQueryWrapper<>();
        evaluateManageMPJLambdaWrapper
                .eq(EvaluateManage::getId, dto.getEvaluateManageId());
        EvaluateManage evaluateManage = evaluateManageMapper.selectOne(evaluateManageMPJLambdaWrapper);
        if(evaluateManage == null){
            throw new MyException("该评价管理已经失效");
        }

        if(evaluateManage.getStatus() != -1){
            throw new MyException("该评价管理正在使用");
        }
        evaluateObjectMapper.objectGradeDeleteExecuter(dto);
        evaluateObjectMapper.objectGradeDeleteObject(dto);
        return true;
    }

    @Override
    public Boolean save(SaveEvaluateObjectDto dto) {
        //获取当前评价管理的类型
        MPJLambdaWrapper<EvaluateManage> evaluateManageMPJLambdaWrapper = new MPJLambdaWrapper<>();
        evaluateManageMPJLambdaWrapper
                .selectAs(EvaluateTemplate::getEvaluateType, EvaluateManageVo::getEvaluateType)
                .select(EvaluateManage.class, x -> VoToColumnUtil.fieldsToColumns(EvaluateManageVo.class).contains(x.getProperty()))
                .innerJoin(EvaluateTemplate.class, EvaluateTemplate::getId, EvaluateManage::getEvaluateTemplateId)
                .eq(EvaluateManage::getId, dto.getEvaluateManageId())
                .disableSubLogicDel();
        EvaluateManageVo evaluateManageVo = evaluateManageMapper.selectJoinOne(EvaluateManageVo.class, evaluateManageMPJLambdaWrapper);
        if(evaluateManageVo == null){
           throw new MyException("未查询到信息，evaluateManageId不正确");
        }

        if(evaluateManageVo.getStatus() != -1){
            throw new MyException("该评价正在使用");
        }

        //清空原有数据
        evaluateObjectMapper.deleteByEvaluateManageId(evaluateManageVo.getId());
        evaluateExecuterMapper.deleteByEvaluateManageId(evaluateManageVo.getId());

        //保存新数据
        Date createDate = new Date();
        long createUserId = StpUtil.getLoginIdAsLong();
        for (AddEvaluateObjectDto objectDto : dto.getObjectList()) {
            if(StrUtil.isEmpty(objectDto.getObjectId())){
               continue;
            }
            EvaluateObject evaluateObject = new EvaluateObject();
            evaluateObject.setObjectId(Long.parseLong(objectDto.getObjectId()));
            evaluateObject.setEvaluateManageId(Long.parseLong(dto.getEvaluateManageId()));
            evaluateObject.setDeleteMark(DeleteMark.NODELETE.getCode());
            evaluateObject.setCreateDate(createDate);
            evaluateObject.setCreateUserId(createUserId);
            evaluateObject.setEnabledMark(EnabledMark.ENABLED.getCode());
            evaluateObject.setBaseGradeId(Long.parseLong(objectDto.getGradeId()));
            if(evaluateManageVo.getEvaluateType().equals(EvaluateTypeEnum.DRILLMASTER_EVALUATE_CLASS.getCode())){
                evaluateObject.setObjectType("class");
            }
            if(evaluateManageVo.getEvaluateType().equals(EvaluateTypeEnum.STUDENT_EVALUATE_HEAD_TEACHER.getCode())){
                evaluateObject.setObjectType("teacher");
            }
            evaluateObjectMapper.insert(evaluateObject);

            for (AddEvaluateExecuterDto executerDto : objectDto.getExecuterList()) {
                EvaluateExecuter executer = new EvaluateExecuter();
                executer.setCreateDate(createDate);
                executer.setCreateUserId(createUserId);
                executer.setEvaluateManageId(Long.parseLong(dto.getEvaluateManageId()));
                executer.setEvaluateObjectId(evaluateObject.getId());
                executer.setUserId(Long.parseLong(executerDto.getExecuterId()));
                executer.setStatus(0);
                evaluateExecuterMapper.insert(executer);
            }
        }
        return true;
    }

    @Override
    public List<EvaluateObjectListVo> getNewObjectList(EvaluateObjectListDto dto) {
        List<EvaluateObjectListVo> newObjectList = new ArrayList<>();
        //入参评价类型是学生评价班主任
        if(dto.getEvaluateType() != null && dto.getEvaluateType().equals(EvaluateTypeEnum.STUDENT_EVALUATE_HEAD_TEACHER.getCode())){
            newObjectList = evaluateObjectMapper.getNewObjectList(dto);
            List<EvaluateExecuterVo> newExecuterList = evaluateObjectMapper.getNewExecuterList(dto);

            //将学生按照班级处理成map
            Map<String, List<EvaluateExecuterVo>> evaluateExecuterVoMap = newExecuterList.stream()
                    .collect(Collectors.groupingBy(EvaluateExecuterVo::getClassId));

            for (EvaluateObjectListVo objectListVo : newObjectList) {
                List<EvaluateExecuterVo> dataList = new ArrayList<>();
                /*for (EvaluateExecuterVo executerVo : newExecuterList) {
                    if(!executerVo.getClassId().equals(objectListVo.getClassId())){
                        continue;
                    }
                    dataList.add(executerVo);
                }*/
                List<EvaluateExecuterVo> executerList = new ArrayList<>();
                if(evaluateExecuterVoMap.get(objectListVo.getClassId()) != null){
                    dataList.addAll(evaluateExecuterVoMap.get(objectListVo.getClassId()));
                    if("random15".equals(dto.getExecuterCount()) && dataList.size() > 0){
                        List<Integer> randomList = new ArrayList<>();
                        Random random = new Random();
                        while(randomList.size() < 15){
                            int nextInt = random.nextInt(dataList.size());
                            if(!randomList.contains(nextInt) && nextInt >= 0){
                                randomList.add(nextInt);
                            }
                        }
                        for (Integer i : randomList) {
                            executerList.add(dataList.get(i));
                        }
                    }else{
                        executerList.addAll(dataList);
                    }
                }
                objectListVo.setExecuterCount(executerList.size());
                objectListVo.setExecuterList(executerList);
            }
        }

        //入参评价类型是教官评价班级
        if(dto.getEvaluateType() != null && dto.getEvaluateType().equals(EvaluateTypeEnum.DRILLMASTER_EVALUATE_CLASS.getCode())) {
            newObjectList = evaluateObjectMapper.getNewObjectList(dto);
            List<EvaluateExecuterVo> newExecuterList = evaluateObjectMapper.getNewExecuterList(dto);

            for (EvaluateObjectListVo objectListVo : newObjectList) {
                objectListVo.setExecuterCount(newExecuterList.size());
                objectListVo.setExecuterList(newExecuterList);
            }
        }

        return newObjectList;
    }
}
