package com.ssj.service.sys.homework.service.impl;

import com.alibaba.fastjson.JSON;
import com.ssj.bean.kmt.kmt.domain.KmtExerciseBookCourse;
import com.ssj.bean.kmt.kmt.domain.KmtExerciseQuestion;
import com.ssj.bean.kmt.kmt.domain.KmtHomeworkWrongQuestion;
import com.ssj.bean.sys.homework.domain.Homework;
import com.ssj.bean.sys.homework.domain.HomeworkPicture;
import com.ssj.bean.weixin.zyb.domain.ZuoybStudentPush;
import com.ssj.conch.constant.CourseConstant;
import com.ssj.conch.util.enums.HomeworkWrongQuestionTypeEnum;
import com.ssj.dao.sys.homework.dao.HomeworkDao;
import com.ssj.dao.sys.homework.dao.HomeworkQueryDao;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.security.manager.TokenManager;
import com.ssj.framework.weixin.util.DateUtil;
import com.ssj.service.conch.parents.dto.WrongQuestionTempDTO;
import com.ssj.service.conch.parents.v1.dto.CorrectDetailDto4;
import com.ssj.service.conch.parents.v1.dto.HomeworkCommentDto2;
import com.ssj.service.conch.parents.v1.dto.HomeworkPictureDto;
import com.ssj.service.conch.student.dto.RelateKnowledgeDto;
import com.ssj.service.kmt.service.KmtExerciseBookCourseService;
import com.ssj.service.kmt.service.KmtExerciseQuestionService;
import com.ssj.service.kmt.service.KmtHomeworkWrongQuestionService;
import com.ssj.service.mapper.HomeworkMapper;
import com.ssj.service.sys.homework.service.HomeworkPictureService;
import com.ssj.service.sys.homework.service.HomeworkService;
import com.ssj.service.sys.template.CommentTemplateMapperService;
import com.ssj.service.weixin.zuoyb.service.ZuoybStudentPushSerivce;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author sh
 * @className HomeworkServiceImpl
 * @description TODO
 * @date 2020/7/14
 */
@Service
@Transactional
public class HomeworkServiceImpl extends BaseServiceImpl<Homework, String> implements HomeworkService {

    @Autowired
    private HomeworkDao homeworkDao;
    @Autowired
    private HomeworkQueryDao homeworkQueryDao;

    @Autowired
    private TokenManager tokenManager;

    @Autowired
    private HomeworkMapper homeworkMapper;

    @Autowired
    private HomeworkPictureService homeworkPictureService;

    @Autowired
    private ZuoybStudentPushSerivce pushService;

    @Autowired
    private KmtHomeworkWrongQuestionService kmtHomeworkWrongQuestionService;

    @Autowired
    private CommentTemplateMapperService commentTemplateMapperService;

    @Autowired
    private KmtExerciseQuestionService kmtExerciseQuestionService;

    @Autowired
    private KmtExerciseBookCourseService kmtExerciseBookCourseService;

    @Override
    public PagingAndSortingRepository<Homework, String> getDao() {
        return homeworkDao;
    }

    @Override
    public Page<Map<String, Object>> findHomeworkByPage(Map<String, Object> searchParam, Pageable pageable) {
        return homeworkQueryDao.findHomeworkByPage(searchParam, pageable);
    }

    /**
     * 查询缓存中的批改详情
     * @param vipId
     * @param subject
     * @param date
     * @return
     */
    @Override
    public CorrectDetailDto4 getRedisCorrectDetail (String vipId, String subject, Date date){
        //超过14点，昨天的批改详情可以查询缓存，今日的详情不查询缓存
        CorrectDetailDto4 temp = null;
        if (DateUtil.compareDate(date, DateUtil.parse_yyyyMMdd(getQueryBeginDate()))){
            temp = tokenManager.get(this.getCorrectDetailRedisKey(vipId, subject, date), CorrectDetailDto4.class);
        }
        return temp;
    }

    /**
     * 查询单科批改详情的redis key
     * @param vipId
     * @param subject
     * @param date
     * @return
     */
    private String getCorrectDetailRedisKey (String vipId, String subject, Date date){
        StringBuilder redisKey = new StringBuilder();
        redisKey.append(vipId).append("_correctDetail").append("_")
                .append(CourseConstant.getAllSubjectList().indexOf(subject))
                .append("_").append(DateUtil.format_yyyyMMdd(date));
        return redisKey.toString();
    }

    /**
     * 获取查询作业列表的开始时间
     * @return
     */
    private String getQueryBeginDate(){
        String beginTime;
        if (DateUtil.getHour(new Date()) < 14) {
            beginTime=DateUtil.format_yyyyMMdd(DateUtil.addDays(new Date(), -1));
        } else {
            beginTime=DateUtil.format_yyyyMMdd(DateUtil.getTodatDate());
        }
        return beginTime;
    }

    @Override
    public Homework findDateSubjectHomework(String vipId, String subject, Date dateTime) {
        String formateDate = DateUtil.format_yyyyMMdd(dateTime);
        return homeworkDao.findByVipIdAndSubjectAndRangTime(vipId, subject, formateDate, formateDate + " 23:59:59");
    }

    public String getHomeworkTime(Homework homework) {
        String homeworkTime = "";
        if (homework.getUsedTime() != null && homework.getUsedTime() > 0) {
            Date startTime = homework.getStartTime();
            Date endTime = homework.getEndTime();
            if (startTime != null && endTime != null) {
                if (startTime.getTime() == endTime.getTime()) {
                    return homeworkTime;
                }
                homeworkTime = DateUtil.format_HHmm(startTime) + "-" + DateUtil.format_HHmm(endTime);
            }
        }
        return homeworkTime;
    }


    @Transactional
    public Integer isCorrected(String homeworkId) {
        List<HomeworkPicture> homeworkPictureList = homeworkPictureService.findAllByHomeworkId(homeworkId);

        //如果存在非模糊的未批改图片，则视为作业未批改
        if (homeworkPictureList.stream().anyMatch(it -> !Objects.equals(1, it.getIsDelete()) &&
                !Objects.equals(1, it.getIsMark()) &&
                !Objects.equals(3, it.getIsMark()) &&
                Objects.equals(0, it.getIsFeedback()))) {
            return 0;
        }

        return 1;
    }

    @Override
    public CorrectDetailDto4 getCorrectDetailDto4(Homework homework) {
        if (homework == null || homework.getWorkType() == null || homework.getWorkType() == 3) {
            return null;
        }
        CorrectDetailDto4 temp = null;
        List<HomeworkPicture> homeworkPictureList = homeworkMapper.findHomeworkCorrectDetailByHomeworkId(homework.getId());
        String redisKey = this.getCorrectDetailRedisKey(homework.getVipId(), homework.getSubject(), homework.getCreateTime());
        if (CollectionUtils.isEmpty(homeworkPictureList)) {
            return null;
        }

        temp = new CorrectDetailDto4();
        temp.setSubject(homework.getSubject());
        temp.setHomeworkId(homework.getId());
        temp.setHomeworkTime(this.getHomeworkTime(homework));
        if (CollectionUtils.isNotEmpty(homeworkPictureList)) {
            temp.setCorrectTeacherId(homeworkPictureList.get(0).getTeacherId());
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        boolean existCorrectedPicture = homeworkPictureList.stream().anyMatch(it -> Objects.equals(it.getIsFeedback(), 1) || Objects.equals(it.getIsMark(), 1) || Objects.equals(it.getIsMark(), 3));
        if (Objects.equals(simpleDateFormat.format(new Date()), simpleDateFormat.format(homework.getCreateTime()))) {
            temp.setCorrectionStatus(this.isCorrected(homework.getId()));

            //如果是未批改，需要判断是否是补拍的情况
            if (Objects.equals(0, temp.getCorrectionStatus()) && homework.getCorrectTime() != null) {
                temp.setCorrectionStatus(2);
            } else if (existCorrectedPicture) {
                temp.setCorrectionStatus(1);
            }
        } else {
            if (homework.getCorrectTime() != null && Objects.equals(0, this.isCorrected(homework.getId()))) {
                //补拍的情况下
                temp.setCorrectionStatus(2);
            } else {
                //普通情况下，历史记录中的批改详情，只要有一张图片批改了，那就认为本次作业已批改
                if (existCorrectedPicture) {
                    temp.setCorrectionStatus(1);
                } else {
                    temp.setCorrectionStatus(0);
                }
            }
        }

        //作业登记、原图列表及批注列表
        List<HomeworkPictureDto> homeworkPictureDtoList = new LinkedList<>();
        List<HomeworkCommentDto2> homeworkCommentDtoList = new LinkedList<>();
        ZuoybStudentPush zuoybStudentPush = pushService.findByVipIdAndDate(homework.getVipId(), DateUtil.format_yyyyMMddHHmmss(homework.getCreateTime()));
        if (zuoybStudentPush != null) {
            String enrollmentImgStr = zuoybStudentPush.getImg();
            if (StringUtils.isNotBlank(enrollmentImgStr)) {
                Arrays.asList(enrollmentImgStr.split(",")).forEach(enrollmentImg -> {
                    HomeworkPictureDto homeworkPictureDto = new HomeworkPictureDto();
                    homeworkPictureDto.setHomeworkPictureUrl(enrollmentImg);
                    homeworkPictureDto.setIsVague(0);
                    homeworkPictureDto.setStatus(3);
                    homeworkPictureDtoList.add(homeworkPictureDto);
                });
            }
        }
        homeworkPictureList.forEach(homeworkPicture -> {
            HomeworkPictureDto homeworkPictureDto = new HomeworkPictureDto();
            homeworkPictureDto.setHomeworkPictureId(homeworkPicture.getId());
            homeworkPictureDto.setHomeworkPictureUrl(homeworkPicture.getFileKey());
            homeworkPictureDto.setIsVague(homeworkPicture.getIsMark() == 1 ? 1:  homeworkPicture.getIsMark() == 3 ?4: 0);
            if (homework.getCorrectTime() != null
                    && Objects.equals(0, homeworkPicture.getIsFeedback())
                    && !Objects.equals(1, homeworkPicture.getIsMark())
                    && !Objects.equals(3, homeworkPicture.getIsMark())) {
                homeworkPictureDto.setStatus(2);
            } else {
                int status = homeworkPicture.getIsMark() > 0 && homeworkPicture.getIsMark() != 2
                        ? homeworkPicture.getIsMark() == 3 ? 4 : homeworkPicture.getIsMark() : 0;
                homeworkPictureDto.setStatus(status);
            }
            homeworkPictureDtoList.add(homeworkPictureDto);

            String correctedPictureUrl = homeworkPicture.getCorrectedPictureUrl();
            if (StringUtils.isNotBlank(correctedPictureUrl)) {
                HomeworkCommentDto2 homeworkCommentDto = new HomeworkCommentDto2();
                homeworkCommentDto.setHomeworkCommentUrl(correctedPictureUrl);
                homeworkCommentDto.setIsComposition(homeworkPicture.getIsComposition());
                if (homeworkPicture.getIsComposition() == 1) {
                    //有作文，查询作文评语
                    homeworkCommentDto.setCompositionCommentModuleList(commentTemplateMapperService.getCompositionCommentModuleDTOList(homeworkPicture.getId()));
                }
                if(StringUtils.isNotBlank(homeworkPicture.getHomeworkComment())){
                    homeworkCommentDto.setHomeworkComment(homeworkPicture.getHomeworkComment());
                }
                homeworkCommentDtoList.add(homeworkCommentDto);
            }

        });
        temp.setHomeworkList(homeworkPictureDtoList);
        temp.setHomeworkCommentList(homeworkCommentDtoList);

        //查询错题和未完成的题目
        Map<String, String> wrongQuestionAndDetails = tokenManager.hget("correctDetail_part_" + homework.getId());
        if (wrongQuestionAndDetails != null && !wrongQuestionAndDetails.isEmpty()){
            temp.setWrongItemList(JSON.parseObject(wrongQuestionAndDetails.get("wrong_questions"), List.class));
            temp.setRelateKnowledgeList(JSON.parseObject(wrongQuestionAndDetails.get("wrong_details"), List.class));
        } else {
            temp.setWrongItemList(this.findWrongQuestionAndSetRedis(homework.getId()));
            //错题知识点列表
            temp.setRelateKnowledgeList(this.findWrongHowDetailAndSetRedis(homework.getId()));
        }

        //未完成内容列表
        if (StringUtils.isNotBlank(homework.getUnFinishedContent())) {
            temp.setUnfinishedList(Arrays.asList(homework.getUnFinishedContent().split(",")));
        } else {
            temp.setUnfinishedList(new ArrayList<>());
        }
        if (DateUtil.compareDate(homework.getCreateTime(), DateUtil.parse_yyyyMMdd(getQueryBeginDate()))){
            tokenManager.set(redisKey, temp, 90 * 24 * 3600);
        }
        return temp;
    }


    public List<Map<String, Object>> findWrongQuestionAndSetRedis(String homeworkId) {
        List<Map<String, Object>> wrongQuestionListGroupByBook = new ArrayList<>();
        List<KmtHomeworkWrongQuestion> kmtHomeworkWrongQuestionList = kmtHomeworkWrongQuestionService.findByHomeworkId(homeworkId);
        if (CollectionUtils.isNotEmpty(kmtHomeworkWrongQuestionList)) {
            List<KmtHomeworkWrongQuestion> wrongQuestionList = kmtHomeworkWrongQuestionList.stream().filter(it -> it.getType().equals(HomeworkWrongQuestionTypeEnum.WrongAnswer.getCode())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(wrongQuestionList)) {//有错题
                Set<String> wrongQuestionIdSet = wrongQuestionList.stream().map(KmtHomeworkWrongQuestion::getQuestionId).filter(Objects::nonNull).collect(Collectors.toSet());
                List<KmtExerciseQuestion> kmtExerciseQuestionList = kmtExerciseQuestionService.findByIdIn(new ArrayList<>(wrongQuestionIdSet));
                Map<String, List<KmtExerciseQuestion>> kmtExerciseQuestionMapGroupByBook = kmtExerciseQuestionList.stream().collect(Collectors.groupingBy(KmtExerciseQuestion::getBookId));
                kmtExerciseQuestionMapGroupByBook.forEach((key, value) -> {
                    List<WrongQuestionTempDTO> wrongQuestionDTOList = new ArrayList<>();
                    Map<String, List<KmtExerciseQuestion>> kmtExerciseQuestionMap = value.stream().collect(Collectors.groupingBy(KmtExerciseQuestion::getBookCourseId));
                    final String[] bookName = {""};
                    kmtExerciseQuestionMap.forEach((key2, value2) -> {
                        value2.sort((o1, o2) -> {
                            Integer num1 = o1.getNum();
                            if (num1 == null) {
                                return -1;
                            }
                            Integer num2 = o2.getNum();
                            if (num2 == null) {
                                return 1;
                            }
                            return num1.compareTo(num2);
                        });

                        KmtExerciseBookCourse kmtExerciseBookCourse = kmtExerciseBookCourseService.getById(key2);
                        if (StringUtils.isBlank(bookName[0])) {
                            bookName[0] = kmtExerciseBookCourse.getBookName();
                        }

                        WrongQuestionTempDTO wrongQuestionDTO = new WrongQuestionTempDTO();
                        wrongQuestionDTO.setUnit(kmtExerciseBookCourse.getUnit());
                        wrongQuestionDTO.setPeriod(kmtExerciseBookCourse.getPeriod());
                        List<Map<String, Object>> questionList = new ArrayList<>();
                        value2.forEach(kmtExerciseQuestion -> {
                            Map<String, Object> questionMap = new HashMap<>();
                            questionMap.put("bigQuestionIndex", kmtExerciseQuestion.getBigQuestionIndex());
                            String smallQuestionName = kmtExerciseQuestion.getSmallQuestionName();
                            if (Objects.equals("(0)", smallQuestionName)) {
                                smallQuestionName = "0";
                            }
                            questionMap.put("smallQuestionIndex", smallQuestionName);
                            Optional<KmtHomeworkWrongQuestion> optional = wrongQuestionList.stream().filter(it -> Objects.equals(it.getQuestionId(), kmtExerciseQuestion.getId())).findFirst();
                            String spaceIndex = "";
                            if (optional.isPresent()) {
                                KmtHomeworkWrongQuestion kmtHomeworkWrongQuestion = optional.get();
                                spaceIndex = kmtHomeworkWrongQuestion.getSpaceIndex();
                            }
                            questionMap.put("spaceIndex", spaceIndex == null ? "" : spaceIndex);
                            questionList.add(questionMap);
                        });
                        wrongQuestionDTO.setQuestionList(questionList);
                        wrongQuestionDTOList.add(wrongQuestionDTO);
                    });

                    Map<String, Object> tempMap = new HashMap<>();
                    tempMap.put("bookName", bookName[0]);
                    tempMap.put("bookCourseList", wrongQuestionDTOList);
                    tempMap.put("wrongQuestionNum", value.size());
                    wrongQuestionListGroupByBook.add(tempMap);
                });
                Map<String, String> data = new HashMap<>();
                data.put("wrong_questions", JSON.toJSONString(wrongQuestionListGroupByBook));
                tokenManager.hset("correctDetail_part_" + homeworkId, data, 48 * 3600);
            }
        }
        return wrongQuestionListGroupByBook;
    }


    public List<RelateKnowledgeDto> findWrongHowDetailAndSetRedis(String homeworkId) {
        List<RelateKnowledgeDto> relateKnowledgeDtoList = new ArrayList<>();
        List<Map<String, Object>> howDetailsMapList = new ArrayList<>(homeworkQueryDao.findDetailsByHomeworkId(homeworkId));
        if (CollectionUtils.isNotEmpty(howDetailsMapList)) {
            howDetailsMapList.forEach(howDetailsMap -> {
                String module = String.valueOf(howDetailsMap.get("module"));
                Optional<RelateKnowledgeDto> optional = relateKnowledgeDtoList.stream().filter(it -> Objects.equals(it.getModule(), module)).findFirst();
                String alias = String.valueOf(howDetailsMap.get("alias"));
                if (optional.isPresent()) {
                    RelateKnowledgeDto relateKnowledgeDto = optional.get();
                    List<String> details = relateKnowledgeDto.getDetails();
                    if (details.contains(alias)) {
                        return;
                    }
                    details.add(alias);
                } else {
                    RelateKnowledgeDto relateKnowledgeDto = new RelateKnowledgeDto();
                    relateKnowledgeDto.setModule(module);
                    List<String> tempAliasList = new ArrayList<>();
                    tempAliasList.add(alias);
                    relateKnowledgeDto.setDetails(tempAliasList);
                    relateKnowledgeDtoList.add(relateKnowledgeDto);
                }
            });
            Map<String, String> data = new HashMap<>();
            data.put("wrong_details", JSON.toJSONString(relateKnowledgeDtoList));
            tokenManager.hset("correctDetail_part_" + homeworkId, data, 48 * 3600);
        }
        return relateKnowledgeDtoList;
    }
}
