package com.qmth.distributed.print.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.qmth.distributed.print.business.bean.dto.open.*;
import com.qmth.distributed.print.business.entity.*;
import com.qmth.distributed.print.business.service.*;
import com.qmth.teachcloud.common.entity.BasicMajor;
import com.qmth.teachcloud.common.entity.BasicSchool;
import com.qmth.teachcloud.common.service.BasicMajorService;
import org.springframework.stereotype.Service;

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

@Service
public class OpenApiServiceImpl implements OpenApiService {

    @Resource
    private GradeBatchPaperService gradeBatchPaperService;

    @Resource
    private GradePaperService gradePaperService;

    @Resource
    private GradePaperDimensionService gradePaperDimensionService;

    @Resource
    private GradePaperStructService gradePaperStructService;

    @Resource
    private GradeModuleDefineService gradeModuleDefineService;

    @Resource
    private GradeModuleEvaluationService gradeModuleEvaluationService;

    @Resource
    ExamTaskService examTaskService;

    @Resource
    BasicMajorService basicMajorService;

    @Resource
    private TSyncExamStudentScoreService tSyncExamStudentScoreService;

    @Resource
    private GradeBatchStudentService gradeBatchStudentService;

    @Override
    public PaperConfig getPaperConfig(BasicSchool basicSchool, String thirdExamId, String gradeCourseCode) {
        GradeBatchPaper gradeBatchPaper = gradeBatchPaperService.findByThirdExamIdAndGradeCourseCode(basicSchool.getId(), thirdExamId, gradeCourseCode);
        if (gradeBatchPaper == null) {
            return null;
        }
        return gradePaperService.findBySchoolIdAndPaperNumberAndPaperType(gradeBatchPaper.getSchoolId(), gradeBatchPaper.getPaperNumber(), gradeBatchPaper.getPaperType());
    }

    @Override
    public List<PaperDimension> getPaperDimension(BasicSchool basicSchool, String thirdExamId, String gradeCourseCode) {
        GradeBatchPaper gradeBatchPaper = gradeBatchPaperService.findByThirdExamIdAndGradeCourseCode(basicSchool.getId(), thirdExamId, gradeCourseCode);
        if (gradeBatchPaper == null) {
            return new ArrayList<>();
        }
        return gradePaperDimensionService.findBySchoolIdAndPaperNumberAndPaperType(gradeBatchPaper.getSchoolId(), gradeBatchPaper.getPaperNumber(), gradeBatchPaper.getPaperType());
    }

    @Override
    public List<PaperStructure> getPaperStructure(BasicSchool basicSchool, String thirdExamId, String gradeCourseCode) {
        GradeBatchPaper gradeBatchPaper = gradeBatchPaperService.findByThirdExamIdAndGradeCourseCode(basicSchool.getId(), thirdExamId, gradeCourseCode);
        if (gradeBatchPaper == null) {
            return new ArrayList<>();
        }
        return gradePaperStructService.findBySchoolIdAndPaperNumberAndPaperType(gradeBatchPaper.getSchoolId(), gradeBatchPaper.getPaperNumber(), gradeBatchPaper.getPaperType());
    }

    @Override
    public List<PaperEvaluation> getPaperEvaluation(BasicSchool basicSchool, String thirdExamId, String gradeCourseCode) {
        List<PaperEvaluation> paperEvaluations = new ArrayList<>();
        GradeBatchPaper gradeBatchPaper = gradeBatchPaperService.findByThirdExamIdAndGradeCourseCode(basicSchool.getId(), thirdExamId, gradeCourseCode);
        if (gradeBatchPaper == null) {
            return paperEvaluations;
        }
        List<GradeModuleDefine> gradeModuleDefineList = gradeModuleDefineService.findBySchoolIdAndPaperNumberAndPaperType(gradeBatchPaper.getSchoolId(), gradeBatchPaper.getPaperNumber(), gradeBatchPaper.getPaperType());
        List<GradeModuleEvaluation> gradeModuleEvaluationList = gradeModuleEvaluationService.findBySchoolIdAndPaperNumberAndPaperType(gradeBatchPaper.getSchoolId(), gradeBatchPaper.getPaperNumber(), gradeBatchPaper.getPaperType());
        // 分组（分隔符_）
        if (!gradeModuleDefineList.isEmpty()) {

            Map<String, List<GradeModuleDefine>> stringListMap = gradeModuleDefineList.stream().collect(Collectors.groupingBy(m -> m.getModuleType() + "_" + m.getInterpret() + "_" + m.getRemark()));
            for (Map.Entry<String, List<GradeModuleDefine>> stringListEntry : stringListMap.entrySet()) {
                String[] key = stringListEntry.getKey().split("_");
                String moduleType = key[0];
                String interpret = key[1];
                String remark = key[2];

                PaperEvaluation paperEvaluation = new PaperEvaluation();
                paperEvaluation.setModuleType(moduleType);
                paperEvaluation.setInterpret(interpret);
                paperEvaluation.setRemark(remark);

                List<PaperEvaluation.SecondaryDimensionLevelDefine> secondaryDimensionLevelDefineArrayList = new ArrayList<>();
                for (GradeModuleDefine gradeModuleDefine : stringListEntry.getValue()) {
                    PaperEvaluation.SecondaryDimensionLevelDefine secondaryDimensionLevelDefine = new PaperEvaluation.SecondaryDimensionLevelDefine();
                    secondaryDimensionLevelDefine.setDefine(gradeModuleDefine.getDefine());
                    secondaryDimensionLevelDefine.setLevel(gradeModuleDefine.getLevel());
                    secondaryDimensionLevelDefine.setMax(gradeModuleDefine.getMax());
                    secondaryDimensionLevelDefine.setMin(gradeModuleDefine.getMin());
                    secondaryDimensionLevelDefine.setScope(gradeModuleDefine.getScope());
                    secondaryDimensionLevelDefineArrayList.add(secondaryDimensionLevelDefine);
                }
                paperEvaluation.setSecondaryDimensionLevelDefineList(secondaryDimensionLevelDefineArrayList);

                if (!gradeModuleEvaluationList.isEmpty()) {
                    GradeModuleEvaluation gradeModuleEvaluation = gradeModuleEvaluationList.stream().filter(m -> moduleType.equals(m.getModuleType().name())).findFirst().orElseGet(null);
                    paperEvaluation.setFormula(gradeModuleEvaluation == null ? null : gradeModuleEvaluation.getFormula().name());

                    List<PaperEvaluation.ModuleEvaluation> moduleEvaluationList = gradeModuleEvaluationList.stream().filter(m -> moduleType.equals(m.getModuleType().name())).map(m -> {
                        PaperEvaluation.ModuleEvaluation moduleEvaluation = new PaperEvaluation.ModuleEvaluation();
                        moduleEvaluation.setAdvice(m.getAdvice());
                        moduleEvaluation.setLevelCode(m.getLevelCode());
                        moduleEvaluation.setLevelName(m.getLevelName());
                        moduleEvaluation.setResult(m.getResult());
                        moduleEvaluation.setScope(m.getScope());
                        return moduleEvaluation;
                    }).collect(Collectors.toList());
                    paperEvaluation.setModuleEvaluationList(moduleEvaluationList);
                }

                paperEvaluations.add(paperEvaluation);
            }
            return paperEvaluations;
        }
        return paperEvaluations;
    }

    @Override
    public List<ExamStudentScore> listExamStudentScore(BasicSchool basicSchool, String thirdExamId, String gradeCourseCode, Integer pageNumber, Integer pageSize) {
        GradeBatchPaper gradeBatchPaper = gradeBatchPaperService.findByThirdExamIdAndGradeCourseCode(basicSchool.getId(), thirdExamId, gradeCourseCode);
        List<ExamStudentScore> examStudentScoreList = new ArrayList<>();
        if (gradeBatchPaper == null) {
            return examStudentScoreList;
        }

        QueryWrapper<ExamTask> examTaskQueryWrapper = new QueryWrapper<>();
        examTaskQueryWrapper.lambda().eq(ExamTask::getSchoolId, gradeBatchPaper.getSchoolId())
                .eq(ExamTask::getPaperNumber, gradeBatchPaper.getPaperNumber());
        ExamTask examTask = examTaskService.getOne(examTaskQueryWrapper);
        if (examTask == null) {
            return examStudentScoreList;
        }

        QueryWrapper<GradeBatchStudent> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(GradeBatchStudent::getBatchId, gradeBatchPaper.getBatchId());
        List<GradeBatchStudent> gradeBatchStudentList = gradeBatchStudentService.list(queryWrapper);

        QueryWrapper<TSyncExamStudentScore> examStudentScoreQueryWrapper = new QueryWrapper<>();
        String subjectCode = examTask.getCourseCode() + gradeBatchPaper.getPaperType() + examTask.getSequence();
        examStudentScoreQueryWrapper.lambda().eq(TSyncExamStudentScore::getSchoolId, gradeBatchPaper.getSchoolId())
                .eq(TSyncExamStudentScore::getSubjectCode, subjectCode);

        Page<TSyncExamStudentScore> page = new Page<>(pageNumber, pageSize);
        IPage<TSyncExamStudentScore> tSyncExamStudentScoreIPage = tSyncExamStudentScoreService.page(page, examStudentScoreQueryWrapper);
        examStudentScoreList = tSyncExamStudentScoreIPage.getRecords().stream().map(m -> {
            ExamStudentScore examStudentScore = new ExamStudentScore();
            examStudentScore.setName(m.getName());
            examStudentScore.setStudentCode(m.getStudentCode());
            examStudentScore.setPaperNumber(gradeBatchPaper.getPaperNumber());
            examStudentScore.setPaperName(m.getSubjectName());
            examStudentScore.setPaperType(gradeBatchPaper.getPaperType());
            examStudentScore.setCollege(m.getCollege());
            BasicMajor basicMajor = basicMajorService.getById(m.getMajorId());
            examStudentScore.setMajor(basicMajor == null ? null : basicMajor.getName());
            examStudentScore.setClassName(m.getClazzName());
            GradeBatchStudent gradeBatchStudent = gradeBatchStudentList.isEmpty() ? null : gradeBatchStudentList.stream().filter(s -> s.getStudentCode().equals(examStudentScore.getStudentCode()) && s.getPaperNumber().equals(examStudentScore.getPaperNumber()) && s.getPaperType().equals(examStudentScore.getPaperType())).findFirst().orElseGet(null);
            examStudentScore.setTeacherName(gradeBatchStudent != null ? gradeBatchStudent.getTeacherName() : null);
            examStudentScore.setTeacherCode(gradeBatchStudent != null ? gradeBatchStudent.getTeacherNumber() : null);
            examStudentScore.setStatus(m.getStatus());
            examStudentScore.setTotalScore(m.getTotalScore());
            examStudentScore.setObjectiveScore(m.getObjectiveScore());
            examStudentScore.setSubjectiveScore(m.getSubjectiveScore());
            String syncData = m.getSyncData();
            JSONObject jsonObject = JSONObject.parseObject(syncData);
            List<ExamStudentScore.TopicInfo> objectiveTopic = new ArrayList<>();
            if (jsonObject.containsKey("objectiveScoreDetail")) {
                String objective = jsonObject.getString("objectiveScoreDetail");
                objectiveTopic = JSON.parseArray(objective, ExamStudentScore.TopicInfo.class);
            }
            examStudentScore.setObjectiveScoreDetail(objectiveTopic);

            List<ExamStudentScore.TopicInfo> subjectiveTopic = new ArrayList<>();
            if (jsonObject.containsKey("subjectiveScoreDetail")) {
                String subjective = jsonObject.getString("subjectiveScoreDetail");
                subjectiveTopic = JSON.parseArray(subjective, ExamStudentScore.TopicInfo.class);
            }
            examStudentScore.setSubjectiveScoreDetail(subjectiveTopic);
            return examStudentScore;
        }).collect(Collectors.toList());
        return examStudentScoreList;
    }
}
