package com.ruoyi.web.controller.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.exam.ElExam;
import com.ruoyi.system.domain.exam.ElExamDepart;
import com.ruoyi.system.domain.exam.ElExamRepo;
import com.ruoyi.system.domain.exam.dto.ExamDTO;
import com.ruoyi.system.domain.exam.dto.ExamRepoDTO;
import com.ruoyi.system.domain.exam.dto.ext.ExamRepoExtDTO;
import com.ruoyi.system.domain.exam.dto.request.ExamSaveReqDTO;
import com.ruoyi.system.domain.exam.dto.response.ExamOnlineRespDTO;
import com.ruoyi.system.domain.exam.enums.OpenType;
import com.ruoyi.system.service.ElExamDepartService;
import com.ruoyi.system.service.ElExamRepoService;
import com.ruoyi.system.service.ElExamService;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * packageName com.ruoyi.web.controller.manager
 *
 * @author wangxy
 * @version JDK 8
 * @className Exammanager
 * @date 2024/6/28
 * @description 考试
 */
@Component
public class ExamManager {


    @Resource
    private ElExamService elExamService;


    @Resource
    private ElExamRepoService examRepoService;


    @Resource
    private ElExamDepartService elExamDepartService;


    /**
     * 查询
     *
     * @param examDTO
     * @return java.util.List<com.hyp.system.domain.SysNotice>
     */
    public List<ExamDTO> selectExamList(ExamDTO examDTO) {
        return elExamService.selectExamList(examDTO);
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(ExamSaveReqDTO reqDTO) {
        // 计算分值
        this.calcScore(reqDTO);
        ElExam elExam = Convert.convert(ElExam.class, reqDTO);
        // 修复状态
        if (Objects.nonNull(reqDTO.getTimeLimit()) && !reqDTO.getTimeLimit()
                && Objects.nonNull(reqDTO.getState())
                && Objects.equals(reqDTO.getState(), 2)) {
            elExam.setState(0);
        } else {
            elExam.setState(reqDTO.getState());
        }
        if (StringUtils.isNotEmpty(reqDTO.getId())) {
            elExam.setUpdateTime(new Date());
            LambdaQueryWrapper<ElExamRepo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ElExamRepo::getExamId, reqDTO.getId());
            examRepoService.remove(wrapper);
            LambdaQueryWrapper<ElExamDepart> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(ElExamDepart::getExamId, reqDTO.getId());
            elExamDepartService.remove(queryWrapper);
        } else {
            elExam.setCreateTime(new Date());
        }
        if (CollUtil.isNotEmpty(reqDTO.getRepoList())) {
            List<ElExamRepo> examRepos = Convert.toList(ElExamRepo.class, reqDTO.getRepoList());
            examRepos.forEach(elExamRepo -> elExamRepo.setExamId(elExam.getId()));
            examRepoService.saveBatch(examRepos);
        }
        if (CollUtil.isNotEmpty(reqDTO.getDepartIds()) && OpenType.DEPT_OPEN.equals(reqDTO.getOpenType())) {
            List<ElExamDepart> list = new ArrayList<>();
            reqDTO.getDepartIds().forEach(deptId -> {
                ElExamDepart ref = new ElExamDepart();
                ref.setExamId(elExam.getId());
                ref.setDepartId(deptId);
                list.add(ref);
            });
            elExamDepartService.saveBatch(list);
        }
        return elExamService.saveOrUpdate(elExam);
    }


    @Transactional(rollbackFor = Exception.class)
    public boolean deleteQuByIds(String ids) {
        List<String> list = Arrays.asList(Convert.toStrArray(ids));
        elExamService.removeByIds(list);
        LambdaQueryWrapper<ElExamDepart> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ElExamDepart::getExamId, list);
        elExamDepartService.remove(queryWrapper);
        LambdaQueryWrapper<ElExamRepo> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(ElExamRepo::getExamId, list);
        return examRepoService.remove(wrapper);
    }

    /**
     * 详情
     *
     * @param id
     * @return com.ruoyi.system.domain.exam.dto.request.ExamSaveReqDTO
     */


    public ExamSaveReqDTO detail(String id) {
        ElExam exam = elExamService.getById(id);
        ExamSaveReqDTO respDTO = Convert.convert(ExamSaveReqDTO.class, exam);
        // 考试部门
        List<Long> departIds = elExamDepartService.lambdaQuery()
                .eq(ElExamDepart::getExamId, id).list().stream()
                .map(ElExamDepart::getDepartId).collect(Collectors.toList());
        respDTO.setDepartIds(departIds);
        // 题库
        List<ExamRepoExtDTO> list = examRepoService.listByExam(id);
        respDTO.setRepoList(list);
        return respDTO;
    }


    public ExamDTO view(String id) {
        ElExam exam = elExamService.getById(id);
        return Convert.convert(ExamDTO.class, exam);
    }


    /**
     * 在线考试
     *
     * @param examDTO
     * @return java.util.List<com.ruoyi.system.domain.exam.dto.response.ExamOnlineRespDTO>
     */
    public List<ExamOnlineRespDTO> onlineExamList(ExamDTO examDTO) {
        return elExamService.onlineExamList(examDTO);
    }


    /**
     * 计算分值
     *
     * @param reqDTO
     */
    private void calcScore(ExamSaveReqDTO reqDTO) {
        // 主观题分数
        int objScore = 0;
        // 题库组卷
        List<ExamRepoExtDTO> repoList = reqDTO.getRepoList();
        for (ExamRepoDTO item : repoList) {
            if (item.getRadioCount() != null
                    && item.getRadioCount() > 0
                    && item.getRadioScore() != null
                    && item.getRadioScore() > 0) {
                objScore += item.getRadioCount() * item.getRadioScore();
            }
            if (item.getMultiCount() != null
                    && item.getMultiCount() > 0
                    && item.getMultiScore() != null
                    && item.getMultiScore() > 0) {
                objScore += item.getMultiCount() * item.getMultiScore();
            }
            if (item.getJudgeCount() != null
                    && item.getJudgeCount() > 0
                    && item.getJudgeScore() != null
                    && item.getJudgeScore() > 0) {
                objScore += item.getJudgeCount() * item.getJudgeScore();
            }
        }
        reqDTO.setTotalScore(objScore);
    }

}
