package com.zhongzheng.modules.bank.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.zhongzheng.common.exception.CustomException;
import com.zhongzheng.common.utils.DateUtils;
import com.zhongzheng.modules.bank.bo.QuestionSimulateAddBo;
import com.zhongzheng.modules.bank.bo.QuestionSimulateEditBo;
import com.zhongzheng.modules.bank.bo.QuestionSimulateQueryBo;
import com.zhongzheng.modules.bank.domain.Question;
import com.zhongzheng.modules.bank.domain.QuestionBank;
import com.zhongzheng.modules.bank.domain.QuestionSimulate;
import com.zhongzheng.modules.bank.mapper.QuestionBankExamMapper;
import com.zhongzheng.modules.bank.mapper.QuestionBankSectionMapper;
import com.zhongzheng.modules.bank.mapper.QuestionMapper;
import com.zhongzheng.modules.bank.mapper.QuestionSimulateMapper;
import com.zhongzheng.modules.bank.service.IQuestionBankService;
import com.zhongzheng.modules.bank.service.IQuestionSimulateService;
import com.zhongzheng.modules.bank.vo.QuestionBankSectionVo;
import com.zhongzheng.modules.bank.vo.QuestionBankVo;
import com.zhongzheng.modules.bank.vo.QuestionSimulateVo;
import com.zhongzheng.modules.bank.vo.QuestionVo;
import com.zhongzheng.modules.exam.domain.ExamConfig;
import com.zhongzheng.modules.exam.mapper.ExamConfigMapper;
import com.zhongzheng.modules.exam.vo.ExamConfigVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;

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

/**
 * 模拟题库Service业务层处理
 *
 * @author ruoyi
 * @date 2021-06-24
 */
@Service
public class QuestionSimulateServiceImpl extends ServiceImpl<QuestionSimulateMapper, QuestionSimulate> implements IQuestionSimulateService {

    @Autowired
    private ExamConfigMapper examConfigMapper;

    @Autowired
    private QuestionMapper questionMapper;



    @Override
    public QuestionSimulateVo queryById(Long simulateId){
        QuestionSimulate db = this.baseMapper.selectById(simulateId);
        return BeanUtil.toBean(db, QuestionSimulateVo.class);
    }

    @Override
    public Map<String,Object> queryByBankId(Long bankId,Long userId) {
        Map<String,Object> param = new HashMap<>();
        param.put("bankId",bankId);
        System.out.println(bankId);
        ExamConfig vo = examConfigMapper.selectBankExamConfig(param);
        if(vo==null){
            throw new CustomException("该题库暂不支持模拟考试");
        }
        //抽选单选题
        Map<String,Object> param1 = new HashMap<>();
        param1.put("bankId",bankId);
        param1.put("type",1);
        param1.put("num",vo.getSingleChoiceNum());
        List<Question> listToatl = new ArrayList<>();
        List<Question> list1 = questionMapper.selectQuestionSimulateList(param1);
        String type1_ids ="";
        if(list1.size()<vo.getSingleChoiceNum()){
            throw new CustomException("题库单选题数不足");
        }
        for (Question s : list1) {
            type1_ids += s.getQuestionId()+",";
            listToatl.add(s);
        }
        //抽选多选题
        Map<String,Object> param2 = new HashMap<>();
        param2.put("bankId",bankId);
        param2.put("type",2);
        param2.put("num",vo.getMultipleChoiceNum());
        List<Question> list2 = questionMapper.selectQuestionSimulateList(param2);
        String type2_ids ="";
        if(list2.size()<vo.getMultipleChoiceNum()){
            throw new CustomException("题库多选题数不足");
        }
        for (Question s : list2) {
            type2_ids += s.getQuestionId()+",";
            listToatl.add(s);
        }
        //抽选判断题
        Map<String,Object> param3 = new HashMap<>();
        param3.put("bankId",bankId);
        param3.put("type",3);
        param3.put("num",vo.getJudgmentNum());
        List<Question> list3 = questionMapper.selectQuestionSimulateList(param3);
        String type3_ids ="";
        if(list3.size()<vo.getJudgmentNum()){
            throw new CustomException("题库判断题数不足");
        }
        for (Question s : list3) {
            type3_ids += s.getQuestionId()+",";
            listToatl.add(s);
        }
        //抽选案例题
        Map<String,Object> param4 = new HashMap<>();
        param4.put("bankId",bankId);
        param4.put("type",4);
        param4.put("num",vo.getCaseNum());
        List<Question> list4 = questionMapper.selectQuestionSimulateList(param4);
        String type4_ids ="";
        if(list4.size()<vo.getCaseNum()){
            throw new CustomException("题库案例题数不足");
        }
        for (Question s : list4) {
            type4_ids += s.getQuestionId()+",";
            listToatl.add(s);
        }
        QuestionSimulateAddBo bo = new QuestionSimulateAddBo();
        bo.setBankId(bankId);
        bo.setType1Ids(type1_ids);
        bo.setType2Ids(type2_ids);
        bo.setType3Ids(type3_ids);
        bo.setType4Ids(type4_ids);
        bo.setUserId(userId);
        bo.setExamConfigId(vo.getId());
        this.insertByAddBo(bo);
        QuestionSimulate add = BeanUtil.toBean(bo, QuestionSimulate.class);
        validEntityBeforeSave(add);
        add.setCreateTime(DateUtils.getNowTime());
        add.setUpdateTime(DateUtils.getNowTime());
        if(!this.save(add)){
            throw new CustomException("模拟试卷创建失败");
        }
        Map<String,Object> result = new HashMap<>();
        result.put("simulateId",add.getSimulateId());
        result.put("list",listToatl);
        result.put("examTime",vo.getExamTime());
        return result;
    }

    @Override
    public List<QuestionSimulateVo> queryList(QuestionSimulateQueryBo bo) {
        LambdaQueryWrapper<QuestionSimulate> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getUserId() != null, QuestionSimulate::getUserId, bo.getUserId());
        lqw.eq(bo.getExamConfigId() != null, QuestionSimulate::getExamConfigId, bo.getExamConfigId());
        lqw.eq(bo.getStatus() != null, QuestionSimulate::getStatus, bo.getStatus());
        lqw.eq(StrUtil.isNotBlank(bo.getType1Ids()), QuestionSimulate::getType1Ids, bo.getType1Ids());
        lqw.eq(StrUtil.isNotBlank(bo.getType2Ids()), QuestionSimulate::getType2Ids, bo.getType2Ids());
        lqw.eq(StrUtil.isNotBlank(bo.getType3Ids()), QuestionSimulate::getType3Ids, bo.getType3Ids());
        lqw.eq(StrUtil.isNotBlank(bo.getType4Ids()), QuestionSimulate::getType4Ids, bo.getType4Ids());
        lqw.eq(bo.getBankId() != null, QuestionSimulate::getBankId, bo.getBankId());
        return entity2Vo(this.list(lqw));
    }

    /**
    * 实体类转化成视图对象
    *
    * @param collection 实体类集合
    * @return
    */
    private List<QuestionSimulateVo> entity2Vo(Collection<QuestionSimulate> collection) {
        List<QuestionSimulateVo> voList = collection.stream()
                .map(any -> BeanUtil.toBean(any, QuestionSimulateVo.class))
                .collect(Collectors.toList());
        if (collection instanceof Page) {
            Page<QuestionSimulate> page = (Page<QuestionSimulate>)collection;
            Page<QuestionSimulateVo> pageVo = new Page<>();
            BeanUtil.copyProperties(page,pageVo);
            pageVo.addAll(voList);
            voList = pageVo;
        }
        return voList;
    }

    @Override
    public Boolean insertByAddBo(QuestionSimulateAddBo bo) {
        QuestionSimulate add = BeanUtil.toBean(bo, QuestionSimulate.class);
        validEntityBeforeSave(add);
        add.setCreateTime(DateUtils.getNowTime());
        add.setUpdateTime(DateUtils.getNowTime());
        return this.save(add);
    }

    @Override
    public Boolean updateByEditBo(QuestionSimulateEditBo bo) {
        QuestionSimulate update = BeanUtil.toBean(bo, QuestionSimulate.class);
        validEntityBeforeSave(update);
        update.setUpdateTime(DateUtils.getNowTime());
        return this.updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(QuestionSimulate entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return this.removeByIds(ids);
    }
}
