package com.xhkjedu.sstudy.service.question;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.sstudy.config.ConfigKey;
import com.xhkjedu.sstudy.listener.MessageSender;
import com.xhkjedu.sstudy.mapper.paper.PaperMapper;
import com.xhkjedu.sstudy.mapper.paperstudent.PaperClassMapper;
import com.xhkjedu.sstudy.mapper.question.QuestionClassMapper;
import com.xhkjedu.sstudy.mapper.question.QuestionExplainMapper;
import com.xhkjedu.sstudy.mapper.question.QuestionMapper;
import com.xhkjedu.sstudy.mapper.subjectbook.SubjectMapper;
import com.xhkjedu.sstudy.model.question.TQuestionClass;
import com.xhkjedu.sstudy.model.question.TQuestionExplain;
import com.xhkjedu.sstudy.utils.ArithUtil;
import com.xhkjedu.sstudy.utils.StudyUtil;
import com.xhkjedu.sstudy.vo.paperstudent.PaperStudentQuestionVo;
import com.xhkjedu.sstudy.vo.question.AnswerStu;
import com.xhkjedu.sstudy.vo.question.QuestionClassDetailVo;
import com.xhkjedu.sstudy.vo.question.QuestionClassVo;
import com.xhkjedu.sstudy.vo.subjectbook.SubjectQuestiontypeVo;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.vo.ResultVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ywx
 * @classname QuestionService
 * @description 
 * @date 2020/6/6 17:09
 **/
@Service
public class QuestionClassService {
    @Resource
    private QuestionClassMapper questionClassMapper;
    @Resource
    private QuestionExplainMapper questionExplainMapper;
    @Resource
    private PaperClassMapper paperClassMapper;
    @Resource
    private QuestionStudentService questionStudentService;
    @Resource
    private PaperMapper paperMapper;
    @Autowired
    private MessageSender messageSender;
    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private SubjectMapper subjectMapper;

    /**
     * 提交作业：全部批阅的作业调用批阅完成方法
     * @Param [pg]
     * @Author ywx
     * @Date 2020/10/14 11:10
     * @return void
     **/
    /*public void submitPaper(TPaperGroup pg){
        Integer wpynum = paperGroupMapper.getWpyNum(pg);//作业班级下未批阅学生作业数量
        if (wpynum == 0){//作业班级下学生的作业全部批改完调用批阅完成方法
            TQuestionClass question = new TQuestionClass();
            question.setPaperid(Long.valueOf(pg.getPaperid()));
            question.setClassid(pg.getClassid());
            TPaper paper = paperMapper.selectByPrimaryKey(pg.getPaperid());
            question.setQctype(paper.getPapertype());
            endCorrect(question);
        }
    }

    //批阅完成
    public void endCorrect(TQuestionClass question) {
        Long paperid = question.getPaperid();
        Integer classid = question.getClassid();
        Integer qctype = question.getQctype();
        Integer checked = paperGroupMapper.getPaperClassChecked(paperid, classid);//获取班级作业是否结束批阅
        if (checked == 1) return;//已结束批阅不处理
        TPaper paper = paperMapper.selectByPrimaryKey(paperid);
        String subjectid = paper.getSubjectid();
        Integer hashear;
        if (N_Utils.isEmpty(paper.getHearfile())) {
            hashear = 0;
        } else {
            hashear = 1;
        }
        //已批阅未得满分的试题
        List<TQuestionStudent> questions = questionStudentService.listQuestions(paperid, classid, qctype);
        for (TQuestionStudent q : questions) {
            q.setQctype(qctype);
            q.setSubjectid(subjectid);
            q.setPaperid(paperid);
            if (qctype == 2) q.setHashear(hashear);
            questionStudentService.updateQuestionStudent(q);
        }

        List<TQuestionClass> questionClasses;
        if (qctype == 1 || qctype == 3) {//题库/靶向作业
            questionClasses = questionClassMapper.getQuestionAnalyze(paperid, classid, qctype);
        } else {//附件作业
            questionClasses = questionClassMapper.getSQuestionAnalyze(paperid, classid);
        }
        //学校错误率%
        Integer serrorrate = questionClassMapper.getErrorRateBySchoolId(questionClasses.get(0).getSchoolid());
        List<TQuestionClass> list = new ArrayList<>();//班级错题集合
        for (TQuestionClass q : questionClasses) {
            Integer stunum = q.getStunum();
            Double stuscore = q.getStuscore();
            q.setPaperid(paperid);
            q.setClassid(classid);
            q.setQctype(qctype);
            Double qscore = N_Utils.formatDouble(stuscore / stunum, 2);
            q.setAvgscore(qscore);
            Double totalscore = q.getQscore()*stunum;
            Double errorrate = N_Utils.getDoubleDivideAndMulitiply((totalscore-stuscore),totalscore);
            q.setErrorrate(errorrate);
            q.setCreatetime(N_Utils.getSecondTimestamp());
            if (qctype == 2) q.setHashear(hashear);
            if (errorrate > serrorrate){
                list.add(q);
            }
        }

        if (N_Utils.isListNotEmpty(list)){
            questionClassMapper.insertList(list);
        }
        paperGroupMapper.updateChecked(paperid.intValue(), classid);
    }*/

    //章节班级错题列表
    public List <QuestionClassVo> directorList(TQuestionClass question) {
        setSearchTime(question);
        List<QuestionClassVo> all = questionClassMapper.directorList(question);
        List<QuestionClassVo> questions = new ArrayList<>();//题库错题
        List<QuestionClassVo> scantrons = new ArrayList<>();//附件错题
        List<TQuestionExplain> explainAll = new ArrayList<>();//全部错题讲解
        listQuestionDetail(all, questions, scantrons, explainAll);//获取错题详情

        for (QuestionClassVo q : all) {
            Integer qctype = q.getQctype();
            if (qctype == 1 || qctype == 3) {
                QuestionClassVo vo = questions.stream().filter(tq -> tq.getQuestionid().equals(q.getQuestionid())).findFirst().orElse(null);
                q.setCtype(vo.getCtype());
                q.setQstem(vo.getQstem());
                q.setQoption(vo.getQoption());
                q.setQtypename(vo.getQtypename());
                q.setCount(vo.getCount());
                q.setHashear(vo.getHashear());
                q.setHearfile(vo.getHearfile());
            } else if (qctype == 2) {
                QuestionClassVo vo = scantrons.stream().filter(tq -> tq.getQuestionid().equals(q.getQuestionid())).findFirst().orElse(null);
                q.setCtype(vo.getCtype());
                q.setQtypename(vo.getQtypename());
            }
            List<TQuestionExplain> explains = explainAll.stream().filter(e -> e.getQctype() == qctype && e.getQuestionid().equals(q.getQuestionid())).collect(Collectors.toList());
            q.setExplains(explains);
            for (TQuestionExplain explain : explains) {
                convertVideo(explain);//视频转换mq
            }
        }
        return all;
    }

    //获取错题详情
    private void listQuestionDetail(List<QuestionClassVo> all, List<QuestionClassVo> questions, List<QuestionClassVo> scantrons, List<TQuestionExplain> explainAll) {
        List<String> questionids = all.stream().filter(q -> q.getQctype() == 1 || q.getQctype() == 3)
                .map(QuestionClassVo::getQuestionid).collect(Collectors.toList());
        List<String> sids = all.stream().filter(q -> q.getQctype() == 2).map(QuestionClassVo::getQuestionid).collect(Collectors.toList());
        if (N_Utils.isListNotEmpty(questionids)) questions.addAll(questionClassMapper.getQuestionById(questionids));
        if (N_Utils.isListNotEmpty(sids)) scantrons.addAll(questionClassMapper.getScantronById(sids));
        if (N_Utils.isListNotEmpty(all)) {
            List<TQuestionExplain> explains = questionExplainMapper.listByQuestionIds(all);
            if (N_Utils.isListNotEmpty(explains)) explainAll.addAll(explains);
        }
    }

    //知识点班级错题列表
    public List<QuestionClassVo> pointList(TQuestionClass question) {
        setSearchTime(question);
        List<QuestionClassVo> all = questionClassMapper.pointList(question);
        for (QuestionClassVo q : all) {
            List<TQuestionExplain> explains = questionExplainMapper.listByQuestionId(q.getQuestionid(), q.getQctype());
            q.setExplains(explains);
            for (TQuestionExplain explain : explains) {
                convertVideo(explain);//视频转换mq
            }
        }
        return all;
    }

    //设置搜素时间段（默认时间段为最近一个月）
    private void setSearchTime(TQuestionClass question) {
        if (N_Utils.isEmptyInteger(question.getStarttime())) {//开始时间为空设置为过去一个月的日期
            question.setStarttime(N_Utils.getLongGoTime(2).intValue());
        }
        if (N_Utils.isEmptyInteger(question.getStoptime())) {//结束时间为空设置为当前日期
            question.setStoptime(N_Utils.getNowtimestamp().intValue());
        }
    }

    //获取详情
    public QuestionClassVo findById(String questionid) {
        return questionClassMapper.findById(questionid);
    }

    //添加讲解
    public void addExplain(TQuestionExplain explain) {
        explain.setCreatetime(N_Utils.getSecondTimestamp());
        explain.setReadcount(0);
        int schoolyear = questionClassMapper.getYearBySchoolTeacherid(explain.getCreateid());
        explain.setYear(schoolyear);
        questionExplainMapper.insertUseGeneratedKeys(explain);
        explain.setQcpid(explain.getId());
        convertVideo(explain);//视频转换mq
    }

    //视频转换mq
    private void convertVideo(TQuestionExplain research) {
        if (StudyUtil.videoList.contains(research.getSuffix()) && (N_Utils.isEmpty(research.getMp4code()) || !"h264".equals(research.getMp4code()))) {
            messageSender.convertVideo(research.getQcpid(), research.getFilepath(), "explain");
        }
    }

    //题型列表
    public List<SubjectQuestiontypeVo> listQtype(TQuestionClass question) {
        List<SubjectQuestiontypeVo> list = questionClassMapper.listQtype(question);
        String subjectid = question.getSubjectid();
        String  subjectname = subjectMapper.getSubjectnameById(subjectid);
        if(subjectname.contains("英语")){
            //如果是英语题获取英语题对应试题包含听力题的题型
            Integer hearnum = questionMapper.getQuestionHasHearNum(subjectid);
            if(hearnum!=null && hearnum >0){
                SubjectQuestiontypeVo qt = new SubjectQuestiontypeVo();
                qt.setQtypename("听力题");
                qt.setQtypeid("tlt");
                list.add(0,qt);
            }
        }
        return list;
    }

    //客观题详情
    public QuestionClassDetailVo objectiveDetail(TQuestionClass question) {
        Integer qctype = question.getQctype();
        QuestionClassDetailVo detail;
        if (qctype == 1 || qctype == 3) {
            detail = questionClassMapper.objectiveDetail(question);
        } else {
            detail = questionClassMapper.objectiveSDetail(question);
            List<Map> files = questionClassMapper.listObjsByPaperid(detail.getPaperid(), qctype);
            detail.setFiles(files);
            String hearfile = paperMapper.getHearfileByPaperid(detail.getPaperid().intValue());
            detail.setHearfile(hearfile);
        }
        Integer totalnum = questionClassMapper.getTotalnum(detail.getPaperid(), detail.getClassid(),qctype);
        Integer ytjnum = 0;
        List<AnswerStu> stus = detail.getStus();
        for (AnswerStu s : stus) {
            Integer stunum = s.getStunum();
            ytjnum = ytjnum +stunum;
            s.setStuscale(N_Utils.floorDiv(stunum,totalnum));
        }
        detail.setYtjnum(ytjnum);
        detail.setWtjnum(totalnum-ytjnum);

        return detail;
    }

    //主观题详情
    public QuestionClassDetailVo subjectiveDetail(TQuestionClass question) {
        Integer qctype = question.getQctype();
        QuestionClassDetailVo detail;
        if (qctype == 1 || qctype == 3) {
            detail = questionClassMapper.subjectiveDetail(question);
        } else {
            detail = questionClassMapper.subjectiveSDetail(question);
            List<Map> files = questionClassMapper.listObjsByPaperid(detail.getPaperid(), qctype);
            detail.setFiles(files);
            String hearfile = paperMapper.getHearfileByPaperid(detail.getPaperid().intValue());
            detail.setHearfile(hearfile);
        }
        Integer totalnum = detail.getWtjnum();
        List<AnswerStu> stus = detail.getStus();
        Integer ytjnum = stus.size();
        detail.setYtjnum(ytjnum);
        detail.setWtjnum(totalnum-ytjnum);
        Double qscore = detail.getQscore();
        Double ascore = ArithUtil.mul(qscore, 0.25);//0~25%档最高得分
        Double bscore = ArithUtil.mul(qscore, 0.5);//26%~50%档最高得分
        Double cscore = ArithUtil.mul(qscore, 0.75);//51%~75%档最高得分
        Integer anum = 0;//0~25%档人数
        Integer bnum = 0;//26%~50%档人数
        Integer cnum = 0;//51%~75%档人数
        Integer dnum = 0;//76%~100%档人数
        List<String> aname = new ArrayList<>();//0~25%档学生名单
        List<String> bname = new ArrayList<>();//26%~50%档学生名单
        List<String> cname = new ArrayList<>();//51%~75%档学生名单
        List<String> dname = new ArrayList<>();//76%~100%档学生名单
        for (AnswerStu s : stus) {
            Double stuscore = s.getStuscore();
            String stuname = s.getStuname();
            if (stuscore.compareTo(ascore) != 1){
                anum++;
                aname.add(stuname);
            } else if (stuscore.compareTo(bscore) != 1){
                bnum++;
                bname.add(stuname);
            } else if (stuscore.compareTo(cscore) != 1){
                cnum++;
                cname.add(stuname);
            } else {
                dnum++;
                dname.add(stuname);
            }
        }
        List<AnswerStu> list = new ArrayList<>();
        list.add(new AnswerStu("0~25%",anum, N_Utils.floorDiv(anum,totalnum),0.0,StringUtils.join(aname,"  ")));
        list.add(new AnswerStu("26%~50%",bnum, N_Utils.floorDiv(bnum,totalnum),0.0,StringUtils.join(bname,"  ")));
        list.add(new AnswerStu("51%~75%",cnum, N_Utils.floorDiv(cnum,totalnum),0.0,StringUtils.join(cname,"  ")));
        list.add(new AnswerStu("76%~100%",dnum, N_Utils.floorDiv(dnum,totalnum),0.0,StringUtils.join(dname,"  ")));
        detail.setStus(list);
        return detail;
    }

    //更新播放次数
    public Integer updateReadCount(Integer qcpid) {
        questionExplainMapper.updateReadCount(qcpid);
        return questionExplainMapper.getReadCount(qcpid);
    }

    //修改讲解mp4code
    public void updateMp4code(TQuestionExplain explain) {
        questionExplainMapper.updateMp4code(explain);
    }

    //处理数据库之前存在的视频
    public void handleExplain(){
        //获取所有没有视频时长的信息
        List<TQuestionExplain> lst = questionExplainMapper.listAll();
        if(lst!=null && lst.size()>0){
            for(TQuestionExplain qe : lst){
                if(N_Utils.isNotEmpty(qe.getFilepath())){

                    MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
                    map.add("videopath",qe.getFilepath());

                    String rtnstr = StudyUtil.sendFormData(ConfigKey.fileapi + "video/dura",map);
                    ResultVo resultVo = JSON.parseObject(rtnstr, ResultVo.class);
                    if(resultVo.getCode()==0){
                        Map<String,Object> map1 = (Map<String, Object>) resultVo.getObj();
                        Integer duration = Integer.parseInt(map1.get("duration").toString());
                        Integer filesize = Integer.parseInt(map1.get("filesize").toString());

                        if(duration!=null){
                            qe.setDuration(duration);
                            qe.setFilesize(filesize);

                            questionExplainMapper.updateDurationAndSize(qe);
                        }
                    }

                }
            }
        }

    }

    //试题讲解所有视频
    public List<TQuestionExplain> listExplainsByQuestionid(TQuestionExplain questionExplain){
        List<TQuestionExplain> list = questionExplainMapper.listByQuestionId(questionExplain.getQuestionid(),questionExplain.getQctype());
        if(list!=null && list.size()>0){
            for(TQuestionExplain qe : list){
                if (StudyUtil.videoList.contains(qe.getSuffix()) && (N_Utils.isEmpty(qe.getMp4code()) || !"h264".equals(qe.getMp4code()))) {
                    messageSender.convertVideo(qe.getQcpid(), qe.getFilepath(), "explain");
                }
            }
        }
        return list;
    }

    //获取举一反三试题列表
    public List<Map> listJYFSQuestion(String questionid, Integer userid, Integer schoolid) {
        String pointIds = questionClassMapper.getPointIds(questionid);
        if (N_Utils.isEmpty(pointIds)) return new ArrayList<>();
        List<Map> list = questionClassMapper.listJYFSQuestion(pointIds, questionid, userid, schoolid);
        for (Map map : list) {
            questionid = map.get("questionid").toString();
            if (N_Utils.isComplexQuestion((Integer) map.get("ctype"))) {
                List<Map> sonqlist = questionMapper.listSonQuestionsForDetail(questionid);
                map.put("sonqlist", sonqlist);
            }
            Integer collected = questionClassMapper.getCollected(questionid, userid);
            map.put("collected",collected);
            String pointname = questionClassMapper.getPointName(questionid);
            map.put("pointname",pointname);
        }
        return list;
    }

    //复合题详情
    public QuestionClassDetailVo complexDetail(TQuestionClass question) {
        QuestionClassDetailVo detail = questionClassMapper.complexDetail(question);
        List<Map> students = questionClassMapper.listStus(detail);//班级作业学生
        Integer totalnum = students.size();
        Map<Integer, String> stuMap = students.stream().collect(Collectors.toMap(m -> (Integer) m.get("studentid"), m -> m.get("username").toString()));
        List<PaperStudentQuestionVo> answers = questionClassMapper.listStusAnswer(detail);//班级作业学生作答情况
        List<Map> sonqlist = questionMapper.listSonQuestionsForDetail(detail.getQuestionid());
        Set<Integer> studentids = new HashSet<>();
        for (Map q : sonqlist) {
            String questionid = q.get("questionid").toString();
            Integer ctype = (Integer) q.get("ctype");
            List<AnswerStu> stus = new ArrayList<>();
            List<PaperStudentQuestionVo> alist =
                    answers.stream().filter(a -> a.getQuestionid().equals(questionid)).collect(Collectors.toList());
            if (N_Utils.isListEmpty(alist)) {//没有学生作答处理下一题
                q.put("stus", stus);
                continue;
            }
            alist.forEach(a -> {
                a.setStudentname(stuMap.get(a.getStudentid()));
                studentids.add(a.getStudentid());
            });//学生姓名赋值
            if (N_Utils.isObjectiveQuestion(ctype)) {//客观题
                Map<String, List<PaperStudentQuestionVo>> collect =
                        alist.stream().collect(Collectors.groupingBy(a -> a.getUseranswer()));
                for (Map.Entry<String, List<PaperStudentQuestionVo>> entry : collect.entrySet()) {
                    String section = entry.getKey();
                    List<PaperStudentQuestionVo> list = entry.getValue();
                    AnswerStu stu = new AnswerStu();
                    stu.setSection(section);
                    Integer stunum = list.size();
                    stu.setStunum(stunum);
                    stu.setStuscale(N_Utils.floorDiv(stunum, totalnum));
                    String stuname = list.stream().map(s -> s.getStudentname()).sorted().collect(Collectors.joining("  "));
                    stu.setStuname(stuname);
                    stus.add(stu);
                }
                stus = stus.stream().sorted(Comparator.comparing(AnswerStu::getSection)).collect(Collectors.toList());
            } else {//主观题
                Double qscore = alist.get(0).getQscore();
                Double ascore = ArithUtil.mul(qscore, 0.25);//0~25%档最高得分
                Double bscore = ArithUtil.mul(qscore, 0.5);//26%~50%档最高得分
                Double cscore = ArithUtil.mul(qscore, 0.75);//51%~75%档最高得分
                Integer anum = 0;//0~25%档人数
                Integer bnum = 0;//26%~50%档人数
                Integer cnum = 0;//51%~75%档人数
                Integer dnum = 0;//76%~100%档人数
                List<String> aname = new ArrayList<>();//0~25%档学生名单
                List<String> bname = new ArrayList<>();//26%~50%档学生名单
                List<String> cname = new ArrayList<>();//51%~75%档学生名单
                List<String> dname = new ArrayList<>();//76%~100%档学生名单
                for (PaperStudentQuestionVo s : alist) {
                    Double stuscore = s.getStuscore();
                    String stuname = s.getStudentname();
                    if (stuscore.compareTo(ascore) != 1) {
                        anum++;
                        aname.add(stuname);
                    } else if (stuscore.compareTo(bscore) != 1) {
                        bnum++;
                        bname.add(stuname);
                    } else if (stuscore.compareTo(cscore) != 1) {
                        cnum++;
                        cname.add(stuname);
                    } else {
                        dnum++;
                        dname.add(stuname);
                    }
                }
                stus.add(new AnswerStu("0~25%", anum, N_Utils.floorDiv(anum, totalnum), 0.0, StringUtils.join(aname, "  ")));
                stus.add(new AnswerStu("26%~50%", bnum, N_Utils.floorDiv(bnum, totalnum), 0.0, StringUtils.join(bname, "  ")));
                stus.add(new AnswerStu("51%~75%", cnum, N_Utils.floorDiv(cnum, totalnum), 0.0, StringUtils.join(cname, "  ")));
                stus.add(new AnswerStu("76%~100%", dnum, N_Utils.floorDiv(dnum, totalnum), 0.0, StringUtils.join(dname, "  ")));
            }
            q.put("stus", stus);
        }
        Integer ytjnum = studentids.size();
        detail.setYtjnum(ytjnum);
        detail.setWtjnum(totalnum - ytjnum);
        detail.setSonqlist(sonqlist);
        return detail;
    }
}
