package com.zd.exam.service.impl;

import com.zd.common.core.exception.ServiceException;
import com.zd.common.security.service.TokenService;
import com.zd.exam.domain.*;
import com.zd.exam.domain.vo.ExamConfig;
import com.zd.exam.enums.QuType;
import com.zd.exam.mapper.ElExamQuAnswerMapper;
import com.zd.exam.mapper.ElExamQuMapper;
import com.zd.exam.mapper.ElExamRepoMapper;
import com.zd.exam.mapper.ElRepoMapper;
import com.zd.exam.service.ElExamRepoService;
import com.zd.exam.service.ElQuAnswerService;
import com.zd.exam.service.ElQuService;
import com.zd.system.api.model.LoginUser;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 考试题库(ElExamRepo)表服务实现类
 *
 * @author liubo
 * @since 2021-08-31 09:23:50
 */
@Service("elExamRepoService")
public class ElExamRepoServiceImpl implements ElExamRepoService {
    @Resource
    private ElExamRepoMapper elExamRepoMapper;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private ElRepoMapper repoMapper;
    @Autowired
    private ElExamQuMapper examQuMapper;
    @Autowired
    private ElExamQuAnswerMapper examQuAnswerMapper;
    @Autowired
    private ElQuAnswerService elQuAnswerService;
    @Autowired
    private ElQuService elQuService;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public ElExamRepo queryById(Long id) {
        return this.elExamRepoMapper.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<ElExamRepo> queryAllByLimit(int offset, int limit) {
        return this.elExamRepoMapper.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param elExamRepo 实例对象
     * @return 实例对象
     */
    @Override
    public ElExamRepo insert(ElExamRepo elExamRepo) {
        this.elExamRepoMapper.insert(elExamRepo);
        return elExamRepo;
    }

    /**
     * 修改数据
     *
     * @param elExamRepo 实例对象
     * @return 实例对象
     */
    @Override
    public ElExamRepo update(ElExamRepo elExamRepo) {
        this.elExamRepoMapper.update(elExamRepo);
        return this.queryById(elExamRepo.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.elExamRepoMapper.deleteById(id) > 0;
    }

    /**
     * 自动组题添加数据
     */
    @Override
    public void saveAll(ElExam elExam) {

        long examId = elExam.getId();
        List<ElExamRepo> repoList = elExam.getRepoList();
        LoginUser loginUser = tokenService.getLoginUser();
        // 先删除
        elExamRepoMapper.deleteByExamId(examId);

        // 再增加
        if (CollectionUtils.isEmpty(repoList)) {
            throw new ServiceException("必须选择题库！");
        }
        Date now = new Date();
        ElRepo repo;

        List<Long> classifyIds = new ArrayList<>();

        int radioCounts = 0, multiCounts = 0, judgeCounts = 0;
        for (ElExamRepo item : repoList) {
            // 2.1 新增考试去掉题库概念
            // 查询题库数量
            /*repo = repoMapper.queryById(item.getRepoId());

            if (item.getRadioCount() != null && repo.getRadioCount() < item.getRadioCount()) {
                throw new ServiceException("题库：" + repo.getTitle() + "单选题数量（" + repo.getRadioCount() + "）不足" + item.getRadioCount());
            }
            if (item.getMultiCount() != null && repo.getMultiCount() < item.getMultiCount()) {
                throw new ServiceException("题库：" + repo.getTitle() + "多选题数量（" + repo.getMultiCount() + "）不足" + item.getMultiCount());
            }
            if (item.getJudgeCount() != null && repo.getJudgeCount() < item.getJudgeCount()) {
                throw new ServiceException("题库：" + repo.getTitle() + "判断题数量（" + repo.getJudgeCount() + "）不足" + item.getJudgeCount());
            }*/

            if(item.getClassifyId() == null){
                throw new ServiceException("题目分类不能为空！");
            }

            classifyIds.add(item.getClassifyId());
            radioCounts += item.getRadioCount();
            multiCounts += item.getMultiCount();
            judgeCounts += item.getJudgeCount();

            item.setExamId(examId);
            item.setCreateTime(now);
            item.setCreateBy(loginUser.getUsername());
            item.setUpdateBy(loginUser.getUsername());
            item.setUpdateTime(now);
            item.setUserId(loginUser.getUserid());
            item.setDeptId(loginUser.getSysUser().getDeptId());
            item.setDeptName(loginUser.getSysUser().getDeptName());
        }

        // 校验题库数据量
        checkQuNum(classifyIds, radioCounts, multiCounts, judgeCounts);

        try {
            elExamRepoMapper.insertBatch(repoList);
        } catch (DuplicateKeyException e) {
            throw new ServiceException("不能选择重复的题库！");
        }

        // 手动题库组卷
        if (2 == elExam.getJoinType()) {
            saveAllByJoin(elExam);
        }

    }

    private void checkQuNum(List<Long> classifyIds, int radioCounts, int multiCounts, int judgeCounts) {
        Map<String, Integer> data = elQuService.selectQuCountByClassifyIds(classifyIds);
        if(Integer.parseInt(data.get("radioCounts")+ "") < radioCounts){
            throw new ServiceException("该分类单选题数量不足，创建失败！");
        }else if(Integer.parseInt(data.get("multiCounts")+ "") < multiCounts){
            throw new ServiceException("该分类多选题数量不足，创建失败！");
        }else if(Integer.parseInt(data.get("judgeCounts")+ "") < judgeCounts){
            throw new ServiceException("该分类判断题数量不足，创建失败！");
        }
    }

    /**
     * 手动组题添加数据
     */
    public void saveAllByJoin(ElExam elExam) {
        List<ElExamRepo> repoList = elExam.getRepoList();
        for (ElExamRepo elExamRepo : repoList) {

            saveExamQuAndAnswer(elExamRepo);
        }
    }

    /**
     * 保存试卷试题列表
     */
    private void saveExamQuAndAnswer(ElExamRepo elExamRepo) {

        List<ElExamQu> batchQuList = new ArrayList<>();

        List<ElQu> quList = elQuService.queryByIds(elExamRepo.getQuIds());
        if(quList.size() == 0){
            throw new ServiceException("问题不能为空！");
        }
        int sort = 0;
        ElExamQu elExamQu;
        for (ElQu item : quList) {

            elExamQu = new ElExamQu();

            elExamQu.setQuId(item.getId());
            elExamQu.setAnswered(0);
            elExamQu.setIsRight(0);
            elExamQu.setExamRepoId(elExamRepo.getId());
            elExamQu.setSort(sort);
            elExamQu.setQuType(item.getQuType());


            if (QuType.RADIO.equals(item.getQuType())) {
                elExamQu.setScore(elExamRepo.getRadioScore());
                elExamQu.setActualScore(elExamRepo.getRadioScore());
            }

            if (QuType.MULTI.equals(item.getQuType())) {
                elExamQu.setScore(elExamRepo.getMultiScore());
                elExamQu.setActualScore(elExamRepo.getMultiScore());
            }

            if (QuType.JUDGE.equals(item.getQuType())) {
                elExamQu.setScore(elExamRepo.getJudgeScore());
                elExamQu.setActualScore(elExamRepo.getJudgeScore());
            }

            batchQuList.add(elExamQu);
            sort++;
        }

        //添加问题
        examQuMapper.addBatchExamQu(batchQuList);

        List<ElExamQuAnswer> batchAnswerList = new ArrayList<>();
        ElExamQuAnswer examQuAnswer;
        for (ElExamQu examQu : batchQuList) {
            //回答列表
            List<ElQuAnswer> answerList = elQuAnswerService.queryByQuId(examQu.getQuId());

            if (!CollectionUtils.isEmpty(answerList)) {

                int ii = 0;
                for (ElQuAnswer answer : answerList) {
                    examQuAnswer = new ElExamQuAnswer();
                    examQuAnswer.setExamQuId(examQu.getId());
                    examQuAnswer.setQuId(answer.getQuId());
                    examQuAnswer.setAnswerId(answer.getId());
                    examQuAnswer.setChecked(0);
                    examQuAnswer.setSort(ii);
                    examQuAnswer.setAbc(QuType.ABC.get(ii));
                    examQuAnswer.setIsRight(answer.getIsRight());
                    ii++;
                    batchAnswerList.add(examQuAnswer);
                }
            }
        }

        //批量添加问题答案
        examQuAnswerMapper.addBatchExamQuAnswer(batchAnswerList);
    }

    @Override
    public List<ElExamRepo> queryByExamId(Long examId) {
        ElExamRepo elExamRepo = new ElExamRepo();
        elExamRepo.setExamId(examId);
        return elExamRepoMapper.queryAll(elExamRepo);
    }

    @Override
    public int deleteByExamId(Long examId) {
        return elExamRepoMapper.deleteByExamId(examId);
    }

    @Override
    public ExamConfig selectSumScoreByExamId(Long examId) {
        return elExamRepoMapper.selectSumScoreByExamId(examId);
    }

}
