package com.xhkjedu.smarking.service.paper;

import com.xhkjedu.exception.MissingParametersException;
import com.xhkjedu.exception.ServiceException;
import com.xhkjedu.smarking.mapper.exam.MsSubjectMapper;
import com.xhkjedu.smarking.mapper.paper.*;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentBlockMapper;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentMapper;
import com.xhkjedu.smarking.mapper.stupaper.MsPaperStudentQuestionMapper;
import com.xhkjedu.smarking.mapper.system.SchoolMapper;
import com.xhkjedu.smarking.mapper.system.UserMapper;
import com.xhkjedu.smarking.model.paper.*;
import com.xhkjedu.smarking.model.stupaper.MsPaperStudent;
import com.xhkjedu.smarking.model.stupaper.MsPaperStudentBlock;
import com.xhkjedu.smarking.model.stupaper.MsPaperStudentQuestion;
import com.xhkjedu.smarking.utils.MarkingUtil;
import com.xhkjedu.smarking.vo.paper.MsPaperParams;
import com.xhkjedu.smarking.vo.system.SchoolCloudVo;
import com.xhkjedu.utils.N_Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 阅卷扫描模板表 服务实现类
 * @Author auto
 * @Date 2024-10-15
 */
@Slf4j
@Service
public class MsTemplateService {
    @Resource
    private MsTemplateMapper msTemplateMapper;
    @Resource
    private MsTemplateBlockMapper msTemplateBlockMapper;
    @Resource
    private MsTemplateBlockQuestionMapper msTemplateBlockQuestionMapper;
    @Resource
    private MsPaperQtypeQuestionMapper msPaperQtypeQuestionMapper;
    @Resource
    private MsPaperBlockMapper msPaperBlockMapper;
    @Resource
    private MsPaperBlockQuestionMapper msPaperBlockQuestionMapper;
    @Resource
    private MsSubjectMapper msSubjectMapper;
    @Resource
    private SchoolMapper schoolMapper;
    @Resource
    private MsPaperMapper msPaperMapper;
    @Resource
    private MsPaperStudentMapper msPaperStudentMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private MsPaperStudentBlockMapper msPaperStudentBlockMapper;
    @Resource
    private MsPaperStudentQuestionMapper msPaperStudentQuestionMapper;

    /*
     * @Description 试卷模板列表
     * @Date 2024/10/18 14:44:33
     * @Author WN
     * @Param [getMpid]
     * @Return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     **/
    public Map<String,Object> listTemplatesByMpid(Integer mpid){
        Map<String,Object> rtnMap = msPaperMapper.getSubjectAndExamByMpid(mpid);
        rtnMap.put("list",msTemplateMapper.listTemplatesByMpid(mpid));
        return rtnMap;
    }

    /**
     * @Description 新增
     * @Param [msTemplate]
     * @Author auto
     * @Date 2024-10-15
     * @return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public Integer save(MsTemplate msTemplate){
        msTemplate.setCreatetime(N_Utils.getSecondTimestamp());
        msTemplate.setCurrstep(1);
        msTemplate.setTstate(0);
        msTemplate.setTbstate(0);
        msTemplate.setBlankindex(-1);

        SchoolCloudVo school = schoolMapper.getSchoolCloudcode(msTemplate.getMpid());
        String savefloder = school.getCloudcode() + "/" + school.getSchoolid() + "/marking/paper";
        String tfront = MarkingUtil.uploadBase64Img(msTemplate.getTfront(),1, savefloder);
        if(N_Utils.isNotEmpty(tfront)){
            msTemplate.setTfront(tfront);
        }
        String tback = MarkingUtil.uploadBase64Img(msTemplate.getTback(),1, savefloder);
        if(N_Utils.isNotEmpty(tback)){
            msTemplate.setTback(tback);
        }

        msTemplateMapper.insertUseGeneratedKeys(msTemplate);
        int mtid = msTemplate.getId();
        msTemplate.setMtid(mtid);

        //更新科目模板状态
        msSubjectMapper.updatePtstateByMpid(msTemplate.getMpid(),1);
        return mtid;
    }

    /*
     * @Description 设置模板
     * @Date 2024/10/21 10:47:00
     * @Author WN
     * @Param [msTemplate]
     * @Return com.xhkjedu.smarking.model.paper.MsTemplate
     **/
    @Transactional(rollbackFor = Exception.class)
    public MsTemplate updateTemplate(MsTemplate msTemplate){

        //根据模板ID获取模板信息
        MsTemplate oldTemplate = msTemplateMapper.selectByPrimaryKey(msTemplate.getMtid());
        if(!msTemplate.getCurrstep().equals(oldTemplate.getCurrstep())) throw new ServiceException("请按顺序操作");

        //定位区选择
        if(msTemplate.getCurrstep() == 3){
            SchoolCloudVo school = schoolMapper.getSchoolCloudcode(msTemplate.getMpid());
            String savefloder = school.getCloudcode() + "/" + school.getSchoolid() + "/marking/paper";
            if(N_Utils.isNotEmpty(msTemplate.getDwtfront())){
                //定位区正面图片
                String dwtfront = MarkingUtil.uploadBase64Img(msTemplate.getDwtfront(),1, savefloder);
                msTemplate.setDwtfront(dwtfront);
            }
            if(N_Utils.isNotEmpty(msTemplate.getDwtback())){
                //定位区反面图片
                String dwtback = MarkingUtil.uploadBase64Img(msTemplate.getDwtback(),1, savefloder);
                msTemplate.setDwtback(dwtback);
            }
        }

        //其中currstep保存时会加1，代表保存后的步骤
        msTemplateMapper.updateTemplateForCurrstep(msTemplate);
        //如果当前保存为6，则需要保存客观题信息
        if(msTemplate.getCurrstep() == 5){
            //模板题块信息
            List<MsTemplateBlock> tblocks = msTemplate.getTblocks();
            savePaperBlockAndTemplate(tblocks,msTemplate);
        }

        if(msTemplate.getCurrstep() == 7){
            Integer mpid = msTemplate.getMpid();
            //代表提交,获取试卷对应所有的模块状态，如果均是已提交，则更改科目表中状态
            int uncommit = msTemplateMapper.getUnCommitTemplateCount(mpid);
            if(uncommit == 0){
                msSubjectMapper.updatePtstateByMpid(mpid,2);
            }
        }
        return msTemplateMapper.selectByPrimaryKey(msTemplate.getMtid());
    }

    //保存客观题题块和模板信息
    private void savePaperBlockAndTemplate(List<MsTemplateBlock> tblocks,MsTemplate msTemplate){
        Integer mpid = msTemplate.getMpid();
        Integer mtid = msTemplate.getMtid();
        Integer timestamp = N_Utils.getSecondTimestamp();
        Integer createid = msTemplate.getCreateid();

        //保存之前先清除已保存的信息试卷客观题题块、模板题块
        msTemplateBlockMapper.deleteByMtidAndMtype(msTemplate.getMtid(),1);
        msPaperBlockMapper.deleteObjByMpidAndBlocktype(mpid,1);
        //获取试卷中所有试题信息
        List<MsPaperQtypeQuestion> questions = msPaperQtypeQuestionMapper.listQuestionsByMpid(mpid);
        List<MsPaperQtypeQuestion> objQuestions = questions.stream().filter(q -> q.getQtype() == 1).collect(Collectors.toList());//客观题试题信息
        if(objQuestions.isEmpty()){
            return;
        }

        if(tblocks.isEmpty()){
            throw new ServiceException("未设置客观题");
        }

        //客观题题块试题信息
        List<MsPaperBlockQuestion> savePbquestions = new ArrayList<>();
        //客观题模块试题信息
        List<MsTemplateBlockQuestion> saveTbquestions = new ArrayList<>();

        int i = 1;
        for(MsTemplateBlock tblock : tblocks){
            //获取客观题单题
            List<MsTemplateBlockQuestion> tbquestions = tblock.getTbquestions();
            //获取客观题题号
            List<String> tbqns = tbquestions.stream().map(MsTemplateBlockQuestion::getQn).collect(Collectors.toList());
            //包含的客观题试题信息
            List<MsPaperQtypeQuestion> selQuestions = objQuestions.stream().filter(q -> tbqns.contains(q.getQn())).collect(Collectors.toList());
            if(selQuestions.isEmpty()){
                throw new ServiceException("试题信息和试卷不匹配");
            }

            Double tbqScores = selQuestions.stream().mapToDouble(MsPaperQtypeQuestion::getQscore).sum();//题块下试题总分值

            //保存试卷题块信息
            MsPaperBlock paperBlock = new MsPaperBlock();
            paperBlock.setMpid(mpid);
            paperBlock.setBlockname("客观题题块" + (i++));
            paperBlock.setBlocktype(1);
            paperBlock.setBlockorder(tblock.getMtborder());
            paperBlock.setBqnum(tbquestions.size());
            paperBlock.setBqscore(tbqScores);
            paperBlock.setCreateid(createid);
            paperBlock.setCreatetime(timestamp);
            msPaperBlockMapper.insertUseGeneratedKeys(paperBlock);
            Integer mblockid = paperBlock.getId();//题块ID

            //保存模板题块信息
            tblock.setMtid(mtid);
            tblock.setBlockname(paperBlock.getBlockname());
            tblock.setMttype(1);
            tblock.setMblockid(mblockid);
            tblock.setCreateid(createid);
            tblock.setCreatetime(timestamp);
            msTemplateBlockMapper.insertUseGeneratedKeys(tblock);
            Integer mtbid = tblock.getId();

            for(MsTemplateBlockQuestion tbquestion : tbquestions) {
                MsPaperQtypeQuestion q = selQuestions.stream().filter(q1 -> q1.getQn().equals(tbquestion.getQn())).findFirst().orElse(null);

                if(q == null) throw new ServiceException("试题信息和试卷不匹配");

                tbquestion.setMtbid(mtbid);
                tbquestion.setMptqid(q.getMptqid());
                saveTbquestions.add(tbquestion);

                MsPaperBlockQuestion pbquestion = new MsPaperBlockQuestion();
                pbquestion.setMblockid(mblockid);
                pbquestion.setMpid(mpid);
                pbquestion.setMbqtype(1);
                pbquestion.setMptqid(q.getMptqid());
                pbquestion.setBqn(q.getQnstr());
                pbquestion.setBqscore(q.getQscore());
                pbquestion.setBqorder(tbquestion.getMtbqorder());
                pbquestion.setCreateid(createid);
                pbquestion.setCreatetime(timestamp);
                savePbquestions.add(pbquestion);
            }
        }

        if(saveTbquestions.isEmpty()) throw new ServiceException("未设置客观题");
        if(objQuestions.size() != saveTbquestions.size()) throw new ServiceException("试题信息和试卷不匹配");

        msPaperBlockQuestionMapper.insertList(savePbquestions);
        msTemplateBlockQuestionMapper.insertList(saveTbquestions);
    }


    /*
     * @Description 保存模板主观题框选
     * @Date 2024/10/21 17:41:42
     * @Author WN
     * @Param [params]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void saveSubjectiveQuestion(MsPaperParams params){
        Integer mtid = params.getMtid();
        Integer mpid = params.getMpid();
        Integer createid = params.getCreateid();
        Integer timestamp = N_Utils.getSecondTimestamp();
        List<MsTemplateBlock> templateBlocks = params.getTblocks();
        //获取试卷中所有主观题id
        List<Integer> blockids = msPaperBlockMapper.listSubjectiveBlockidsByMpid(mpid);
        List<Integer> selids = templateBlocks.stream().map(MsTemplateBlock::getMblockid).collect(Collectors.toList());

        boolean areEqual = blockids.stream().sorted().collect(Collectors.toList())
                                .equals(selids.stream().sorted().collect(Collectors.toList()));
        if(!areEqual){
            throw new MissingParametersException("题块未全部框选");
        }

        for (MsTemplateBlock templateBlock : templateBlocks){
            templateBlock.setMtid(mtid);
            templateBlock.setMttype(2);
            templateBlock.setCreateid(createid);
            templateBlock.setCreatetime(timestamp);
        }

        //删除模板中题块定位数据
        msTemplateBlockMapper.deleteByMtidAndMtype(mtid,2);

        //保存模板题块信息
        msTemplateBlockMapper.insertList(templateBlocks);

        //更改模板题块框选状态
        msTemplateMapper.updateTemplateTbstate(mtid,1);
        //清空已生成学生试卷、题块、试题信息
        msPaperStudentMapper.deletePaperStuByMpid(mpid);

        //获取试卷中所有模板题块框选状态
        int tbnum = msTemplateMapper.getUnSelTemplateCount(mpid);
        if(tbnum == 0){
            //更改科目题块框选状态已完成
            msSubjectMapper.updatePbstateByMpid(mpid,2);
            //保存学生试卷试题信息
            savePaperStudentBlock(mpid);
        }
    }

    //保存学生试卷试题信息
    private void savePaperStudentBlock(Integer mpid){
        //获取试卷对应信息
        MsPaper paper = msPaperMapper.selectByPrimaryKey(mpid);
        Integer examid = paper.getExamid();
        String subjectid = paper.getSubjectid();
        //获取试卷中所有学生信息
        List<Integer> students = userMapper.listStuForExamByExamIdAndSubjectid(examid,subjectid);
        Integer timestamp = N_Utils.getSecondTimestamp();
        List<MsPaperStudent> savePaperStudents = new ArrayList<>();
        for(Integer stuid : students) {
            MsPaperStudent es = new MsPaperStudent();
            es.setExamid(examid);
            es.setMsid(paper.getMsid());
            es.setMpid(mpid);
            es.setSubjectid(subjectid);
            es.setStudentid(stuid);
            es.setSstate(0);
            es.setPnum(paper.getPnum());
            es.setPscore(paper.getPscore());
            es.setStuscore(0.0);
            es.setCosttime(0);
            es.setCreatetime(timestamp);
            es.setHasbad(0);
            es.setStuscoretype(0);
            es.setPagenum(0);
            es.setSubmittype(0);
            savePaperStudents.add(es);
        }
        msPaperStudentMapper.insertList(savePaperStudents);//保存试卷学生信息
        //获取试卷中题块、试题信息
        List<MsPaperBlock> paperBlocks = msPaperBlockMapper.listPaperBlockQuestions(mpid,null);
        //获取试卷中所有试题
        List<MsPaperQtypeQuestion> questions = msPaperQtypeQuestionMapper.listQuestionsByMpid(mpid);
        List<MsPaperStudentBlock> savePaperStudentBlocks = new ArrayList<>();
        List<MsPaperStudentQuestion> savePaperStudentQuestions = new ArrayList<>();
        Map<Integer,Integer> quesBlockMap = new HashMap<>();
        int i = 0;
        for(MsPaperStudent ps : savePaperStudents){
            Integer mpsid = ps.getId();
            Integer studentid = ps.getStudentid();

            for(MsPaperBlock block : paperBlocks){
                Integer mblockid = block.getMblockid();
                MsPaperStudentBlock psblock = new MsPaperStudentBlock();
                psblock.setExamid(examid);
                psblock.setMpid(mpid);
                psblock.setSubjectid(subjectid);
                psblock.setStudentid(studentid);
                psblock.setMblockid(mblockid);
                psblock.setMpsid(mpsid);
                psblock.setCreatetime(timestamp);
                savePaperStudentBlocks.add(psblock);

                if(i == 0){
                    //处理试题题块关系
                    List<MsPaperBlockQuestion> bqlist = block.getQuestions();
                    for(MsPaperBlockQuestion bq : bqlist){
                        if(bq.getMbqtype() == 1){
                            //说明是原题
                            quesBlockMap.put(bq.getMptqid(),mblockid);
                        }else{
                            //合并试题
                            String mptqids = bq.getMergeqid();
                            String[] ids = mptqids.split(",");
                            for(String id : ids){
                                quesBlockMap.put(Integer.parseInt(id),mblockid);
                            }
                        }
                    }
                }
            }
            i++;

            for(MsPaperQtypeQuestion q : questions){
                MsPaperStudentQuestion psquestion = new MsPaperStudentQuestion();
                psquestion.setMpid(mpid);
                psquestion.setStudentid(studentid);
                psquestion.setExamid(examid);
                psquestion.setSubjectid(subjectid);
                psquestion.setMptqid(q.getMptqid());
                psquestion.setMpsid(mpsid);
                psquestion.setMblockid(quesBlockMap.get(q.getMptqid()));
                psquestion.setCtype(q.getCtype());
                psquestion.setQuestionid(q.getQuestionid());
                psquestion.setQn(q.getQn());
                psquestion.setQorder(q.getQorder());
                psquestion.setQscore(q.getQscore());

                savePaperStudentQuestions.add(psquestion);
            }
        }
        msPaperStudentBlockMapper.insertBatchStudentBlock(savePaperStudentBlocks);//保存试卷学生题块信息
        msPaperStudentQuestionMapper.saveBatchStuPaperQuestion(savePaperStudentQuestions);//保存试卷学生试题信息

    }

    /*
     * @Description 删除模板
     * @Date 2024/10/21 17:49:46
     * @Author WN
     * @Param [mtid]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void deleteTemplate(Integer mtid){
        MsTemplate msTemplate = msTemplateMapper.selectByPrimaryKey(mtid);
        int mpid = msTemplate.getMpid();
        msTemplateMapper.deleteByPrimaryKey(mtid);
        //更改科目题块框选状态未设置
        msSubjectMapper.updatePbstateByMpid(mpid,0);
    }

    /*
     * @Description 获取模板详情
     * @Date 2024/10/23 11:47:48
     * @Author WN
     * @Param [mtid]
     * @Return com.xhkjedu.smarking.model.paper.MsTemplate
     **/
    public MsTemplate getTemplateDetailByMtid(MsTemplate mt){
        MsTemplate msTemplate = msTemplateMapper.getTemplateAndExamidByMtid(mt.getMtid());
        msTemplate.setTblocks(msTemplateBlockMapper.listTemplateBlockQuestions(mt.getMtid(),mt.getMttype()));
        return msTemplate;
    }

    /*
     * @Description 模板题块详情-主观题
     * @Date 2024/10/24 10:24:05
     * @Author WN
     * @Param [mtid]
     * @Return java.util.List<com.xhkjedu.smarking.model.paper.MsTemplateBlock>
     **/
    public List<Map<String,Object>> listTemplateBlocksByMtidAndType(Integer mtid){
        return msTemplateBlockMapper.listSubjectiveBlockQuestions(mtid);
    }

    /*
     * @Description 主观题框选题块获取
     * @Date 2024/12/27 16:51:38
     * @Author WN
     * @Param [mpid, mtid]
     * @Return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     **/
    public List<Map<String,Object>> listBlockTemplates(Integer mpid, Integer mtid){
        return msTemplateBlockMapper.listBlockTemplates(mpid, mtid);
    }
}
