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

import com.alibaba.fastjson.JSON;
import com.xhkjedu.smarking.mapper.report.reportclass.*;
import com.xhkjedu.smarking.mapper.report.reportother.MsrExamMapper;
import com.xhkjedu.smarking.model.report.reportother.MsrReportparam;
import com.xhkjedu.smarking.service.report.reportother.MsrReportparamService;
import com.xhkjedu.smarking.utils.MarkingUtil;
import com.xhkjedu.smarking.vo.report.reportother.SzJsonVo;
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 ywx
 *Date 2025/1/3 14:31
 **/
@Service
public class MsrClassService {
    @Resource
    private MsrClassSubjectMapper msrClassSubjectMapper;
    @Resource
    private MsrClassSectionMapper msrClassSectionMapper;
    @Resource
    private MsrClassRankrateMapper msrClassRankrateMapper;
    @Resource
    private MsrClassNearlineMapper msrClassNearlineMapper;
    @Resource
    private MsrExamMapper msrExamMapper;
    @Resource
    private MsrReportparamService msrReportparamService;

    /**
     * @Description 班级对比表-列表
     * @Date 2025/1/6 16:55
     * @Author YWX
     * @Param [params]
     * @Return java.lang.Object
     **/
    public Object listClassForBjDb(StudentParams params) {
        List<LabelVo> labels = params.getLabels();
        StringBuilder sql = new StringBuilder();
        sql.append("cs.classid,cs.stunum");
        sql.append(",if(cs.classid=0,'全体',(select c.classname from t_class c where c.classid=cs.classid)) as classname");
        List<String> infoFields = new ArrayList<>();
        infoFields.add("classid");
        infoFields.add("classname");
        infoFields.add("stunum");

        List<String> rangeNames = new ArrayList<>();
        for (LabelVo label : labels) {
            Integer labelType = label.getLabelType();
            String labelName = label.getLabelName();
            String labelField = label.getLabelField();
            if (labelType.equals(2)) {
                rangeNames.add(labelName);
                continue;
            }
            sql.append(",");
            if (labelType.equals(1) || labelType.equals(3)) {
                infoFields.add(labelField);
            }
            sql.append(labelField);
        }

        String gradeField = "rangename,rangenum,rangerate,rangenumrank";
        String[] gradeFields = gradeField.split(",");
        if (N_Utils.isListNotEmpty(rangeNames)) {
            sql.append(",").append(gradeField);
        }
        sql.append(" from msr_class_subject cs ");
        if (N_Utils.isListNotEmpty(rangeNames)) {
            sql.append(" inner join msr_class_subject_grade csg on cs.examid=csg.examid ");
            sql.append(" and cs.classid=csg.classid and cs.subjectid=csg.subjectid and csg.reportcode='zh' ");
            sql.append(" and csg.rangename in ('").append(String.join("','", rangeNames)).append("') ");
        }
        List<Map> list = msrClassSubjectMapper.listClassForBjDb(sql.toString(), params);
        return formatList(params, list, infoFields, gradeFields);
    }

    //格式化列表
    private List<Map<String, Object>> formatList(StudentParams params, List<Map> list
            , List<String> infoFields, String[] gradeFields) {
        Map<Integer, List<Map>> collect = list.stream().collect(Collectors.groupingBy(
                m -> N_Utils.obj2Int(m.get("classid")), LinkedHashMap::new, Collectors.toList()));
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<Integer, List<Map>> entry : collect.entrySet()) {
            List<Map> values = entry.getValue();
            Map<String, Object> map = new LinkedHashMap<>();
            Map info = values.get(0);
            for (String field : infoFields) {
                if (field.contains(",")) {
                    String[] fields = field.split(",");
                    for (String f : fields) {
                        map.put(f, info.get(f));
                    }
                } else {
                    map.put(field, info.get(field));
                }
            }
            List<LinkedHashMap> gradeList = new ArrayList<>();
            for (Map m : values) {
                LinkedHashMap<String, Object> gradeMap = new LinkedHashMap<>();
                for (String field : gradeFields) {
                    gradeMap.put(field, m.get(field));
                }
                gradeList.add(gradeMap);
            }
            map.put("gradeList", gradeList);
            result.add(map);
        }

        String fieldname = params.getFieldname();
        if (N_Utils.isNotEmpty(fieldname)) {
            result = MarkingUtil.sortBySubjectField(result, params.getFieldvalue(), fieldname, params.getOd(), "gradeList");
        }
        return result;
    }

    /**
     * @Description 班级对比表-指标列表
     * @Date 2025/1/7 17:04
     * @Author YWX
     * @Param [params]
     * @Return java.lang.Object
     **/
    public Object listBjDbZb(StudentParams params) {
        Map<String, Object> map = new HashMap<>();
        List<LabelVo> labels = new ArrayList<>();
        labels.add(new LabelVo("平均分", "classavgscore,classavgrate,classavgrank"));
        MsrReportparam reportparam = msrReportparamService.getOneReportParams(params.getExamid(), "scorerate", "zh", params.getSubjectid());
        List<SzJsonVo> scorerates = JSON.parseArray(reportparam.getSzjson(), SzJsonVo.class);
        for (SzJsonVo vo : scorerates) {
            labels.add(new LabelVo(vo.getDjkey(), 2));
        }
        labels.add(new LabelVo("综合率", "zhl"));
        labels.add(new LabelVo("标准差", "bzc"));
        labels.add(new LabelVo("最高分", "classmaxscore"));
        labels.add(new LabelVo("最低分", "classminscore"));
        labels.add(new LabelVo("全科及格率", 3, "qkjgl"));
        labels.add(new LabelVo("超均率", "cjl"));
        labels.add(new LabelVo("标准分", "bzf"));
        labels.add(new LabelVo("中位数", "zws"));
        labels.add(new LabelVo("离均差", "ljc"));
        labels.add(new LabelVo("比均率", "bjl"));
        labels.add(new LabelVo("众数", "zs"));
        map.put("labels", labels);
        map.put("scorerate", scorerates);
        reportparam = msrReportparamService.getOneReportParams(params.getExamid(), "allrate", "zh", "");
        map.put("allrate", JSON.parseObject(reportparam.getSzjson(), SzJsonVo.class));
        return map;
    }

    /**
     * @Description 分数段统计-指标
     * @Date 2025/1/8 16:24
     * @Author YWX
     * @Param [params]
     * @Return java.lang.Object
     **/
    public Object getFsdZb(StudentParams params) {
        MsrReportparam reportParams = msrReportparamService.getOneReportParams(params.getExamid(), "scoresection", "zh", params.getSubjectid());
        Integer rptype = reportParams.getRptype();
        String szjson = reportParams.getSzjson();
        Map<String, Object> map = new HashMap<>();
        map.put("rptype", rptype);
        if (rptype.equals(0)) {
            map.put("params", JSON.parseObject(szjson, Map.class));
        } else {
            map.put("params", JSON.parseArray(szjson, Map.class));
        }
        return map;
    }

    /**
     * @Description 综合报告-分数段统计-列表
     * @Date 2025/1/8 16:47
     * @Author YWX
     * @Param [params]
     * @Return java.lang.Object
     **/
    public Object listClassForFsd(StudentParams params) {
        StringBuilder sql = new StringBuilder();
        sql.append("cs.classid,cs.stunum");
        sql.append(",if(cs.classid=0,'全体',(select c.classname from t_class c where c.classid=cs.classid)) as classname");
        List<String> infoFields = new ArrayList<>();
        infoFields.add("classid");
        infoFields.add("classname");
        infoFields.add("stunum");

        String gradeField = "fzfw,fzfwnum,fzfwrate";
        sql.append(",").append(gradeField);
        String[] gradeFields = gradeField.split(",");
        sql.append(" from msr_class_section cs ");
        List<Map> list = msrClassSectionMapper.listClassForFsd(sql.toString(), params);
        return formatList(params, list, infoFields, gradeFields);
    }

    /**
     * @Description 综合报告-名次和比例分析-列表
     * @Date 2025/1/9 16:51
     * @Author YWX
     * @Param [params]
     * @Return java.lang.Object
     **/
    public Object listClassForMcBl(StudentParams params) {
        StringBuilder sql = new StringBuilder();
        sql.append("cr.classid,cr.stunum");
        sql.append(",if(cr.classid=0,'全体',(select c.classname from t_class c where c.classid=cr.classid)) as classname");
        List<String> infoFields = new ArrayList<>();
        infoFields.add("classid");
        infoFields.add("classname");
        infoFields.add("stunum");

        String gradeField = "ztname,ctname,rnum,rrate";
        sql.append(",").append(gradeField);
        String[] gradeFields = gradeField.split(",");
        sql.append(" from msr_class_rankrate cr ");
        List<Map> list = msrClassRankrateMapper.listClassForMcBl(sql.toString(), params);
        return formatList(params, list, infoFields, gradeFields);
    }

    /**
     * @Description 总分分档上线-列表
     * @Date 2025/1/10 9:26
     * @Author YWX
     * @Param [params]
     * @Return java.lang.Object
     **/
    public Object listClassForFdSxZf(StudentParams params) {
        StringBuilder sql = new StringBuilder();
        sql.append("cn.classid");
        sql.append(",if(cn.classid=0,'全体',(select c.classname from t_class c where c.classid=cn.classid)) as classname");
        List<String> infoFields = new ArrayList<>();
        infoFields.add("classid");
        infoFields.add("classname");

        String gradeField = "dwname,dworder,dwscore,sxnum,ljsnum,ljsxrate";
        sql.append(",").append(gradeField);
        String[] gradeFields = gradeField.split(",");
        sql.append(" from msr_class_nearline cn ");
        List<Map> list = msrClassNearlineMapper.listClassForFdSx(sql.toString(), params);
        List<Map<String, Object>> data = formatList(params, list, infoFields, gradeFields);
        Map<String, Object> map = msrExamMapper.getFullAndMaxScoreByExamId(params.getExamid());
        map.put("list", data);
        return map;
    }

    /**
     * @Description 学科分档上线-列表
     * @Date 2025/1/10 11:34
     * @Author YWX
     * @Param [params]
     * @Return java.lang.Object
     **/
    public Object listClassForFdSxXk(StudentParams params) {
        StringBuilder sql = new StringBuilder();
        sql.append("cn.classid");
        sql.append(",if(cn.classid=0,'全体',(select c.classname from t_class c where c.classid=cn.classid)) as classname");
        sql.append(",if(cn.subjectid='zf','总分',(select s.subjectname from t_subject s where s.subjectid=cn.subjectid)) as subjectname");
        List<String> infoFields = new ArrayList<>();
        infoFields.add("classid");
        infoFields.add("classname");

        String gradeField = "subjectid,dwscore,sxnum,ssxnum,gxrate,mzxrate";
        sql.append(",").append(gradeField);
        String[] gradeFields = gradeField.split(",");
        sql.append(" from msr_class_nearline cn ");
        List<String> fields = new ArrayList<>();
        fields.add("subjectname");
        Collections.addAll(fields, gradeFields);
        gradeFields = fields.toArray(new String[0]);
        List<Map> list = msrClassNearlineMapper.listClassForFdSx(sql.toString(), params);
        return formatList(params, list, infoFields, gradeFields);
    }
}
