package com.ruoyi.system.service.impl.score;

import java.text.DecimalFormat;
import java.util.*;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.entity.FormalParentsStudent;
import com.ruoyi.common.core.domain.entity.FormalTeacherClass;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.score.ScoreData;
import com.ruoyi.system.domain.score.ScoreDataDetails;
import com.ruoyi.system.mapper.FormalParentsStudentMapper;
import com.ruoyi.system.mapper.FormalTeacherClassMapper;
import com.ruoyi.system.mapper.score.ScoreDataMapper;
import com.ruoyi.system.service.score.IScoreDataService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.stream.Collectors;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import static com.ruoyi.common.constant.CacheConstants.*;
import static com.ruoyi.common.utils.PageUtils.startPage;

/**
 * 成绩Service业务层处理
 *
 * @author boman
 * @date 2023-07-20
 */
@Service
public class ScoreDataServiceImpl implements IScoreDataService {
    @Autowired
    private ScoreDataMapper scoreDataMapper;

    @Autowired
    private FormalTeacherClassMapper formalTeacherClassMapper;
    @Autowired
    private FormalParentsStudentMapper formalParentsStudentMapper;
    @Autowired
    private RedisCache redisCache;

    /**
     * 查询成绩
     *
     * @param scoreData 成绩主键
     * @return 成绩
     */
    @Override
    public ScoreData selectScoreDataByScoreId(ScoreData scoreData) {
        Long scoreId = scoreData.getScoreId();
        Map<String, Object> params = scoreData.getParams();
        String role = "admin";
        if (params != null && params.size() > 0) {
            role = (String) params.get("role");
        }
        StringBuilder stdId = new StringBuilder("0,");
        if ("parents".equals(role)) {
            Long userId = SecurityUtils.getLoginUser().getUserId();
            //获取该家长的孩子id
            LoginUser user = SecurityUtils.getLoginUser();
            FormalParentsStudent formalParentsStudent = new FormalParentsStudent();
            formalParentsStudent.setParentsId(user.getUserId());
            List<FormalParentsStudent> formalParentsStudents = formalParentsStudentMapper.selectFormalParentsStudentList(formalParentsStudent);
            for (FormalParentsStudent parentsStudent : formalParentsStudents) {
                stdId.append(parentsStudent.getId()).append(",");
            }
            if (StringUtils.isNotBlank(stdId.toString())) {
                stdId = new StringBuilder(stdId.substring(0, stdId.length() - 1));
            }

            Map<String,Object> map = new HashMap<>();
            map.put("stdId",stdId.toString());
            scoreData.setParams(map);
            //获取查看人数
            Object chaKanCount = redisCache.getCacheObject(SCORE_PEOPLE_CHAKAN_COUNT + scoreId);
            if (ObjectUtils.isEmpty(chaKanCount)) {
                redisCache.setCacheObject(SCORE_PEOPLE_CHAKAN_COUNT + scoreId, 1);
            } else {
                //判断该家长是否查看过
                Object cacheObject = redisCache.getCacheObject(SCORE_PEOPLE_CHAKAN + scoreId + ":" + userId);
                if (ObjectUtils.isEmpty(cacheObject)) {
                    redisCache.setCacheObject(SCORE_PEOPLE_CHAKAN_COUNT + scoreId, Integer.parseInt(String.valueOf(chaKanCount)) + 1);
                }
            }
            //如果是家长要记录到redis中
            redisCache.setCacheObject(SCORE_PEOPLE_CHAKAN + scoreId + ":" + userId, userId);
            return scoreDataMapper.selectScoreDataForParents(scoreData);
        }
        return scoreDataMapper.selectScoreDataByScoreId(scoreId);
    }

    /**
     * 查询成绩列表
     *
     * @param scoreData 成绩
     * @return 成绩
     */
    @Override
    public List<ScoreData> selectScoreDataList(ScoreData scoreData) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        StringBuilder classId = new StringBuilder("0,");
        Map<String, Object> params = scoreData.getParams();
        String role = "admin";
        if (params != null && params.size() > 0) {
            role = (String) params.get("role");
        }
        List<ScoreData> scoreDataList = new ArrayList<>();
        if ("teacher".equals(role)) {
            FormalTeacherClass formalTeacherClass = new FormalTeacherClass();
            formalTeacherClass.setTeacherId(user.getUserId());
            List<FormalTeacherClass> formalTeacherClasses = formalTeacherClassMapper.selectFormalTeacherClassList(formalTeacherClass);
            if (formalTeacherClasses != null && formalTeacherClasses.size() > 0) {
                for (FormalTeacherClass teacherClass : formalTeacherClasses) {
                    classId.append(teacherClass.getClassId()).append(",");
                }
            }
            if (StringUtils.isNotBlank(classId.toString())) {
                classId = new StringBuilder(classId.substring(0, classId.length() - 1));
            }
            startPage();
            scoreData.setScoreClassId(classId.toString());
            scoreDataList = scoreDataMapper.selectScoreDataList(scoreData);
        } else if ("parents".equals(role)) {
            FormalParentsStudent formalParentsStudent = new FormalParentsStudent();
            formalParentsStudent.setParentsId(user.getUserId());
            List<FormalParentsStudent> formalParentsStudents = formalParentsStudentMapper.selectFormalParentsStudentList(formalParentsStudent);
            for (FormalParentsStudent parentsStudent : formalParentsStudents) {
                classId.append(parentsStudent.getClassId()).append(",");
            }
            if (StringUtils.isNotBlank(classId.toString())) {
                classId = new StringBuilder(classId.substring(0, classId.length() - 1));
            }
            startPage();
            scoreData.setScoreClassId(classId.toString());
            scoreDataList = scoreDataMapper.selectScoreDataList(scoreData);
        } else if ("admin".equals(role)) {
            startPage();
            scoreDataList = scoreDataMapper.selectScoreDataList(scoreData);
        }
        //赋值查看率
        if (scoreDataList != null && scoreDataList.size() > 0) {
            DecimalFormat df = new DecimalFormat("##.0%");
            String percent = "0.00%";
            for (ScoreData data : scoreDataList) {
                //全部人数
                double chaKanAll = 0D;
                double chaKanCount = 0D;
                if (ObjectUtils.isNotEmpty(redisCache.getCacheObject(SCORE_PEOPLE_ALL + data.getScoreId()))) {
                    chaKanAll = (int) redisCache.getCacheObject(SCORE_PEOPLE_ALL + data.getScoreId());
                    if (ObjectUtils.isNotEmpty(redisCache.getCacheObject(SCORE_PEOPLE_CHAKAN_COUNT + data.getScoreId()))) {
                        //已查看
                        chaKanCount = (int) redisCache.getCacheObject(SCORE_PEOPLE_CHAKAN_COUNT + data.getScoreId());
                    }
                }
                double weiChaKan = chaKanAll;
                if (chaKanAll > 0 && chaKanCount >= 0) {
                    weiChaKan = chaKanAll - chaKanCount;
                    double z = chaKanCount / chaKanAll;
                    if (Math.abs(z) >= 0.1) {
                        //计算百分比
                        percent = df.format(z);
                    }
                }
                data.setChaKan(chaKanCount);
                data.setWeiChaKan(weiChaKan);
                data.setPercentage(percent);
            }
        }
        return scoreDataList;
    }

    /**
     * 新增成绩
     *
     * @param scoreData 成绩
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertScoreData(ScoreData scoreData) {
        scoreData.setCreateTime(DateUtils.getNowDate());
        int rows = scoreDataMapper.insertScoreData(scoreData);
        List<ScoreDataDetails> scoreDataDetailsList = scoreData.getScoreDataDetailsList();
        if (scoreDataDetailsList != null && scoreDataDetailsList.size() > 0) {
            scoreDataDetailsList.stream().sorted(Comparator.comparing(ScoreDataDetails::getZongfen).reversed()).collect(Collectors.toList());
            for (int i = 0; i < scoreDataDetailsList.size(); i++) {
                scoreDataDetailsList.get(i).setScoreSort(i + 1 + "");
            }
            insertScoreDataDetails(scoreData);
        }
        Long scoreId = scoreData.getScoreId();
        //新增成绩的时候,往redis中放入该次考试总人数
        int count = scoreDataMapper.selectDetailsCountByScoreId(scoreId);
        redisCache.setCacheObject(SCORE_PEOPLE_ALL + scoreId, count);
        redisCache.setCacheObject(SCORE_PEOPLE_CHAKAN_COUNT + scoreId, 0);
        return rows;
    }

    /**
     * 修改成绩
     *
     * @param scoreData 成绩
     * @return 结果
     */
    @Transactional
    @Override
    public int updateScoreData(ScoreData scoreData) {
        scoreData.setUpdateTime(DateUtils.getNowDate());
        scoreDataMapper.deleteScoreDataDetailsByScoreId(scoreData.getScoreId());
        insertScoreDataDetails(scoreData);
        return scoreDataMapper.updateScoreData(scoreData);
    }

    /**
     * 批量删除成绩
     *
     * @param scoreIds 需要删除的成绩主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteScoreDataByScoreIds(Long[] scoreIds) {
        scoreDataMapper.deleteScoreDataDetailsByScoreIds(scoreIds);
        return scoreDataMapper.deleteScoreDataByScoreIds(scoreIds);
    }

    /**
     * 删除成绩信息
     *
     * @param scoreId 成绩主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteScoreDataByScoreId(Long scoreId) {
        scoreDataMapper.deleteScoreDataDetailsByScoreId(scoreId);
        return scoreDataMapper.deleteScoreDataByScoreId(scoreId);
    }

    /**
     * 后台首页成绩统计排名
     */
    @Override
    public List<ScoreDataDetails> indexPaiMing(ScoreData scoreData) {
        //最新一次考试
        List<ScoreDataDetails> scoreDataDetails = scoreDataMapper.selectScoreDataByScoreClassId(scoreData.getScoreClassId());
        if (scoreDataDetails != null && scoreDataDetails.size() > 0) {
            scoreDataDetails = scoreDataDetails.subList(0, Math.min(scoreDataDetails.size(), 10));
        }
        return scoreDataDetails;
    }

    /**
     * 后台首页成绩统计分段人数饼图最新一次考试
     */
    @Override
    public Map<String, Object> indexBingTu(ScoreData scoreData) {
        //获取缓存的数据
        Map<String, Object> cacheMap = redisCache.getCacheMap(CacheConstants.FEN_DUAN_NEW + scoreData.getScoreClassId());
        //获取班级id对应的最新考试id
        Long scoreDataId = (Long) redisCache.getCacheObject(CacheConstants.SCORE_ID + scoreData.getScoreClassId());
        boolean flag = false;
        if (cacheMap != null) {
            //获取redis缓存的考试id
            Long scoreId = (Long) cacheMap.get("scoreId");
            //判断最新一次考试id和缓存id是否匹配
            if (scoreDataId != null && scoreDataId.equals(scoreId)) {
                //说明缓存就是最新的
                return cacheMap;
            } else {
                //说明缓存数据不是最新的需要放到对比数据key中去 成为对比数据
                flag = true;
            }
        }
        Map<String, Object> map = new HashMap<>(8);
        int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0;
        map.put("One", a);
        map.put("Tow", b);
        map.put("Thr", c);
        map.put("For", d);
        map.put("Fiv", e);
        map.put("Six", f);
        map.put("Sev", g);
        map.put("Eig", h);
        List<ScoreDataDetails> scoreDataDetails = scoreDataMapper.selectScoreDataByScoreClassId(scoreData.getScoreClassId());
        if (scoreDataDetails != null && scoreDataDetails.size() > 0) {
            int zongfen = 0;
            //计算各个分数段有多少人
            for (ScoreDataDetails scoreDataDetail : scoreDataDetails) {
                if (scoreDataDetail.getZongfen() != null) {
                    zongfen = scoreDataDetail.getZongfen();
                }
                if (zongfen >= 0 && zongfen <= 100) {
                    a++;
                } else if (zongfen > 100 && zongfen <= 200) {
                    b++;
                } else if (zongfen > 200 && zongfen <= 300) {
                    c++;
                } else if (zongfen > 300 && zongfen <= 400) {
                    d++;
                } else if (zongfen > 400 && zongfen <= 500) {
                    e++;
                } else if (zongfen > 500 && zongfen <= 600) {
                    f++;
                } else if (zongfen > 600 && zongfen <= 700) {
                    g++;
                } else if (zongfen > 700) {
                    h++;
                }
            }
            map.put("One", a);
            map.put("Tow", b);
            map.put("Thr", c);
            map.put("For", d);
            map.put("Fiv", e);
            map.put("Six", f);
            map.put("Sev", g);
            map.put("Eig", h);
            map.put("scoreId", scoreDataDetails.get(0).getScoreId());
            //把最新数据放到最新缓存key中
            redisCache.setCacheMap(CacheConstants.FEN_DUAN_NEW + scoreData.getScoreClassId(), map);
            redisCache.setCacheObject(CacheConstants.SCORE_ID + scoreData.getScoreClassId(), scoreDataDetails.get(0).getScoreId());
            if (flag) {
                //放入对比数据
                redisCache.setCacheMap(CacheConstants.FEN_DUAN_LAST + scoreData.getScoreClassId(), cacheMap);
            }
        }
        return map;
    }

    /**
     * 后台首页成绩统计分段人数折线图
     */

    @Override
    public Map<String, Object> indexZheXian(ScoreData scoreData) {
        Map<String, Object> map = new HashMap<>(8);
        //分段
        List<String> x = new ArrayList<>();
        x.add("One");
        x.add("Tow");
        x.add("Thr");
        x.add("For");
        x.add("Fiv");
        x.add("Six");
        x.add("Sev");
        x.add("Eig");
        //本次
        List<Object> y1 = new ArrayList<>();
        //上次
        List<Object> y2 = new ArrayList<>();
        Map<String, Object> cacheMapNew = redisCache.getCacheMap(CacheConstants.FEN_DUAN_NEW + scoreData.getScoreClassId());
        Map<String, Object> cacheMapLast = redisCache.getCacheMap(CacheConstants.FEN_DUAN_LAST + scoreData.getScoreClassId());
        if (cacheMapNew != null && cacheMapNew.size() > 0) {
            for (String key : cacheMapNew.keySet()) {
                if (!"scoreId".equals(key)) {
                    y1.add(cacheMapNew.get(key));
                    if (cacheMapLast.get(key) != null) {
                        y2.add(cacheMapLast.get(key));
                    } else {
                        y2.add(0);
                    }
                }
            }
        } else {
            for (int i = 0; i < 8; i++) {
                y1.add(0);
                y2.add(0);
            }
        }

        map.put("x", x);
        map.put("y1", y1);
        map.put("y2", y2);
        return map;
    }

    /**
     * 新增成绩_子信息
     *
     * @param scoreData 成绩对象
     */
    public void insertScoreDataDetails(ScoreData scoreData) {
        List<ScoreDataDetails> scoreDataDetailsList = scoreData.getScoreDataDetailsList();
        Long scoreId = scoreData.getScoreId();
        if (StringUtils.isNotNull(scoreDataDetailsList)) {
            List<ScoreDataDetails> list = new ArrayList<ScoreDataDetails>();
            for (ScoreDataDetails scoreDataDetails : scoreDataDetailsList) {
                scoreDataDetails.setScoreId(scoreId);
                list.add(scoreDataDetails);
            }
            if (list.size() > 0) {
                scoreDataMapper.batchScoreDataDetails(list);
            }
        }
    }
}
