package com.yida.data.school.exam.service.impl;

import static com.yida.data.common.core.entity.constant.imageConstant.SCORE_IMAGE_URL;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.CurrentUser;
import com.yida.data.common.core.entity.constant.AppConstant;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.exam.CoreExamination;
import com.yida.data.common.core.entity.exam.CoreExaminationPublish;
import com.yida.data.common.core.entity.exam.CoreExaminationPublishGradeConvertType;
import com.yida.data.common.core.entity.exam.CoreExaminationPublishRecord;
import com.yida.data.common.core.entity.exam.CoreExaminationStudent;
import com.yida.data.common.core.entity.exam.EduExamAvg;
import com.yida.data.common.core.entity.notice.app.AppNotice;
import com.yida.data.common.core.entity.notice.app.inside.PushMessage;
import com.yida.data.common.core.entity.notice.qywx.NewsSchoolNotice;
import com.yida.data.common.core.entity.notice.qywx.inside.Article;
import com.yida.data.common.core.entity.notice.qywx.inside.News;
import com.yida.data.common.core.entity.school.EduYidaAppAccount;
import com.yida.data.common.core.entity.system.Dept;
import com.yida.data.common.core.entity.system.EduApp;
import com.yida.data.common.core.entity.system.EduYidaApp;
import com.yida.data.common.core.entity.user.EduParent;
import com.yida.data.common.core.entity.user.EduStudent;
import com.yida.data.common.core.utils.AppUtil;
import com.yida.data.common.core.utils.WxUtil;
import com.yida.data.common.service.CommonService;
import com.yida.data.school.exam.mapper.CoreExaminationMapper;
import com.yida.data.school.exam.mapper.CoreExaminationPublishGradeConvertTypeMapper;
import com.yida.data.school.exam.mapper.CoreExaminationPublishMapper;
import com.yida.data.school.exam.mapper.CoreExaminationStudentCourseMapper;
import com.yida.data.school.exam.mapper.CoreExaminationStudentMapper;
import com.yida.data.school.exam.service.CoreExaminationPublishGradeConvertTypeService;
import com.yida.data.school.exam.service.CoreExaminationPublishRecordService;
import com.yida.data.school.exam.service.CoreExaminationPublishService;
import com.yida.data.school.exam.service.EduExamAvgService;
import com.yida.data.user.feign.RemoteStudentService;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(readOnly = true)
@RefreshScope
public class CoreExaminationPublishServiceImpl extends
    ServiceImpl<CoreExaminationPublishMapper, CoreExaminationPublish> implements CoreExaminationPublishService {

    @Resource
    private CoreExaminationMapper coreExaminationMapper;
    @Resource
    private CoreExaminationPublishMapper coreExaminationPublishMapper;
    @Resource
    private WxUtil wxUtil;
    @Resource
    private EduExamAvgService eduExamAvgService;
    @Resource
    private CommonService commonService;
    @Resource
    private CoreExaminationPublishGradeConvertTypeService coreExaminationPublishGradeConvertTypeServiceImpl;
    @Resource
    private CoreExaminationStudentCourseMapper coreExaminationStudentCourseMapper;
    @Resource
    private CoreExaminationStudentMapper coreExaminationStudentMapper;
    @Resource
    private CoreExaminationPublishGradeConvertTypeMapper coreExaminationPublishGradeConvertTypeMapper;
    @Resource
    private RemoteStudentService remoteStudentService;
    @Resource
    private CoreExaminationPublishRecordService coreExaminationPublishRecordService;
    @Value("${febs.pageUrl}")
    private String pageUrl;
    private static final String SCORE_DETAIL = "/score/scoreDetail";

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = CachePrefixConstant.EXAM_STUDENT_SCORE_RANK, allEntries = true)
    public void publishExamination(CoreExaminationPublish coreExaminationPublish, CurrentUser currentUser) {

        //登录用户id
        Long userId = 1L;
        if (currentUser != null) {
            userId = currentUser.getUserId();
        }
        //保存发布信息
        coreExaminationPublish.setCreateId(userId);
        coreExaminationPublishMapper.insert(coreExaminationPublish);

        //保存发布的成绩换算信息
        List<CoreExaminationPublishGradeConvertType> typeList = coreExaminationPublish.getTypeList();
        if (typeList != null && typeList.size() > 0) {
            typeList.forEach(type -> type.setCoreExaminationPublishId(coreExaminationPublish.getId()));
        }

        coreExaminationPublishGradeConvertTypeServiceImpl.saveBatch(typeList);

        //修改考试的发布状态
        CoreExamination coreExamination = coreExaminationMapper.selectById(coreExaminationPublish.getCoreExaminationId());
        coreExamination.setPublish("1");
        coreExaminationMapper.updateById(coreExamination);

        //如果都被屏蔽则不存入数据
        if ("1".equals(coreExaminationPublish.getSchoolBlock()) && "1".equals(coreExaminationPublish.getTeacherBlock()) && "1"
            .equals(coreExaminationPublish.getParentBlock())) {
            return;
        }
        //查询考试的学生信息
        List<CoreExaminationStudent> studentList = coreExaminationStudentMapper
            .findExaminationStudentList(coreExaminationPublish.getCoreExaminationId(), null, null);
        for (CoreExaminationStudent student : studentList) {
            // 计算等级并更新
            List<String> rankList =
                coreExaminationPublishGradeConvertTypeMapper
                    .findGradeRank(coreExamination.getScore(), student.getScore(), coreExamination.getId());
            if (rankList != null && rankList.size() > 0) {
                student.setGradeLevel(rankList.get(0));
                coreExaminationStudentMapper.updateById(student);
            }
        }
        //根据考试主键id查询学生科目成绩
        List<CoreExaminationPublishRecord> recordList = coreExaminationStudentCourseMapper
            .findByCoreExaminationId(coreExaminationPublish.getCoreExaminationId());
        //计算成绩等级
        for (CoreExaminationPublishRecord record : recordList) {
            record.setCoreExaminationPublishId(coreExaminationPublish.getId());
            //查询成绩等级信息，查询条件换算百分比，并更新成绩为对应的等级
            List<String> rankList =
                coreExaminationPublishGradeConvertTypeMapper
                    .findGradeRank(record.getCourseScore(), record.getScore(), record.getCoreExaminationId());
            if (rankList != null && rankList.size() > 0) {
                record.setGradeLevel(rankList.get(0));
            }
        }
        coreExaminationPublishRecordService.saveBatch(recordList);
        // 保存平均成绩
        List<EduExamAvg> avgList = new ArrayList<>();
        // 年级总平均
        // 班级总平均
        Map<Long, Integer> studentNum = new HashMap<>();
        Map<Long, Double> scoreAll = new HashMap<>();
        studentNum.put(null, 0);
        scoreAll.put(null, 0D);
        for (CoreExaminationStudent student : studentList) {
            if (!studentNum.containsKey(student.getClassId())) {
                studentNum.put(student.getClassId(), 0);
                scoreAll.put(student.getClassId(), 0D);
            }
            studentNum.put(student.getClassId(), studentNum.get(student.getClassId()) + 1);
            scoreAll.put(student.getClassId(), scoreAll.get(student.getClassId()) + student.getScore());
            studentNum.put(null, studentNum.get(null) + 1);
            scoreAll.put(null, scoreAll.get(null) + student.getScore());
        }
        for (Map.Entry<Long, Integer> oneStudent : studentNum.entrySet()) {
            EduExamAvg avg = new EduExamAvg();
            avg.setExamId(coreExamination.getId());
            avg.setDeptType(oneStudent.getKey() == null ? 1 : 0);
            avg.setDeptId(oneStudent.getKey() == null ? studentList.get(0).getGradeId() : oneStudent.getKey());
            avg.setScoreAvg(scoreAll.get(oneStudent.getKey()) / oneStudent.getValue());
            avg.setScoreAvgRate(avg.getScoreAvg() * 100 / coreExamination.getScore());
            avgList.add(avg);
        }

        // 各科目的年级平均、班级平均
        Map<Long, Map<Long, Integer>> courseStudentNum = new HashMap<>();
        Map<Long, Map<Long, Double>> courseScoreAll = new HashMap<>();
        Map<Long, Double> courseScore = new HashMap<>();
        for (CoreExaminationPublishRecord record : recordList) {
            if (!courseStudentNum.containsKey(record.getCoreExaminationCourseId())) {
                courseStudentNum.put(record.getCoreExaminationCourseId(), new HashMap<Long, Integer>() {{
                    put(null, 0);
                }});
                courseScoreAll.put(record.getCoreExaminationCourseId(), new HashMap<Long, Double>() {{
                    put(null, 0D);
                }});
                courseScore.put(record.getCoreExaminationCourseId(), record.getCourseScore());
            }

            if (!courseStudentNum.get(record.getCoreExaminationCourseId()).containsKey(record.getClassId())) {
                courseStudentNum.get(record.getCoreExaminationCourseId()).put(record.getClassId(), 0);
                courseScoreAll.get(record.getCoreExaminationCourseId()).put(record.getClassId(), 0D);
            }

            courseStudentNum.get(record.getCoreExaminationCourseId())
                .put(record.getClassId(),
                    courseStudentNum.get(record.getCoreExaminationCourseId()).get(record.getClassId()) + 1);
            courseScoreAll.get(record.getCoreExaminationCourseId())
                .put(record.getClassId(),
                    courseScoreAll.get(record.getCoreExaminationCourseId()).get(record.getClassId()) + record.getScore());

            courseStudentNum.get(record.getCoreExaminationCourseId())
                .put(null,
                    courseStudentNum.get(record.getCoreExaminationCourseId()).get(null) + 1);
            courseScoreAll.get(record.getCoreExaminationCourseId())
                .put(null,
                    courseScoreAll.get(record.getCoreExaminationCourseId()).get(null) + record.getScore());
        }

        for (Map.Entry<Long, Map<Long, Integer>> courseClassScore : courseStudentNum.entrySet()) {
            for (Map.Entry<Long, Integer> classScore : courseClassScore.getValue().entrySet()) {
                EduExamAvg avg = new EduExamAvg();
                avg.setExamId(coreExamination.getId());
                avg.setDeptType(classScore.getKey() == null ? 1 : 0);
                avg.setDeptId(classScore.getKey() == null ? studentList.get(0).getGradeId() : classScore.getKey());
                avg.setScoreAvg(courseScoreAll.get(courseClassScore.getKey()).get(classScore.getKey()) / classScore.getValue());
                avg.setScoreAvgRate(avg.getScoreAvg() * 100 / courseScore.get(courseClassScore.getKey()));
                avg.setCourseId(courseClassScore.getKey());
                avgList.add(avg);
            }
        }
        eduExamAvgService.saveBatch(avgList);
        // 发送成绩通知
        pushScoreNotice(coreExamination, studentList);
    }

    private void pushScoreNotice(CoreExamination coreExamination, List<CoreExaminationStudent> studentList) {
        Dept school = commonService.getDept(coreExamination.getSchoolId());
        EduApp eduApp = commonService.getAppByCodeAndSchool(AppConstant.INDEX_PARENT, null, school.getDeptId());
        List<Long> studentId = studentList.stream().map(x -> x.getCoreStudentId()).collect(Collectors.toList());
        String accessToken = null;
        EduYidaApp yidaApp = null;
        EduYidaAppAccount yidaAppAccount = null;
        // 绑定了企业微信
        if (school.getSchoolType().contains(Dept.TYPE_QYWX)) {
            accessToken = wxUtil.getAccessToken(eduApp.getWxCorpId(), eduApp.getWxSecret());
        }
        // 绑定了易达app
        if (school.getSchoolType().contains(Dept.TYPE_YIDA_APP)) {
            yidaApp = commonService.getYidaApp(school.getDeptId());
            yidaAppAccount = commonService.getYidaAppAccount(school.getDeptId(), 0);
        }
        for (int i = 0; i < studentId.size(); i++) {
            EduStudent student = remoteStudentService.getStudentNoPermission(studentId.get(i)).getData();
            String title = student.getStuName() + "的成绩已经发布，请查阅！";
            String url = pageUrl + SCORE_DETAIL + "?studentId=" + studentId.get(i) +
                "&examId=" + coreExamination.getId();
            String description = coreExamination.getName();

            // 向微信推消息
            if (school.getSchoolType().contains(Dept.TYPE_QYWX)) {
                Article article = new Article();
                article.setTitle(title);
                article.setUrl(url + "&corpId=" + eduApp.getWxCorpId());
                article.setPicurl(SCORE_IMAGE_URL);
                article.setDescription(description);
                News news = new News(Arrays.asList(article));
                NewsSchoolNotice newsSchoolNotice = new NewsSchoolNotice();
                newsSchoolNotice.setNews(news);
                newsSchoolNotice.setAgentid(eduApp.getWxAgentId());
                List<EduParent> parent = student.getParents();
                if (CollUtil.isNotEmpty(parent)) {
                    List<String> parentId =
                        parent.stream().filter(x -> StrUtil.isNotBlank(x.getWxId())).map(x -> x.getWxId())
                            .collect(Collectors.toList());
                    newsSchoolNotice.setTo_parent_userid(parentId);
                    wxUtil.pushSchoolNotice(accessToken, newsSchoolNotice);
                }
            }
            // 向易达app推送消息
            if (school.getSchoolType().contains(Dept.TYPE_YIDA_APP)) {
                PushMessage pushMessage = new PushMessage();
                pushMessage.setMsgType(PushMessage.ARTICLE);
                pushMessage.setTitle(title);
                pushMessage.setImgUrl(SCORE_IMAGE_URL);
                pushMessage.setContent(description);
                pushMessage.setHtmlUrl(url + "&schoolId=" + school.getDeptId());
                pushMessage.setAccountId(yidaAppAccount.getYidaAppAccountId());
                AppNotice appNotice = new AppNotice();
                appNotice.setMsgList(Arrays.asList(pushMessage));
                appNotice.setUserIds(student.getParents().stream().filter(x -> StrUtil.isNotBlank(x.getYidaAppUserId()))
                    .map(x -> x.getYidaAppUserId()).collect(Collectors.toList()));
                appNotice.setPushMessage(new PushMessage(school.getDeptName() + "智慧校园",
                    yidaAppAccount.getYidaAppAccountId()));
                AppUtil.sendMsg(appNotice, yidaApp);
            }
        }
    }

}



