package com.artfess.examine.manager.impl;

import com.alibaba.fastjson.JSONObject;
import com.artfess.base.enums.DelStatusEnum;
import com.artfess.base.enums.QuestionTypeEnum;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.query.PageBean;
import com.artfess.base.query.PageList;
import com.artfess.base.query.QueryFilter;
import com.artfess.base.util.StringUtil;
import com.artfess.examine.dao.ExamQuestionsInfoDao;
import com.artfess.examine.dao.ExamQuestionsOptionDao;
import com.artfess.examine.dao.ExamSubjectInfoDao;
import com.artfess.examine.manager.ExamQuestionsInfoManager;
import com.artfess.examine.manager.ExamQuestionsOptionManager;
import com.artfess.examine.model.ExamQuestionsInfo;
import com.artfess.examine.model.ExamQuestionsOption;
import com.artfess.examine.model.ExamSubjectInfo;
import com.artfess.examine.vo.QuestionAnalysisVo;
import com.artfess.examine.vo.StatisticalReqVo;
import com.artfess.examine.vo.SubjectQuestionTypeVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 题库试题信息 服务实现类
 *
 * @author min.wu
 * @company 阿特菲斯信息技术有限公司
 * @since 2022-10-19
 */
@Service
public class ExamQuestionsInfoManagerImpl extends BaseManagerImpl<ExamQuestionsInfoDao, ExamQuestionsInfo> implements ExamQuestionsInfoManager {


    @Resource
    private ExamQuestionsOptionDao questionsOptionDao;

    @Resource
    private ExamSubjectInfoDao subjectInfoDao;

    @Autowired
    private ExamQuestionsOptionManager questionsOptionService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createInfo(ExamQuestionsInfo t) {

        QueryWrapper<ExamQuestionsInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sub_id_", t.getSubId());
        queryWrapper.eq("question_", t.getQuestion());
        List<ExamQuestionsInfo> questionsInfos = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(questionsInfos)) {
            throw new RuntimeException("该课目下题目已重复！");
        }

        if (!QuestionTypeEnum.shortAnswer.getType().equals(t.getType())
                && !QuestionTypeEnum.operation.getType().equals(t.getType())
                && !QuestionTypeEnum.lst.getType().equals(t.getType())) {
            Assert.hasText(t.getRightOption(), "请填写正确答案");
        }

        int insert = this.baseMapper.insert(t);
        if (insert > 0) {
            processOptions(t.getOptions(), t.getId());
            return t.getId();
        }

        return null;
    }

    private void processOptions(List<ExamQuestionsOption> options, String id) {

        QueryWrapper<ExamQuestionsOption> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("question_id_", id);
        questionsOptionDao.delete(queryWrapper);
        if (CollectionUtils.isEmpty(options)) {
            return;
        }
        options.forEach(option -> {
            Assert.hasText(option.getOptionKey(), "选项编号不能为空");
            Assert.hasText(option.getOptionContent(), "选项内容不能为空");
            option.setQuestionId(id);
            this.questionsOptionDao.insert(option);
        });

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateInfo(ExamQuestionsInfo t) {
        QueryWrapper<ExamQuestionsInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sub_id_", t.getSubId());
        queryWrapper.eq("question_", t.getQuestion());
        queryWrapper.ne("id_", t.getId());
        List<ExamQuestionsInfo> questionsInfos = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(questionsInfos)) {
            throw new RuntimeException("该课目下题目已重复！");
        }

        if (!QuestionTypeEnum.shortAnswer.getType().equals(t.getType())
                && !QuestionTypeEnum.operation.getType().equals(t.getType())
                && !QuestionTypeEnum.lst.getType().equals(t.getType())) {
            Assert.hasText(t.getRightOption(), "请填写正确答案");
        }

        int count = this.baseMapper.updateById(t);
        if (count > 0) {
            processOptions(t.getOptions(), t.getId());
            return t.getId();
        }
        return null;
    }

    @Override
    public ExamQuestionsInfo findById(String id) {
        Assert.hasText(id, "请选择要查看的试题");
        ExamQuestionsInfo examQuestionsInfo = this.baseMapper.selectById(id);
        Assert.notNull(examQuestionsInfo, "题目信息不存在");
        String subId = examQuestionsInfo.getSubId();
        ExamSubjectInfo examSubjectInfo = subjectInfoDao.selectById(subId);
        if(null != examSubjectInfo) {
            examQuestionsInfo.setSubjectName(examSubjectInfo.getName());
        }
        QueryWrapper<ExamQuestionsOption> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("question_id_", id);
        List<ExamQuestionsOption> examQuestionsOptions = questionsOptionDao.selectList(queryWrapper);
        examQuestionsInfo.setOptions(examQuestionsOptions);

        return examQuestionsInfo;
    }

    @Override
    public List<ExamQuestionsInfo> randomQuestion(String subjectId, String questionType, Integer numuber) {

        return this.baseMapper.randomQuestion(subjectId, questionType, numuber);
    }

    @Override
    public List<SubjectQuestionTypeVo> findBySubjectId(String subjectId) {
        List<SubjectQuestionTypeVo> list = this.baseMapper.findBySubjectId(subjectId);
        return list;
    }

    @Override
    public PageList<ExamQuestionsInfo> findByPage(QueryFilter<ExamQuestionsInfo> queryFilter) {
        PageBean pageBean = queryFilter.getPageBean();
        IPage<ExamQuestionsInfo> result = baseMapper.findByPage(convert2IPage(pageBean), convert2Wrapper(queryFilter, currentModelClass()));
        return new PageList<ExamQuestionsInfo>(result);
    }

    @Override
    public QuestionAnalysisVo questionAnalysis(StatisticalReqVo reqVo) {
        QuestionAnalysisVo questionAnalysisVo = new QuestionAnalysisVo();
        QueryWrapper<ExamQuestionsInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_dele_", DelStatusEnum.N.getType());
        if(!StringUtils.isEmpty(reqVo.getSubjectId())){
            queryWrapper.eq("sub_id_", reqVo.getSubjectId());
        }
        queryWrapper.isNotNull("type_");
        List<ExamQuestionsInfo> questionsInfos = this.baseMapper.selectList(queryWrapper);
        questionsInfos.forEach(question -> {
            question.setDifficulty("1");
        });
        Map<String, List<ExamQuestionsInfo>> map = questionsInfos.stream().collect(Collectors.groupingBy(ExamQuestionsInfo::getType));
        List<SubjectQuestionTypeVo> list = Lists.newArrayList();
        map.forEach((key, value) ->{
            SubjectQuestionTypeVo subjectQuestionTypeVo = new SubjectQuestionTypeVo();
            subjectQuestionTypeVo.setType(key);
            subjectQuestionTypeVo.setCount(value.size());
            Map<String, List<ExamQuestionsInfo>> dMap = value.stream().collect(Collectors.groupingBy(ExamQuestionsInfo::getDifficulty));
            dMap.forEach((dkey, dvalue) ->{
                if(StringUtils.isEmpty(dkey)) {
                    return;
                }
                Integer size = 0;
                if(!CollectionUtils.isEmpty(dvalue)) {
                    size = dvalue.size();
                }
                if("1".equals(dkey)) {
                    subjectQuestionTypeVo.setSimple(size);
                }
                if("2".equals(dkey)) {
                    subjectQuestionTypeVo.setOrdinary(size);
                }
                if("3".equals(dkey)) {
                    subjectQuestionTypeVo.setDifficult(size);
                }

            });
            list.add(subjectQuestionTypeVo);
        });

        questionAnalysisVo.setQuestionTypeVos(list);

        Map<String, List<ExamQuestionsInfo>> dMap = questionsInfos.stream().collect(Collectors.groupingBy(ExamQuestionsInfo::getDifficulty));
        JSONObject jsObject = new JSONObject();
        dMap.forEach((dkey, dvalue) ->{
            if(StringUtils.isEmpty(dkey)) {
                return;
            }
            Integer size = 0;
            if(!CollectionUtils.isEmpty(dvalue)) {
                size = dvalue.size();
            }
            jsObject.put(dkey, size);

        });
        questionAnalysisVo.setDifficultPercentage(jsObject);
        return questionAnalysisVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean importExcel(ExamQuestionsInfo question) {
        QueryWrapper<ExamQuestionsInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sub_id_", question.getSubId());
        queryWrapper.eq("question_", question.getQuestion());
        List<ExamQuestionsInfo> questionsInfos = this.baseMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(questionsInfos)) {
//            question.setQuestion(question.getQuestion() +"..");
//            throw new RuntimeException("该课目下题目已重复！");

        }
        if(StringUtil.isEmpty(question.getRightOption())) {
            throw new RuntimeException(question.getQuestion() + "请填写正确答案！");
        }
        question.setType(QuestionTypeEnum.getType(question.getType()));

        if(QuestionTypeEnum.radio.getType().equals(question.getType()) && question.getRightOption().length() > 1){
            question.setType(QuestionTypeEnum.multi.getType());
            question.setRightOption(org.apache.commons.lang3.StringUtils.join(question.getRightOption().split(""), ","));
        }else  if(QuestionTypeEnum.fillIn.getType().equals(question.getType()) || QuestionTypeEnum.lst.getType().equals(question.getType()) || QuestionTypeEnum.judge.getType().equals(question.getType())){
            Assert.hasText(question.getRightOption(), "请填写正确答案");
            question.setRightOption(question.getRightOption());
        }else  if(QuestionTypeEnum.judge.getType().equals(question.getType())){
            Assert.hasText(question.getRightOption(), "请填写正确答案");
            if("对".equals(question.getRightOption())) {
                question.setRightOption("1");
            }else if("错".equals(question.getRightOption())) {
                question.setRightOption("0");
            }
        }
        else if(QuestionTypeEnum.multi.getType().equals(question.getType())){
            question.setRightOption(org.apache.commons.lang3.StringUtils.join(question.getRightOption().split(""), ","));
        }

        question.setDifficulty("1");
        question.setScore(new BigDecimal(5));
        int insert = this.baseMapper.insert(question);
        if (insert > 0) {
            if(QuestionTypeEnum.radio.getType().equals(question.getType()) || QuestionTypeEnum.multi.getType().equals(question.getType())){
                List<ExamQuestionsOption> optionList = Lists.newArrayList();
                ExamQuestionsOption option = new ExamQuestionsOption();
                option.setOptionKey("A");
                option.setQuestionId(question.getId());
                String optionContent = question.getOptionOne();
                if(!StringUtils.isEmpty(optionContent) && optionContent.length() > 2) {
                    optionContent = question.getOptionOne().substring(2);
                }
                option.setOptionContent(optionContent);
                optionList.add(option);
                option = new ExamQuestionsOption();
                option.setOptionKey("B");
                option.setQuestionId(question.getId());
                optionContent = question.getOptionTwo();
                if(!StringUtils.isEmpty(optionContent) && optionContent.length() > 2) {
                    optionContent = question.getOptionTwo().substring(2);
                    option.setOptionContent(optionContent);
                    optionList.add(option);
                }

                option = new ExamQuestionsOption();
                option.setOptionKey("C");
                option.setQuestionId(question.getId());
                optionContent = question.getOptionThree();
                if(!StringUtils.isEmpty(optionContent) && optionContent.length() > 2) {
                    optionContent = question.getOptionThree().substring(2);
                    option.setOptionContent(optionContent);
                    optionList.add(option);
                }

                option = new ExamQuestionsOption();
                option.setOptionKey("D");
                option.setQuestionId(question.getId());
                optionContent = question.getOptionFour();
                if(!StringUtils.isEmpty(optionContent) && optionContent.length() > 2) {
                    optionContent = question.getOptionFour().substring(2);
                    option.setOptionContent(optionContent);
                    optionList.add(option);
                }


                option = new ExamQuestionsOption();
                option.setOptionKey("E");
                option.setQuestionId(question.getId());
                optionContent = question.getOptionFive();
                if(!StringUtils.isEmpty(optionContent) && optionContent.length() > 2) {
                    optionContent = question.getOptionFive().substring(2);
                    option.setOptionContent(optionContent);
                    optionList.add(option);
                }


                option = new ExamQuestionsOption();
                option.setOptionKey("F");
                option.setQuestionId(question.getId());
                optionContent = question.getOptionSix();
                if(!StringUtils.isEmpty(optionContent) && optionContent.length() > 2) {
                    optionContent = question.getOptionSix().substring(2);
                    option.setOptionContent(optionContent);
                    optionList.add(option);
                }

                questionsOptionService.saveBatch(optionList);
            }
            return true;
        }

        return false;
    }

    @Override
    public List<ExamQuestionsInfo> getQuestionList(List<String> idList) {
        QueryWrapper<ExamQuestionsInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("sub_id_", idList);
        queryWrapper.eq("is_dele_", DelStatusEnum.N.getType());
        return this.baseMapper.selectList(queryWrapper);
    }


}
