package com.hc.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hc.business.dto.ZccmPaperAnswer;
import com.hc.business.dto.ZccmPaperCommitDTO;
import com.hc.business.dto.ZccmPaperResultDto;
import com.hc.business.dto.ZccmQuestionTypeDto;
import com.hc.business.mapper.*;
import com.hc.business.model.*;
import com.hc.business.service.ZccmPaperService;
import com.hc.core.utils.enums.InfoEnum;
import com.hc.core.utils.exception.ResponseException;
import com.hc.core.utils.result.Result;
import com.hc.core.utils.tool.Verification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;

/**
 * 试卷表(ZccmPaper)表服务实现类
 *
 * @author java
 * @since 2020-12-07 11:34:36
 */

@Service("paperService")
public class ZccmPaperServiceImpl implements ZccmPaperService {

    private final ZccmPaperMapper paperMapper;

    private final ZccmQuestionMapper questionMapper;

    private final ZccmPaperQuestionMapper paperQuestionMapper;

    private final ZccmQuestionTypeMapper questionTypeMapper;

    private final ZccmQuestionAnswerMapper questionAnswerMapper;

    private final ZccmUserTestHistoryMapper userTestHistoryMapper;

    private final ZccmUserMapper userMapper;

    public ZccmPaperServiceImpl(ZccmPaperMapper paperMapper,
                                ZccmQuestionMapper questionMapper,
                                ZccmPaperQuestionMapper paperQuestionMapper,
                                ZccmQuestionTypeMapper questionTypeMapper,
                                ZccmQuestionAnswerMapper questionAnswerMapper,
                                ZccmUserTestHistoryMapper userTestHistoryMapper,
                                ZccmUserMapper userMapper) {
        this.paperMapper = paperMapper;
        this.questionMapper = questionMapper;
        this.paperQuestionMapper = paperQuestionMapper;
        this.questionTypeMapper = questionTypeMapper;
        this.questionAnswerMapper = questionAnswerMapper;
        this.userTestHistoryMapper = userTestHistoryMapper;
        this.userMapper = userMapper;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param paperId 主键
     * @return 实例对象
     */
    @Override
    public ZccmPaper queryById(Integer paperId) {
        return this.paperMapper.selectByPrimaryKey(paperId);
    }

    /**
     * 新增数据
     *
     * @param paper 实例对象
     * @return 实例对象
     */
    @Override
    public ZccmPaper insert(ZccmPaper paper) {
        this.paperMapper.insert(paper);
        return paper;
    }

    /**
     * 修改数据
     *
     * @param paper 实例对象
     * @return 实例对象
     */
    @Override
    public ZccmPaper update(ZccmPaper paper) {
        this.paperMapper.updateByPrimaryKeySelective(paper);
        return this.queryById(paper.getPaperId());
    }

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

    /**
     * 分页查询多条数据
     *
     * @param page 页码
     * @param size 查询条数
     * @return 对象列表
     */
    @Override
    public PageInfo queryAllByLimit(int page, int size) {
        return PageHelper.startPage(page, size).doSelectPageInfo(this.paperMapper::selectAll);
    }

    @Override
    public ZccmPaperResultDto queryQuestionList(Integer paperId) {

        List<ZccmQuestionTypeDto> zccmQuestionTypeDtoList = new ArrayList<>();
        ZccmPaperResultDto zccmZccmPaperResultDto = new ZccmPaperResultDto();

        ZccmPaper paper = paperMapper.selectByPrimaryKey(paperId);
        //可加入试卷状态判断
        if (Objects.isNull(paper)) {
            throw new ResponseException(InfoEnum.PAPER_ERROR);
        }

        //查询抽题规则
        List<ZccmPaperQuestion> paperQuestions = paperQuestionMapper.queryByPaperId(paperId);


        for (ZccmPaperQuestion paperQuestion : paperQuestions) {

            ZccmQuestionTypeDto zccmQuestionTypeDto = new ZccmQuestionTypeDto();

            Integer questionType = paperQuestion.getQuestionType();

            Integer questionLevel = paperQuestion.getQuestionLevel();

            Integer questionTagId = paperQuestion.getQuestionTagId();

            ZccmQuestionType questionType1
                    = questionTypeMapper.selectByPrimaryKey(questionType);

            List<Integer> questionList1
                    = questionMapper.queryByTagId(questionType, questionLevel, questionTagId);

            if (Objects.isNull(questionType1)) {
                throw new ResponseException(-1, "数据库无此类型习题,请联系管理员");
            }

            List<Integer> idList = new ArrayList<>();
            if (questionList1.size() == paperQuestion.getQuestionNum() || questionList1.size() < paperQuestion.getQuestionNum()) {
                idList = questionList1;
            } else {
                //循环随机需要的题目  直到达到需要的数目
                for (int i = 0; i < paperQuestion.getQuestionNum(); i++) {
                    Integer randomId;
                    do {
                        //随机一个id
                        randomId = questionList1.get(new Random().nextInt(questionList1.size() - 1));
                    } while (idList.contains(randomId));
                    idList.add(randomId);
                }
            }

            zccmQuestionTypeDto.setQuestionList(idList);
            zccmQuestionTypeDto.setTypeName(questionType1.getTypeName());
            zccmQuestionTypeDtoList.add(zccmQuestionTypeDto);

        }

        zccmZccmPaperResultDto.setPaper(paper);
        zccmZccmPaperResultDto.setZccmQuestionTypeDtoList(zccmQuestionTypeDtoList);
        return zccmZccmPaperResultDto;
    }

    @Override
    public Result paperCommit(ZccmPaperCommitDTO commitDTO) {

//        Integer userId = commitDTO.getUserId();

//        int i = userTestHistoryMapper.queryCountByParam(userId);

//        if (i > 2) {
//            throw new ResponseException(-1,"您已有三次考试记录,当前批次暂无机会继续考试");
//        }

        Integer amountScore = this.calculateScore(commitDTO.getAnswerList());

        ZccmUser user = userMapper.selectByPrimaryKey(commitDTO.getUserId());
        if (user == null) {
            throw new ResponseException(InfoEnum.LOGIN_USER_NAME_ERROR);
        }

        //进行试卷提交后的相关操作  考试记录的信息
        ZccmPaper paper = paperMapper.selectByPrimaryKey(commitDTO.getPaperId());
        if (Objects.isNull(paper)) {
            throw new ResponseException(InfoEnum.PAPER_ERROR);
        }

        ZccmUserTestHistory testHistory = new ZccmUserTestHistory();

        testHistory.setCreateTime(System.currentTimeMillis());
        testHistory.setPaperId(commitDTO.getPaperId());
        testHistory.setClassId(commitDTO.getClassId());
        testHistory.setTestTime(commitDTO.getTestTime());
        testHistory.setUserId(commitDTO.getUserId());
        testHistory.setTotalScore(paper.getPaperScore());
        testHistory.setScore(amountScore);

        String answer = JSON.toJSONString(commitDTO.getAnswerList());
        testHistory.setAnswer(answer);
        userTestHistoryMapper.insert(testHistory);

        return Result.success(testHistory);
    }


    private Integer calculateScore(List<ZccmPaperAnswer> answerList) {

        Integer AMOUNT_SCORE = 0;

        for (ZccmPaperAnswer answer : answerList) {
            //前台传过来的问题id
            Integer questionId = answer.getQuestionId();
            //前台传过来的问题答案
            List<Integer> paperAnswerId = answer.getAnswerId();
            //依据问题id查出正确答案 然后和前端传过来的答案对比
            List<Integer> answerId =
                    questionAnswerMapper.selectAnswerIdListByQuestionId(questionId);
            if (CollectionUtils.isEmpty(answerId)) {
                throw new ResponseException(-1, "此题未配置答案,请联系管理员");
            }
            //获取对应问题的题库的信息
            ZccmQuestion question = questionMapper.selectByPrimaryKey(questionId);
            if (Objects.isNull(question.getQuestionScore())) {
                throw new ResponseException(-1, "数据库习题未配置分数,请联系管理员");
            }

            //判断前端提交答案是否与题库答案相等
            //多选题长度不同，答案肯定不对
          if(true == Verification.equalList(paperAnswerId,answerId)){
              //累计成绩
                AMOUNT_SCORE += question.getQuestionScore();
          }

          //            if (paperAnswerId.equals(answerId)) {
//                //累计成绩
//                AMOUNT_SCORE += question.getQuestionScore();
//            }
        }
        return AMOUNT_SCORE;
    }

}