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

import com.alibaba.dubbo.config.annotation.Service;
import com.ssj.bean.sys.teacher.domain.OnlineTeacherWeight;
import com.ssj.bean.sys.teacher.domain.TeacherWeightRule;
import com.ssj.bean.weixin.libmy.domain.LibVip;
import com.ssj.bean.weixin.libmy.domain.TbLibManager;
import com.ssj.dao.sys.homework.dao.HomeworkQueryDao;
import com.ssj.dao.sys.teacher.dao.OnlineTeacherWeightDao;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.security.manager.TokenManager;
import com.ssj.service.kmt.arrange.service.KmtArrangeAllotService;
import com.ssj.service.sys.teacher.OnlineTeacherWeightService;
import com.ssj.service.sys.teacher.TeacherWeightRuleService;
import com.ssj.service.weixin.library.service.IBookManagerService;
import com.ssj.service.weixin.library.service.ILibVipService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 *
 * @author yrf
 * @date 2019/5/9 10:43
 */
@Service(version = "1.0")
@Transactional
public class OnlineTeacherWeightServiceImpl extends BaseServiceImpl<OnlineTeacherWeight, String> implements OnlineTeacherWeightService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private OnlineTeacherWeightDao onlineTeacherWeightDao;
    @Autowired
    private HomeworkQueryDao homeworkQueryDao;
    @Autowired
    private TeacherWeightRuleService teacherWeightRuleService;
    @Autowired
    private IBookManagerService bookManagerService;
    @Autowired
    private ILibVipService libVipService;
    @Autowired
    private TokenManager tokenManager;
    @Autowired
    private KmtArrangeAllotService kmtArrangeAllotService;

    @Override
    public PagingAndSortingRepository<OnlineTeacherWeight, String> getDao() {
        return onlineTeacherWeightDao;
    }

    @Override
    public long computeAndSaveWeight() {
        int pageNo = 1;
        int pageSize = 500;
        boolean hasNextPage = true;
        int pageCount = -1;
        final long[] computeCount = {0L};

        do {
            //查询老师的旧分配权重记录
            Page<OnlineTeacherWeight> onlineTeacherWeightPage = onlineTeacherWeightDao.findAll(new PageRequest(pageNo - 1, pageSize));

            List<OnlineTeacherWeight> onlineTeacherWeightList = onlineTeacherWeightPage.getContent();
            if (CollectionUtils.isNotEmpty(onlineTeacherWeightList)) {
                //重新计算分配权重
                onlineTeacherWeightList.forEach(onlineTeacherWeight -> {
                    //查询分配作业总数权重规则
                    TeacherWeightRule teacherWeightRule4HomeworkSum = teacherWeightRuleService.findByTypeAndGradeAndValue(1, onlineTeacherWeight.getGrade(), new BigDecimal(onlineTeacherWeight.getSumHomework()));
                    if (teacherWeightRule4HomeworkSum == null) {
                        //未查询到对应规则，跳过此次权重计算
                        return;
                    }

                    //查询前一天批改作业图片数量和总用时，若是第一次计算则查询之前所有数据，计算批改平均用时
                    BigDecimal oldAveCorrectTime = Optional.ofNullable(onlineTeacherWeight.getAveCorrectTime()).orElse(BigDecimal.ZERO);
                    LocalDate todayDate = LocalDate.now();
                    String lastDayDateStr = todayDate.minusDays(1).format(DateTimeFormatter.ISO_LOCAL_DATE);
                    String beginTimeStr = null;
                    String endTimeStr = lastDayDateStr + " 23:59:59";
                    if (oldAveCorrectTime.compareTo(BigDecimal.ZERO) > 0) {
                        beginTimeStr = lastDayDateStr + " 00:00:00";
                    }
                    List<Map<String, Object>> homeworkPictureSumAndUsedTimeList = homeworkQueryDao.countCorrectedHomeworkPictureSumAndUsedTime(onlineTeacherWeight.getTeacherId(), beginTimeStr, endTimeStr);
                    if (CollectionUtils.isNotEmpty(homeworkPictureSumAndUsedTimeList)) {
                        Map<String, Object> homeworkPictureSumAndUsedTimeMap = homeworkPictureSumAndUsedTimeList.get(0);
                        int pictureSum = Integer.valueOf(Optional.ofNullable(homeworkPictureSumAndUsedTimeMap.get("picture_sum")).orElse(-1).toString());
                        int correctionTime = Integer.valueOf(Optional.ofNullable(homeworkPictureSumAndUsedTimeMap.get("correction_time")).orElse(-1).toString());
                        if (pictureSum > 0 && correctionTime > 0) {
                            BigDecimal newAveCorrectTime = new BigDecimal(correctionTime / 60.0 / pictureSum);
                            if (oldAveCorrectTime.compareTo(BigDecimal.ZERO) > 0) {
                                //计算最新平均批改用时，四舍五入保留2位小数
                                BigDecimal finalAveCorrectTime = (newAveCorrectTime.add(oldAveCorrectTime)).divide(new BigDecimal("2"), 2, BigDecimal.ROUND_HALF_UP);
                                onlineTeacherWeight.setAveCorrectTime(finalAveCorrectTime);
                            } else {
                                onlineTeacherWeight.setAveCorrectTime(newAveCorrectTime);
                            }
                        }
                    }
                    //查询批改速度权重规则
                    TeacherWeightRule teacherWeightRule4CorrectSpeed = teacherWeightRuleService.findByTypeAndGradeAndValue(2, null, onlineTeacherWeight.getAveCorrectTime());
                    if (teacherWeightRule4CorrectSpeed == null) {
                        //未查询到对应规则，跳过此次权重计算
                        return;
                    }

                    //查询老师评分权重规则
                    TbLibManager libManager = bookManagerService.findByUserIdAndType(onlineTeacherWeight.getTeacherId(), 8);
                    if (libManager == null) {
                        return;
                    }
                    TeacherWeightRule teacherWeightRule4Score = teacherWeightRuleService.findByTypeAndGradeAndValue(3, null, new BigDecimal(String.valueOf(libManager.getPraise())));
                    if (teacherWeightRule4Score == null) {
                        //未查询到对应规则，跳过此次权重计算
                        return;
                    }

                    //计算并保存新权重
                    BigDecimal newWeight = teacherWeightRule4HomeworkSum.getWeight().add(teacherWeightRule4CorrectSpeed.getWeight()).add(teacherWeightRule4Score.getWeight());
                    onlineTeacherWeight.setWeight(newWeight);

                    computeCount[0] ++;
                });

                onlineTeacherWeightDao.save(onlineTeacherWeightList);
            }

            if (pageCount < 0) {
                pageCount = onlineTeacherWeightPage.getTotalPages();
            }
            if (pageNo >= pageCount) {
                //已没有下一页
                hasNextPage = false;
            } else {
                pageNo ++;
            }
        } while (hasNextPage);

        return computeCount[0];
    }

    @Override
    public void updateRealTimeWeightAndHomeworkSum(String vipId, TbLibManager correctTeacher, int pictureSum) {
        if (pictureSum == 0) {
            logger.info("需要更新的图片数量不正确：pictureSum={}", pictureSum);
            return;
        }

        if (StringUtils.isBlank(vipId) || null == correctTeacher) {
            logger.info("学生id为空或批改老师分配记录为空");
            return;
        }

        LibVip libVip = libVipService.getById(vipId);
        if (libVip == null) {
            logger.info("学生不存在，vipId={}", vipId);
            return;
        }

        //更新批改图片总数
        String teacherId = correctTeacher.getUserId();
        String school = libVip.getSchool();
        String grade = libVip.getGrade();
        OnlineTeacherWeight onlineTeacherWeight = this.findTopByTeacherIdAndSchoolNameAndGrade(teacherId, school, grade);
        Date now = new Date();
        if (onlineTeacherWeight == null) {
            logger.info("初始化权重记录：teacherId={}, schoolName={}, grade={}", teacherId, school, grade);
            onlineTeacherWeight = new OnlineTeacherWeight();
            onlineTeacherWeight.setTeacherId(teacherId);
            onlineTeacherWeight.setSumHomework(pictureSum);
            onlineTeacherWeight.setSchoolName(school);
            onlineTeacherWeight.setGrade(grade);
            onlineTeacherWeight.setAveCorrectTime(BigDecimal.ZERO);
            onlineTeacherWeight.setWeight(new BigDecimal("3"));
            onlineTeacherWeight.setCreateTime(now);
        } else {
            Integer oldSumHomework = Optional.ofNullable(onlineTeacherWeight.getSumHomework()).orElse(0);
            int newSumHomework = oldSumHomework + pictureSum;
            if (newSumHomework < 0) {
                newSumHomework = 0;
            }
            onlineTeacherWeight.setSumHomework(newSumHomework);
        }
        onlineTeacherWeightDao.save(onlineTeacherWeight);

        //更新实时权重
        //判断老师当前是否在排班内
        BigDecimal teacherWeight = onlineTeacherWeight.getWeight();
        if(!kmtArrangeAllotService.findTeacherArrange(new Date(),correctTeacher.getUserId())) {
            //不在排班,分配一张图片权重+10，批改一张图片权重-10
            teacherWeight = teacherWeight.add(new BigDecimal(3));
        }
        BigDecimal oldCorrectHomeworkNum = Optional.ofNullable(correctTeacher.getCorrectHomeworkNum()).orElse(BigDecimal.ZERO);
        BigDecimal newCorrectHomeworkNum = oldCorrectHomeworkNum.add(teacherWeight.multiply(new BigDecimal(pictureSum)));
        if (newCorrectHomeworkNum.compareTo(BigDecimal.ZERO) < 0) {
            newCorrectHomeworkNum = BigDecimal.ZERO;
        }
        correctTeacher.setCorrectHomeworkNum(newCorrectHomeworkNum);
        if (pictureSum > 0) {
            correctTeacher.setAllotTime(now);
        }
        bookManagerService.save(correctTeacher);
    }

    @Override
    public OnlineTeacherWeight findTopByTeacherIdAndSchoolNameAndGrade(String teacherId, String school, String grade) {
        return onlineTeacherWeightDao.findTopByTeacherIdAndSchoolNameAndGrade(teacherId, school, grade);
    }
}
