package com.example.demo.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.dto.request.exam.AddExamRequest;
import com.example.demo.dto.request.exam.BasePageRequest;
import com.example.demo.dto.request.exam.ScoreRequest;
import com.example.demo.dto.request.exam.StemAndExamRequest;
import com.example.demo.dto.response.*;
import com.example.demo.dto.response.admin.BaseAdminResponse;
import com.example.demo.dto.response.admin.BasePageResponse;
import com.example.demo.dto.response.admin.ExamWithoutStemsDto;
import com.example.demo.dto.response.feign.FeignResponse;
import com.example.demo.entity.Paper;
import com.example.demo.entity.PaperItem;
import com.example.demo.mapper.PaperItemMapper;
import com.example.demo.mapper.PaperMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;



/**
 * @Author hxh
 * @Date 2020-09-16 2:26
 * @Descrption TODO
 */
@Service
public class ExamService {
    @Autowired
    private PaperMapper paperMapper;
    @Autowired
    private PaperItemMapper paperItemMapper;
    @Autowired
    private FeignService feignService;

    public List<ExamDto> getExamListByGradeAndSubject(StemAndExamRequest request){
        //条件查询，根据request获得数据库中相应试卷
        QueryWrapper<Paper> wrapper = new QueryWrapper<>();
        wrapper.eq(request.getGroupName()!=null,"groupName",request.getGroupName())
                .eq(request.getGradeName()!=null,"gradeName",request.getGradeName())
                .eq(request.getSubject()!=null,"subject",request.getSubject());

        /* 两种写法 TODO 调试
        Paper paper = new Paper();
        paper.setGroupName(request.getGroupName());
        paper.setGradeName(request.getGradeName());
        paper.setSubject(request.getSubject());
        wrapper.setEntity(paper);*/
        List<Paper> papers = paperMapper.selectList(wrapper);

        List<ExamDto> exams = new LinkedList<>();
        for(Paper p : papers){

            //得到一个具体试卷，继续循环
            ExamDto exam = getExamById(p.getId());

            exams.add(exam);
        }
        return exams;
    }

    public ExamDto getExamById(int id){
        Paper paper = paperMapper.selectById(id);

        ExamDto exam = new ExamDto(paper);

        //根据paperId获得试卷中题目（一个paperItem对应一道题目id）
        QueryWrapper<PaperItem> wrapper = new QueryWrapper<>();
        wrapper.eq("pid",id);
        List<PaperItem> paperItems = paperItemMapper.selectList(wrapper);

        for(PaperItem item : paperItems){
            System.out.println(item);
        }
        List<StemDto> stems = getExamStems(paperItems);

        //将stems存储到对应exam中
        exam.setStems(stems);
        return exam;
    }

    public List<StemDto> getExamStems(List<PaperItem> paperItems){
        //用feign获取题目信息（根据题目id到老师接口调用）
        List<StemDto> stems = new LinkedList<>();
        for(PaperItem item : paperItems){
            FeignResponse response = feignService.getResponse(item.getSid());
            if(response.getCode().compareTo("200")==0){
                StemDto stem =  response.getData();
                stem.setAns();
                stems.add(stem);
            }
        }
        return stems;
    }

    public ScoreDto getScore(ScoreRequest request){
        int paperId = request.getId();
        ExamDto exam = getExamById(paperId);        //试卷
        List<StemDto> stems = exam.getStems();      //试卷中的题目
        List<List<String>> rightAnswers = new LinkedList<>();    //正确答案集
        double rightNum = 0;                               //正确数
        double totalNum = exam.getStems().size();          //总数
        for(int i=0; i<totalNum; i++){
            rightAnswers.add(stems.get(i).getAnswer());     //添加正确答案到rightAnswers

            if(request.getAnswers().get(i).size() == stems.get(i).getAnswer().size()){  //答案数相同再判断是否得分
                boolean flag = true;
                for(int j=0; j<request.getAnswers().get(i).size(); j++){
                    String left = request.getAnswers().get(i).get(j); //提交的答案内容
                    String  right = stems.get(i).getAnswer().get(j);  //正确答案内容
                    if(left.compareTo(right)!=0){
                        flag = false;
                        break;
                    }
                }
                if(flag) {rightNum++;}
            }
        }
        double score = (rightNum/totalNum)*100;
        ScoreDto scoreDto = new ScoreDto(String.format("%.1f",score),rightAnswers);
        return scoreDto;
    }

    /*
     *
     *
     */
    @Transactional
    public BaseResponse addExam(AddExamRequest request){
        //调用老师接口，取得List<StemDto>并将题号保存到stemIds
        List<String> stemIds = new LinkedList<>();
        for(StemDto stem : feignService.getStems(request).getData().getData()){
            stemIds.add(stem.getId());
        }
        //根据request需要的题目数目，随机选择题目String，并保存到selectIds
        //如果取得的stemIds.size小于request的题目数量，直接返回stemIds
        //否则随机将题目id保存到selectedIds
        List<String> selectedIds = new LinkedList<>();
        if(stemIds.size()<=request.getNumber()){
            selectedIds = stemIds;
        }else {
            boolean[] selected = new boolean[stemIds.size()];
            int i=0;
            Random random = new Random();
            while(i<request.getNumber()){
                int j = random.nextInt(stemIds.size());
                if(!selected[j]){
                    selected[j] = true;
                    selectedIds.add(stemIds.get(j));
                    i++;
                }
            }
        }
        //向数据库插入exam和相应exam_item
        try {
            Paper insertPaper = new Paper(null,request.getName(),request.getGroupName(),request.getGradeName(),request.getSubject(),1);
            paperMapper.insert(insertPaper);
            for(String str : selectedIds){
                paperItemMapper.insert(new PaperItem(null,insertPaper.getId(),str));
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return new BaseResponse(200,"添加成功",null);
    }


    //后台List所有试卷
    public BaseAdminResponse list(BasePageRequest request){
        Page<Paper> page = new Page<>(request.getStart(),request.getLimit());
        QueryWrapper<Paper> wrapper = new QueryWrapper<>();
        if(request.getData() instanceof StemAndExamRequest){
            wrapper.eq(((StemAndExamRequest) request.getData()).getGroupName()!=null,"groupName",((StemAndExamRequest) request.getData()).getGroupName())
                    .eq(((StemAndExamRequest) request.getData()).getGradeName()!=null,"gradeName",((StemAndExamRequest) request.getData()).getGradeName())
                    .eq(((StemAndExamRequest) request.getData()).getSubject()!=null,"subject",((StemAndExamRequest) request.getData()).getSubject());
        }
        IPage<Paper> paperPage = paperMapper.selectPage(page,wrapper);
        List<Paper> papers = paperPage.getRecords();
        List<ExamWithoutStemsDto> exams = new LinkedList<>();
        for(Paper p: papers ){
            ExamWithoutStemsDto exam = new ExamWithoutStemsDto(p);
            exams.add(exam);
        }
        BasePageResponse<List<ExamWithoutStemsDto>> examPage = new BasePageResponse<>(paperPage.getTotal(),
                paperPage.getPages(),
                paperPage.getSize(),
                paperPage.getCurrent(),
                exams.size(),
                exams);

        return new BaseAdminResponse(200,"",examPage);
    }
}
