package cn.com.qmth.stmms.ms.admin.service;

import cn.com.qmth.stmms.ms.core.domain.InspectRange;
import cn.com.qmth.stmms.ms.core.domain.InspectStudent;
import cn.com.qmth.stmms.ms.core.domain.InspectTask;
import cn.com.qmth.stmms.ms.core.domain.Paper;
import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
import cn.com.qmth.stmms.ms.core.domain.user.Role;
import cn.com.qmth.stmms.ms.core.repository.*;
import cn.com.qmth.stmms.ms.core.vo.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by yuanpan on 2017/10/19.
 */
@Service
public class InspectRangeService {

    @Autowired
    private InspectRangeRepo inspectRangeRepo;

    @Autowired
    private PaperRepo paperRepo;

    @Autowired
    private InspectTaskRepo inspectTaskRepo;

    @Autowired
    private MarkUserRepo markUserRepo;


    @Autowired
    private InspectStudentRepo inspectStudentRepo;

    @Transactional
    public void start(Long id) {
        //将本范围激活，并将其他范围设置成未激活
        InspectRange inspectRange = inspectRangeRepo.findOne(id);
        inspectRange.setEditable(false);
        inspectRange.setActive(true);
        inspectRangeRepo.save(inspectRange);

        List<InspectRange> otherRanges = inspectRangeRepo.findByWorkId(inspectRange.getWorkId());
        for (InspectRange r : otherRanges) {
            if (!Objects.equals(r.getId(), inspectRange.getId())) {
                r.setActive(false);
                inspectRangeRepo.save(r);
            }
        }

        //判断是否已经有复查任务了
        int taskCount = inspectTaskRepo.countByWorkIdAndInspectRangeId(inspectRange.getWorkId(), inspectRange.getId());
        if (taskCount > 0) {
            //不要重新生产任务
            return;
        }

        List<MarkUser> scInspectors = markUserRepo.findByWorkIdAndSubjectAndRole(inspectRange.getWorkId(), Subject.SC, Role.INSPECTOR);
        List<MarkUser> sxInspectors = markUserRepo.findByWorkIdAndSubjectAndRole(inspectRange.getWorkId(), Subject.SX, Role.INSPECTOR);
        List<MarkUser> smInspectors = markUserRepo.findByWorkIdAndSubjectAndRole(inspectRange.getWorkId(), Subject.SM, Role.INSPECTOR);

        List<InspectStudent> inspectStudents = inspectStudentRepo.findByInspectRangeId(id);

        List<InspectTask> inspectTasks = new ArrayList<>();
        for (InspectStudent inspectStudent : inspectStudents) {
            String examNumber = inspectStudent.getExamNumber();
            Paper scPaper = paperRepo.findByWorkIdAndSubjectAndExamNumber(inspectRange.getWorkId(), Subject.SC, examNumber);
            Paper sxPaper = paperRepo.findByWorkIdAndSubjectAndExamNumber(inspectRange.getWorkId(), Subject.SX, examNumber);
            Paper smPaper = paperRepo.findByWorkIdAndSubjectAndExamNumber(inspectRange.getWorkId(), Subject.SM, examNumber);


            //色彩的
            if(scPaper != null){
            	for (MarkUser inspector : scInspectors) {
            		InspectTask inspectTask = new InspectTask();
            		
            		inspectTask.setMarkerId(inspector.getId());
            		inspectTask.setMarkerName(inspector.getName());
            		inspectTask.setSubject(inspector.getSubject());
            		inspectTask.setWorkId(inspectRange.getWorkId());
            		inspectTask.setInspectRangeId(id);
            		inspectTask.setPaper(scPaper);
            		inspectTask.setQuestionId(scPaper.getQuestionId());
            		inspectTask.setCreatedOn(new Date());
            		
            		inspectTasks.add(inspectTask);
            	}
            }
            //速写
            if(sxPaper != null){
            	for (MarkUser inspector : sxInspectors) {
            		InspectTask inspectTask = new InspectTask();
            		
            		inspectTask.setMarkerId(inspector.getId());
            		inspectTask.setMarkerName(inspector.getName());
            		inspectTask.setSubject(inspector.getSubject());
            		inspectTask.setWorkId(inspectRange.getWorkId());
            		inspectTask.setInspectRangeId(id);
            		inspectTask.setPaper(sxPaper);
            		inspectTask.setQuestionId(sxPaper.getQuestionId());
            		inspectTask.setCreatedOn(new Date());
            		
            		inspectTasks.add(inspectTask);
            	}
            }
            //素描
            if(smPaper != null){
            	for (MarkUser inspector : smInspectors) {
            		InspectTask inspectTask = new InspectTask();
            		
            		inspectTask.setMarkerId(inspector.getId());
            		inspectTask.setMarkerName(inspector.getName());
            		inspectTask.setSubject(inspector.getSubject());
            		inspectTask.setWorkId(inspectRange.getWorkId());
            		inspectTask.setInspectRangeId(id);
            		inspectTask.setPaper(smPaper);
            		inspectTask.setQuestionId(smPaper.getQuestionId());
            		inspectTask.setCreatedOn(new Date());
            		
            		inspectTasks.add(inspectTask);
            	}
            }

        }

        inspectTaskRepo.save(inspectTasks);

    }


    @Transactional
    public void save(InspectRange inspectRange) {

        InspectRange.InspectRangeType type = inspectRange.getType();

        Long workId = inspectRange.getWorkId();

        List<Paper> papers = paperRepo.findByWorkId(workId);


        List<String> examNumbers = new ArrayList<>();

        Map<String, List<Paper>> group;
        //根据抽查方式，计算出将要抽查的人数
        switch (type) {
            case ZF:
                //根据总分查询
                group = papers.stream().collect(Collectors.groupingBy(Paper::getExamNumber));
                group.forEach((examNumber, paperList) -> {
                    int totalScore = paperList.stream().map(p -> p.getScore().intValue()).reduce((acc, item) -> acc + item).get();
                    if (totalScore > inspectRange.getCondition()) {
                        examNumbers.add(examNumber);
                    }
                });

                break;
            case DKFS:
                //根据单科分数查询
                group = papers.stream().collect(Collectors.groupingBy(Paper::getExamNumber));
                group.forEach((examNumber, paperList) -> {
                    int maxScore = paperList.stream().map(p -> p.getScore().intValue()).max(Integer::compareTo).get();
                    if (maxScore > inspectRange.getCondition()) {
                        examNumbers.add(examNumber);
                    }
                });

                break;
            case SYD:
                //根据生源地排名
                group = papers.stream().collect(Collectors.groupingBy(Paper::getSourceName));

                group.forEach((sourceName, paperList) -> {
                    Map<String, List<Paper>> examNumberList = paperList.stream().collect(Collectors.groupingBy(Paper::getExamNumber));

                    final List<Object[]> totalScoreList = new ArrayList<>();
                    examNumberList.forEach((examNumber, studentPaperList) -> {
                        int totalScore = studentPaperList.stream().map(p -> p.getScore().intValue()).reduce((acc, item) -> acc + item).get();
                        totalScoreList.add(new Object[]{examNumber, totalScore});
                    });

                    totalScoreList.sort((o1, o2) -> {
                        Integer t1 = (Integer) o1[1];
                        Integer t2 = (Integer) o2[1];
                        return t2.compareTo(t1);//分数从高到低排序
                    });

                    int studentCount = totalScoreList.size() > inspectRange.getCondition() ? inspectRange.getCondition() : totalScoreList.size();
                    for (int i = 0; i < studentCount; i++) {
                        Object examNumberInObject = totalScoreList.get(i)[0];
                        examNumbers.add((String) examNumberInObject);
                    }

                });
                break;
        }

        inspectRange.setActive(false);
        inspectRange.setEditable(true);
        if (inspectRange.getId() != null) {
            //如果是修改操作，要将先前标记的学生试卷改回来
//            paperRepo.resetInspectRange(inspectRange.getId());
            inspectStudentRepo.deleteByInspectRangeId(inspectRange.getId());
        }

        inspectRange.setStudentCount(examNumbers.size());
        InspectRange savedRange = inspectRangeRepo.save(inspectRange);


        if (examNumbers.size() > 0) {

            //再重新标记
            //paperRepo.markInspectRange(inspectRange.getId(), examNumbers);
            List<InspectStudent> inspectStudents = new ArrayList<>();
            for (String examNumber : examNumbers) {
                InspectStudent inspectStudent = new InspectStudent();
                inspectStudent.setExamNumber(examNumber);
                inspectStudent.setInspectRangeId(savedRange.getId());
                inspectStudents.add(inspectStudent);
            }
            inspectStudentRepo.save(inspectStudents);
        }

    }
}
