package com.tykj.dev.device.train.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.tykj.dev.device.questionbank.entity.Problem;
import com.tykj.dev.device.questionbank.service.ProblemService;
import com.tykj.dev.device.train.dao.TestPaperDao;
import com.tykj.dev.device.train.entity.GenerateTestPaper;
import com.tykj.dev.device.train.entity.TestPaper;
import com.tykj.dev.device.train.entity.vo.ProblemVo;
import com.tykj.dev.device.train.entity.vo.TestPaperListVo;
import com.tykj.dev.device.train.entity.vo.TestPaperManagementListVo;
import com.tykj.dev.device.train.service.TestPaperService;
import com.tykj.dev.device.train.service.TrainThemeService;
import com.tykj.dev.misc.base.BeanHelper;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.JacksonUtil;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * @author zjm
 * @version 1.0.0
 * @ClassName TestPaperServiceImpl.java
 * @Description TODO
 * @createTime 2021年05月30日 16:33:00
 */
@Service
public class TestPaperServiceImpl implements TestPaperService {
    @Autowired
    TestPaperDao testPaperDao;

    @Autowired
    TestPaperService testPaperService;

    @Autowired
    ProblemService problemService;

    @Autowired
    TrainThemeService trainThemeService;

    @Override
    public TestPaper saveProble(TestPaper testPaper) {
        return testPaperDao.save(testPaper);
    }

    @Override
    public TestPaper findByIdProble(Integer id) {
        Optional<TestPaper> optional = testPaperDao.findById(id);
        if (optional.isPresent()){
            TestPaper testPaper= optional.get();
            testPaper.setJudgeProblemList(JacksonUtil.readValue(testPaper.getJudgeProblem(), new TypeReference<List<ProblemVo>>() {
            }));
            testPaper.setChooseProblemList(JacksonUtil.readValue(testPaper.getChooseProblem(), new TypeReference<List<ProblemVo>>() {
            }));
            testPaper.setMultipleChoiceProblemList(JacksonUtil.readValue(testPaper.getMultipleChoiceProblem(), new TypeReference<List<ProblemVo>>() {
            }));
            testPaper.setShortAnswerProblemList(JacksonUtil.readValue(testPaper.getShortAnswerProblem(), new TypeReference<List<ProblemVo>>() {
            }));
            return testPaper;
        }else {
            throw new ApiException(ResponseEntity.status(500).body("[试卷] 没有找到对应的试卷"));
        }
    }

    @Override
    public TestPaper findByUserIdAndTrainId(Integer userId, Integer trainId) {
       TestPaper testPaper= testPaperDao.findByTrainIdAndUserId(trainId,userId);
        testPaper.setJudgeProblemList(JacksonUtil.readValue(testPaper.getJudgeProblem(), new TypeReference<List<ProblemVo>>() {
        }));
        testPaper.setChooseProblemList(JacksonUtil.readValue(testPaper.getChooseProblem(), new TypeReference<List<ProblemVo>>() {
        }));
        testPaper.setMultipleChoiceProblemList(JacksonUtil.readValue(testPaper.getMultipleChoiceProblem(), new TypeReference<List<ProblemVo>>() {
        }));
        testPaper.setShortAnswerProblemList(JacksonUtil.readValue(testPaper.getShortAnswerProblem(), new TypeReference<List<ProblemVo>>() {
        }));
        return testPaper;
    }

    @Override
    public List<TestPaper> findByTrainIdAndStatus(Integer trainId, Integer status) {
        return testPaperDao.findAllByTrainIdAndStatus(trainId,status);
    }


    @Override
    public List<TestPaper> findAll() {
        return testPaperDao.findAll();
    }

    @Override
    public void deleteById(Integer id) {
            testPaperDao.deleteById(id);
    }

    @Override
    public TestPaper generateTestPaper(GenerateTestPaper generateTestPaper) {
        TestPaper testPaper=new TestPaper();
//        testPaper.setChooseProblemList(problemService.findByTypeAndLevel(1,1));
//        testPaper.setJudgeProblemList(problemService.findByTypeAndLevel(2,1));
//        testPaper.setMultipleChoiceProblemList(problemService.findByTypeAndLevel(4,1));
//        testPaper.setShortAnswerProblemList(problemService.findByTypeAndLevel(3,1));
//        generateTestPaper.
        List<ProblemVo> chooseList=new ArrayList<>();
        List<ProblemVo> judgeProblemList=new ArrayList<>();
        List<ProblemVo> multipleChoiceProblemList=new ArrayList<>();
        List<ProblemVo> shortAnswerProblemList=new ArrayList<>();
        generateTestPaper.getChooseCount().forEach(
                (k,v)->{
                    if (v!=0) {
                        chooseList.addAll(getSubStringByRadom(problemService.findByTypeAndLevel(1, k), v));
                    }
                }
        );

        generateTestPaper.getJudgeCount().forEach(
                (k,v)->{
                    if (v!=0) {
                        judgeProblemList.addAll(getSubStringByRadom(problemService.findByTypeAndLevel(2, k), v));
                    }
                }
        );

        generateTestPaper.getMultipleChoiceCount().forEach(
                (k,v)->{
                    if (v!=0) {
                        multipleChoiceProblemList.addAll(getSubStringByRadom(problemService.findByTypeAndLevel(4, k), v));
                    }
                }
        );

        generateTestPaper.getShortAnswerCount().forEach(
                (k,v)->{
                    if (v!=0) {
                        shortAnswerProblemList.addAll(getSubStringByRadom(problemService.findByTypeAndLevel(3, k), v));
                    }
                }
        );

        testPaper.setChooseProblemList(chooseList);
        testPaper.setShortAnswerProblemList(shortAnswerProblemList);
        testPaper.setMultipleChoiceProblemList(multipleChoiceProblemList);
        testPaper.setJudgeProblemList(judgeProblemList);
        testPaper.setChooseProblem(JacksonUtil.toJSon(testPaper.getChooseProblemList()));
        testPaper.setJudgeProblem(JacksonUtil.toJSon(testPaper.getJudgeProblemList()));
        testPaper.setMultipleChoiceProblem(JacksonUtil.toJSon(testPaper.getMultipleChoiceProblemList()));
        testPaper.setShortAnswerProblem(JacksonUtil.toJSon(testPaper.getShortAnswerProblemList()));
        return testPaper;
    }

    @Override
    public List<TestPaperManagementListVo> TEST_PAPER_MANAGEMENT_LIST_VOS(Integer unitId,Integer status) {
        Integer trainStatus;
        Integer testPaperStatus;
        if (status==0){
            trainStatus=1;
            testPaperStatus=0;
        }else {
            trainStatus=2;
            testPaperStatus=1;
        }
        List<TestPaperManagementListVo> testPaperManagementListVos=new ArrayList<>();
        trainThemeService.findByUnitIdAndisNotExamines(trainStatus,unitId).forEach(
                trainTheme -> {
                    TestPaperManagementListVo testPaperManagementListVo=new TestPaperManagementListVo();
                    testPaperManagementListVo.setTrainId(trainTheme.getTrainId());
                    testPaperManagementListVo.setName(trainTheme.getName());
                    testPaperManagementListVo.setCount(this.findByTrainIdAndStatus(trainTheme.getTrainId(),testPaperStatus).size());
                    testPaperManagementListVos.add(testPaperManagementListVo);
                }
        );
        return testPaperManagementListVos;
    }

    @Override
    public List<TestPaperListVo> findAllByTrainId(Integer trainId) {
        return testPaperDao.findAllByTrainId(trainId).stream().map(TestPaper::toTestPaperListVo).collect(Collectors.toList());
    }

    public List<ProblemVo> getSubStringByRadom(List<Problem> list, int count){
        List backList = null;
        backList = new ArrayList<ProblemVo>();
        Random random = new Random();
        int backSum = 0;
        if (list.size() >= count) {
            backSum = count;
        }else {
            backSum = list.size();
        }
        for (int i = 0; i < backSum; i++) {
//			随机数的范围为0-list.size()-1
            int target = random.nextInt(list.size());
            backList.add(toVo(list.get(target)));
            list.remove(target);
        }
        return backList;
    }

    private ProblemVo toVo(Problem problem){

        ModelMapper mapper = BeanHelper.getUserMapper();

       ProblemVo problemVo=  mapper.map(problem,ProblemVo.class);
       if (problem.getChooseOptions()!=null) {
           problemVo.setChooseOptionsList(JacksonUtil.readValue(problem.getChooseOptions(), new TypeReference<List<String>>() {
           }));
       }
       return problemVo;
    }
}
