package com.qmth.teachcloud.mark.service.impl;

import java.util.*;

import javax.annotation.Resource;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.qmth.teachcloud.common.entity.MarkQuestion;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.mark.SubjectiveStatus;
import com.qmth.teachcloud.common.service.SysUserService;
import com.qmth.teachcloud.common.service.TeachcloudCommonService;
import com.qmth.teachcloud.mark.bean.mark.MarkConfigItem;
import com.qmth.teachcloud.mark.dto.mark.ScoreItem;
import com.qmth.teachcloud.mark.dto.mark.SpecialTagDTO;
import com.qmth.teachcloud.mark.dto.mark.manage.*;
import com.qmth.teachcloud.mark.entity.*;
import com.qmth.teachcloud.mark.enums.MarkTaskStatus;
import com.qmth.teachcloud.mark.service.*;

@Service
public class TaskServiceImpl implements TaskService {

    @Resource
    private MarkPaperService markPaperService;
    @Resource
    private MarkTaskService markTaskService;
    @Resource
    private MarkStudentService markStudentService;
    @Resource
    private MarkQuestionService markQuestionService;
    @Resource
    private MarkHeaderTrackService markHeaderTrackService;
    @Resource
    private MarkTrackService markTrackService;
    @Resource
    private MarkSubjectiveScoreService markSubjectiveScoreService;
    @Resource
    private TeachcloudCommonService teachcloudCommonService;
    @Resource
    private MarkGroupService markGroupService;
    @Resource
    private MarkHeaderTagService markHeaderTagService;
    @Resource
    private MarkSpecialTagService markSpecialTagService;
    @Resource
    private SysUserService sysUserService;

    @Override
    public Task build(MarkArbitrateHistory markArbitrateHistory, MarkGroup markGroup) {
        MarkStudent markStudent = markStudentService.getById(markArbitrateHistory.getStudentId());
        Task task = new Task();
        task.setStudentId(markArbitrateHistory.getStudentId());
        task.setTaskId(markArbitrateHistory.getId());
        task.setSecretNumber(markArbitrateHistory.getSecretNumber());
        task.setQuestionList(buildArbitrateStep(markGroup, markArbitrateHistory));
//        task.setSpecialTagList(getHeaderTagList(history.getStudentId(), group.getNumber()));
//        task.setJsonUrl(fileService.getJsonUri(student.getExamId(), student.getSecretNumber()));
        if (StringUtils.isNotBlank(markStudent.getObjectiveScoreList())) {
            task.setObjectiveScore(markStudent.getObjectiveScore());
        }
        if (StringUtils.isNotBlank(markStudent.getSheetPath())) {
            task.setSheetUrls(teachcloudCommonService.filePreview(markStudent.getSheetPathList()));
        }
        task.setMarkerTime(markArbitrateHistory.getUpdateTime());
        if (markArbitrateHistory.getTotalScore() != null) {
            task.setMarkerScore(markArbitrateHistory.getTotalScore());
        }
        if (StringUtils.isNotBlank(markGroup.getPicList())) {
            task.setSliceConfig(JSON.parseArray(markGroup.getPicList(), MarkConfigItem.class));
        }
        return task;
    }

    @Override
    public Task build(Long studentId) {
        MarkStudent markStudent = markStudentService.getById(studentId);
        Task task = new Task();
        if (markStudent != null) {
            task.setStudentId(markStudent.getId());
            task.setSecretNumber(markStudent.getSecretNumber());
            task.setStudentCode(markStudent.getStudentCode());
            task.setStudentName(markStudent.getStudentName());
            task.setCourseCode(markStudent.getCourseCode());
            task.setCourseName(markStudent.getCourseName());
            task.setPaperNumber(markStudent.getPaperNumber());

            // 原图
//            task.setSheetUrls(teachcloudCommonService.filePreview(markStudent.getSheetPathList()));
            task.setSheetUrls(teachcloudCommonService.fileMarkPreview(markStudent.getSheetPathList()));

            if (!markStudent.getSubjectiveStatus().equals(SubjectiveStatus.UNMARK)) {
                task.setQuestionList(buildMarkStep(markStudent));
                task.setSpecialTagList(getMarkSpecialTagList(markStudent));
                task.setHeaderTagList(getHeaderTagList(markStudent));
            }
            if (StringUtils.isNotBlank(markStudent.getObjectiveScoreList())) {
                task.setObjectiveScore(markStudent.getObjectiveScore());
            }
            task.setMarkerScore(markStudent.getTotalScore());
            return task;
        }
        return task;
    }

    private List<MarkStepDTO> buildMarkStep(MarkStudent markStudent) {
        Long examId = markStudent.getExamId();
        String paperNumber = markStudent.getPaperNumber();
        List<MarkStepDTO> list = new LinkedList<MarkStepDTO>();
        List<MarkQuestion> sList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(examId,
                paperNumber, null, false);
        Set<Integer> mainList = markSubjectiveScoreService.listMainNumberByStudentIdAndUncalculate(markStudent.getId(),
                true);
        List<MarkSubjectiveScore> scoreList = markSubjectiveScoreService
                .listByStudentIdAndGroupNumber(markStudent.getId(), null);
        for (int i = 0; i < scoreList.size(); i++) {
            MarkQuestion question = sList.get(i);
            String questionNumber = question.getQuestionNumber();
            MarkStepDTO step = buildStep(question);
            if (!scoreList.isEmpty() && scoreList.size() == sList.size()) {
                step.setScore(scoreList.get(i).getScore());
                if (mainList.contains(step.getMainNumber())) {
                    step.setUncalculate(true);
                }
            }
            // 增加阅卷轨迹列表获取
            List<MarkTask> markTaskList = markTaskService.listByStudentIdAndGroupNumber(markStudent.getId(), question.getGroupNumber());
            // 仲裁轨迹
            List<MarkHeaderTrack> headerTracks = markHeaderTrackService.listByStudentIdAndQuestionNumber(markStudent.getId(), questionNumber);
            List<String> questionList = new ArrayList<>();
            Map<Long,String> userNameMap = new HashMap<>();
            // 不管单评还是多评显示所有评卷员给分轨迹
            for (MarkTask markTask : markTaskList) {
                List<MarkTrack> tracks = markTrackService.listByTaskIdAndQuestionNumber(markTask.getId(), questionNumber);
                if (!questionList.contains(questionNumber)) {
                    questionList.add(questionNumber);
                } else if (CollectionUtils.isNotEmpty(headerTracks)) {
                    continue;
                }
                for (MarkTrack track : tracks) {
//                    step.addTrack(new MarkerTrackDTO(track));
                    if(userNameMap.get(track.getUserId())==null){
                        SysUser user = sysUserService.getByUserId(track.getUserId());
                        userNameMap.put(track.getUserId(),user.getRealName()+"("+user.getLoginName()+")");
                    }
                    step.addTrack(replaceTrackFromHeaderTrack(track, headerTracks,userNameMap));
                }
            }
            for (MarkHeaderTrack headerTrack : headerTracks) {
                step.addHeaderTrack(new TrackDTO(headerTrack));
            }
            list.add(step);
        }
        return list;
    }

    private MarkerTrackDTO replaceTrackFromHeaderTrack(MarkTrack markTrack, List<MarkHeaderTrack> headerTracks,Map<Long,String> userNameMap) {
        MarkerTrackDTO markerTrackDTO = new MarkerTrackDTO(markTrack,userNameMap.get(markTrack.getUserId()));
        if (CollectionUtils.isNotEmpty(headerTracks)) {
            Optional<MarkHeaderTrack> optional = headerTracks.stream().filter(m -> m.getStudentId().equals(markTrack.getStudentId()) && m.getQuestionNumber().equals(markTrack.getQuestionNumber())).findFirst();
            if (optional.isPresent()) {
                MarkHeaderTrack markHeaderTrack = optional.get();
                markerTrackDTO = new MarkerTrackDTO(markHeaderTrack,userNameMap.get(markHeaderTrack.getUserId()));
            }
        }
        return markerTrackDTO;
    }

    private List<MarkStepDTO> buildArbitrateStep(MarkGroup group, MarkArbitrateHistory markArbitrateHistory) {
        List<MarkStepDTO> list = new LinkedList<>();
        List<MarkQuestion> markQuestionList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(
                group.getExamId(), group.getPaperNumber(), group.getNumber(), false);
        List<MarkHeaderTrack> tracks = markHeaderTrackService.listByExamAndPaperNumberAndGroupNumberAndStudentId(
                group.getExamId(), group.getPaperNumber(), group.getNumber(), markArbitrateHistory.getStudentId());
        List<ScoreItem> sItems = new ArrayList<ScoreItem>();
        if (markArbitrateHistory != null) {
            sItems = markArbitrateHistory.getScoreItemList();
        }
        for (int i = 0; i < markQuestionList.size(); i++) {
            MarkQuestion question = markQuestionList.get(i);
            MarkStepDTO step = buildStep(question);
            if (markArbitrateHistory != null) {
                if (!sItems.isEmpty() && sItems.size() == markQuestionList.size()) {
                    step.setScore(sItems.get(i).getScore());
                }
                // 增加阅卷轨迹列表获取
                String questionNumber = question.getQuestionNumber();
                for (MarkHeaderTrack track : tracks) {
                    if (track.getQuestionNumber().equals(questionNumber)) {
                        step.addTrack(new TrackDTO(track));
                    }
                }
            }
            list.add(step);
        }
        return list;
    }

    private MarkStepDTO buildStep(MarkQuestion question) {
        MarkStepDTO step = new MarkStepDTO();
        step.setMainNumber(question.getMainNumber());
        step.setSubNumber(String.valueOf(question.getSubNumber()));
        step.setGroupNumber(question.getGroupNumber());
        step.setTitle(question.getMainTitle());
        step.setDefaultScore(0d);
        step.setMaxScore(question.getTotalScore());
        step.setMinScore(0d);
        step.setIntervalScore(question.getIntervalScore());
        step.setUncalculate(false);
        return step;
    }

    @Override
    public Task build(MarkTask t) {
        Task task = new Task();
        task.setTaskId(t.getId());
        task.setGroupNumber(task.getGroupNumber());
        task.setSecretNumber(t.getSecretNumber());
        task.setMarkerTime(t.getMarkerTime());
        task.setPaperNumber(t.getPaperNumber());
        task.setMarkerScore(t.getMarkerScore());
        task.setRejected(t.getStatus().equals(MarkTaskStatus.REJECTED));
        task.setPrevious(t.getStatus().equals(MarkTaskStatus.MARKED));
        task.setStudentId(t.getStudentId());
        task.setStudentCode(t.getStudentCode());
        task.setQuestionList(buildMarkStep(t));
        task.setSpecialTagList(getMarkSpecialTagList(t));
        MarkStudent student = markStudentService.getById(t.getStudentId());
//        task.setSheetUrls(teachcloudCommonService.filePreview(student.getSheetPathList()));
        task.setSheetUrls(teachcloudCommonService.fileMarkPreview(student.getSheetPathList()));
        MarkGroup group = markGroupService.getByExamIdAndPaperNumberAndGroupNumber(t.getExamId(), t.getPaperNumber(),
                t.getGroupNumber());
        task.setSliceConfig(group.getPictureConfigList());
        MarkPaper markPaper = markPaperService.getByExamIdAndPaperNumber(t.getExamId(), t.getPaperNumber());
        task.setObjectiveScore(markPaper.getShowObjectScore() ? student.getObjectiveScore() : null);
        return task;
    }

    private List<MarkStepDTO> buildMarkStep(MarkTask task) {
        List<MarkStepDTO> list = new LinkedList<MarkStepDTO>();
        List<MarkQuestion> sList = markQuestionService.listQuestionByExamIdAndPaperNumberAndGroupNumber(
                task.getExamId(), task.getPaperNumber(), task.getGroupNumber(), false);
        List<MarkTrack> tracks = new ArrayList<MarkTrack>();
        List<ScoreItem> sItems = new ArrayList<ScoreItem>();
//		List<ScoreItem> rItems = null;
        if (task != null) {
            tracks = markTrackService.listByTaskId(task.getId());
            sItems = task.getMarkerScoreItem();
        }
        for (int i = 0; i < sList.size(); i++) {
            MarkQuestion question = sList.get(i);
            MarkStepDTO step = buildStep(question);
            if (task != null) {
                if (!sItems.isEmpty() && sItems.size() == sList.size()) {
                    step.setScore(sItems.get(i).getScore());
                }
//				if (rItems == null) {
//					// 无打回记录
//					step.setRejected(false);
//				} else if (rItems != null && rItems.isEmpty()) {
//					// 全打回
//					step.setRejected(true);
//				} else if (rItems != null && !rItems.isEmpty() && rItems.size() == sList.size()) {
//					// 部分打回
//					step.setRejected(rItems.get(i).getScore() == null);
//				}
                // 未选做
//                if (task.getMarkerScore() != null && task.getMarkerScore() == UN_SELECTIVE_SCORE) {
//                    step.setScore(UN_SELECTIVE_SCORE);
//                }
                // 增加阅卷轨迹列表获取
                String questionNumber = question.getQuestionNumber();
                for (MarkTrack track : tracks) {
                    if (track.getQuestionNumber().equals(questionNumber)) {
                        step.addTrack(new TrackDTO(track));
                    }
                }
            }
            list.add(step);
        }
        return list;
    }

    private SpecialTagDTO[] getHeaderTagList(MarkStudent student) {
        List<MarkHeaderTag> list = markHeaderTagService.findByStudentId(student.getId());
        SpecialTagDTO[] specialTags = new SpecialTagDTO[list.size()];
        for (int i = 0; i < list.size(); i++) {
            specialTags[i] = new MarkerSpecialTagDTO(list.get(i).getUserId(), list.get(i).getGroupNumber(),
                    list.get(i));
        }
        return specialTags;
    }

    public SpecialTagDTO[] getMarkSpecialTagList(MarkTask library) {
        SpecialTagDTO[] specialTags = null;
        List<MarkSpecialTag> list = markSpecialTagService.findByTaskId(library.getId());
        if (!list.isEmpty()) {
            specialTags = new SpecialTagDTO[list.size()];
            for (int i = 0; i < list.size(); i++) {
                SpecialTagDTO specialTagDTO = new SpecialTagDTO(list.get(i));
                specialTags[i] = specialTagDTO;
            }
        }
        return specialTags;
    }

    private SpecialTagDTO[] getMarkSpecialTagList(MarkStudent student) {
        List<SpecialTagDTO> list = new LinkedList<>();
        List<MarkGroup> groups = markGroupService.listGroupByExamIdAndPaperNumber(student.getExamId(),
                student.getPaperNumber());
        for (MarkGroup group : groups) {
            List<MarkTask> libraryList = markTaskService.listByStudentIdAndGroupNumber(student.getId(),
                    group.getNumber());
            // 不管单评还是多评显示所有评卷员特殊标记
            for (MarkTask library : libraryList) {
                List<MarkSpecialTag> tagList = markSpecialTagService.findByTaskId(library.getId());
                for (MarkSpecialTag specialTag : tagList) {
                    list.add(new MarkerSpecialTagDTO(library.getUserId(), library.getGroupNumber(), specialTag));
                }
            }
        }
        return list.toArray(new SpecialTagDTO[0]);
    }
}
