package com.xhkjedu.smarking.service.report.report;

import com.xhkjedu.smarking.mapper.report.reportstu.MsrStudentMapper;
import com.xhkjedu.smarking.mapper.report.reportstu.MsrStudentPointMapper;
import com.xhkjedu.smarking.model.report.reportstu.MsrStudent;
import com.xhkjedu.smarking.utils.MarkingUtil;
import com.xhkjedu.smarking.vo.report.reportother.ExamReportParams;
import com.xhkjedu.smarking.vo.report.reportother.ScoreGroupVo;
import com.xhkjedu.smarking.vo.report.reportstu.LabelVo;
import com.xhkjedu.smarking.vo.report.reportstu.StudentParams;
import com.xhkjedu.utils.N_Utils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description：学生报告信息
 * @Author: WN
 * @Date: 2024/12/24 9:50:38
 **/
@Service
public class MsrStudentService {
    @Resource
    private MsrStudentMapper msrStudentMapper;
    @Resource
    private MsrStudentPointMapper msrStudentPointMapper;

    //综合报告-小分表-列表
    public List<Map<String, Object>> listStuScoreAndRank(Integer examid, String subjectid) {
        return msrStudentMapper.listStuScoreAndRankByExamidAndSubjectid(examid, subjectid);
    }

    //学生报告-学生各学科试题分析
    public List<Map<String, Object>> listStuSubjectQuestions(ExamReportParams params) {
        return msrStudentMapper.listStuSubjectQuestions(params);
    }

    //学生报告-学生各学科知识点分析
    public List<Map<String, Object>> listStuPoints(ExamReportParams params) {
        return msrStudentPointMapper.listStuPoints(params);
    }

    /**
     * @Description 综合报告-排行榜
     * @Date 2025/1/6 9:12
     * @Author YWX
     * @Param [params]
     * @Return java.lang.Object
     **/
    public Object listStudentForPhb(StudentParams params) {
        List<LabelVo> labels = params.getLabels();
        StringBuilder sql = new StringBuilder();
        sql.append("s.studentid,s.subjectid,s.classid");
        sql.append(",if(s.subjectid='zf','总分',(select ts.subjectname from t_subject ts where ts.subjectid=s.subjectid)) as subjectname");
        boolean showClass = false;
        List<String> userFields = new ArrayList<>();
        List<String> subjectFields = new ArrayList<>();
        for (LabelVo label : labels) {
            Integer labelType = label.getLabelType();
            String labelName = label.getLabelName();
            String labelField = label.getLabelField();
            sql.append(",");
            if (labelType.equals(1)) {
                if (labelName.equals("姓名")) {
                    sql.append("username as ");
                }
                userFields.add(labelField);
            } else if (labelType.equals(2)) {
                subjectFields.add(labelField);
            } else if (labelType.equals(3)) {
                sql.append("(select c.classname from t_class c where c.classid=s.classid) as ");
                showClass = true;
            }
            sql.append(labelField);
        }
        sql.append(" from msr_student s ");
        if (N_Utils.isListNotEmpty(userFields)) {
            sql.append(" inner join t_user u on s.studentid=u.userid ");
            String studentname = params.getStudentname();
            if (N_Utils.isNotEmpty(studentname)) {
                sql.append(" and (u.username like '%").append(studentname).append("%'");
                sql.append(" or u.examno like '%").append(studentname).append("%'");
                sql.append(" or u.studentno like '%").append(studentname).append("%')");
            }
        }
        List<Map> list = msrStudentMapper.listStudentForPhb(sql.toString(), params);
        Map<String, List<Map>> collect = list.stream().collect(Collectors.groupingBy(
                m -> m.get("studentid") + "_" + m.get("classid"), LinkedHashMap::new, Collectors.toList()));
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<String, List<Map>> entry : collect.entrySet()) {
            List<Map> values = entry.getValue();
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("studentid", entry.getKey().split("_")[0]);
            for (String field : userFields) {
                map.put(field, values.get(0).get(field));
            }
            if (showClass) {
                map.put("classname", values.get(0).get("classname"));
            }
            List<LinkedHashMap> subjectList = new ArrayList<>();
            for (Map m : values) {
                LinkedHashMap<String, Object> subjectMap = new LinkedHashMap<>();
                subjectMap.put("subjectid", m.get("subjectid"));
                subjectMap.put("subjectname", m.get("subjectname"));
                for (String field : subjectFields) {
                    subjectMap.put(field, m.get(field));
                }
                subjectList.add(subjectMap);
            }
            map.put("subjectList", subjectList);
            result.add(map);
        }

        String fieldname = params.getFieldname();
        if (N_Utils.isNotEmpty(fieldname)) {
            result = MarkingUtil.sortBySubjectField(result, params.getFieldvalue(), fieldname, params.getOd(), "subjectList");
        }
        if (N_Utils.isTrueInteger(params.getPage())) {
            return MarkingUtil.getPageResult(params.getPage(), params.getPageSize(), result);
        } else {
            return result;
        }
    }

    //综合报告-排行榜-指标
    public Object listPhbZb() {
        List<LabelVo> labels = new ArrayList<>();
        labels.add(new LabelVo("姓名", "studentname"));
        labels.add(new LabelVo("考号", "examno"));
        labels.add(new LabelVo("学号", "studentno"));
        labels.add(new LabelVo("班级",3, "classname"));
        labels.add(new LabelVo("分数", 2, "stuscore"));
        labels.add(new LabelVo("等级", 2, "gradevalue"));
        labels.add(new LabelVo("学校排名", 2, "schoolrank"));
        labels.add(new LabelVo("班级排名", 2, "classrank"));
        labels.add(new LabelVo("标准分", 2, "bzf"));
        labels.add(new LabelVo("超均率", 2, "cjl"));
        return labels;
    }

    /**
     * @Description 校级报告-总分分布
     * @Date 2025/1/10 17:29
     * @Author YWX
     * @Param [params]
     * @Return java.lang.Object
     **/
    public Object listScoreForZfFb(StudentParams params) {
        StringBuilder sql = new StringBuilder();
        sql.append("s.fullscore,s.stuscore,s.studentid");
        sql.append(" from msr_student s ");
        sql.append(" where s.examid=").append(params.getExamid());
        sql.append(" and s.subjectid='zf'");
        sql.append(" group by s.studentid");
        List<MsrStudent> list = msrStudentMapper.listStudentBySql(sql.toString());
        if (N_Utils.isListEmpty(list)) {
            return new ArrayList<>();
        }
        Double fullscore = list.get(0).getFullscore();
        int totalNum = list.size();
        List<ScoreGroupVo> groups = MarkingUtil.scoreGroup(fullscore, 12);
        long num;
        for (ScoreGroupVo group : groups) {
            Double minvalue = group.getMinvalue();
            Double maxvalue = group.getMaxvalue();
            if (minvalue.equals(0.0)) {
                num = list.stream().filter(s -> s.getStuscore().compareTo(maxvalue) < 0).count();
            } else if (maxvalue.equals(fullscore)) {
                num = list.stream().filter(s -> s.getStuscore().compareTo(minvalue) >= 0).count();
            } else {
                num = list.stream().filter(s -> s.getStuscore().compareTo(minvalue) >= 0 && s.getStuscore().compareTo(maxvalue) < 0).count();
            }
            group.setNum((int) num);
            group.setNumrate(N_Utils.getIntegerDivideAndMulitiply(group.getNum(), totalNum));
        }
        return groups;
    }
}
