package com.xhkjedu.smarking.service.exam;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xhkjedu.smarking.mapper.exam.*;
import com.xhkjedu.smarking.model.exam.MsSubjectInvigilate;
import com.xhkjedu.smarking.vo.exam.EITeacherVo;
import com.xhkjedu.utils.N_Utils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @Description 阅卷科目监考分配表 服务实现类
 * @Author auto
 * @Date 2024-10-15
 */
@Service
public class MsSubjectInvigilateService {
    @Resource
    private MsSubjectInvigilateMapper msSubjectInvigilateMapper;
    @Resource
    private MsExamMapper examMapper;
    @Resource
    private MsSubjectMapper subjectMapper;
    @Resource
    private MsClassMapper classMapper;

    /**
     * @Description 监考设置
     * @Date 2024/10/18 15:02
     * @Author YWX
     * @Param [msid, subjectid, createid, teachers]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    public void setTeacher(Integer msid, String subjectid, Integer createid, List<MsSubjectInvigilate> teachers) {
        msSubjectInvigilateMapper.delByMsId(msid);//删除考试科目监考教师
        int timestamp = N_Utils.getSecondTimestamp();
        teachers.forEach(t -> {
            t.setMsid(msid);
            t.setSubjectid(subjectid);
            t.setCreateid(createid);
            t.setCreatetime(timestamp);
        });
        msSubjectInvigilateMapper.insertList(teachers);
        subjectMapper.updateInvigilateStateByMsId(msid, 2);//更新考试科目监考设置状态为2已设置
    }

    /**
     * @Description 根据考试科目id获取考试科目基本信息
     * @Date 2024/10/18 15:48
     * @Author YWX
     * @Param [msid]
     * @Return java.util.Map
     **/
    public Map getSubjectByMsId(Integer msid) {
        return msSubjectInvigilateMapper.getSubjectByMsId(msid);
    }

    /**
     * @Description 监考设置列表
     * @Date 2024/10/18 15:47
     * @Author YWX
     * @Param [examid]
     * @Return java.util.Map
     **/
    public Map listSubject(Integer examid) {
        Map map = examMapper.findById(examid);
        List<Map> subjects = msSubjectInvigilateMapper.listSubject(examid);//监考设置列表
        String msids = subjects.stream().map(s -> s.get("msid").toString()).collect(Collectors.joining(","));
        List<EITeacherVo> users = msSubjectInvigilateMapper.listUserByMsIds(msids);
        Integer schoolid = Integer.parseInt(map.get("schoolid").toString());
        List<Map<String,Object>> schoolClasses = classMapper.listSchoolClassByExamId(schoolid, examid);//考试班级
        int classnum = getClassNum(schoolClasses);
        for (Map s : subjects) {
            Integer msid = (Integer) s.get("msid");
            if (N_Utils.isListEmpty(users)) users = new ArrayList<>();
            String majorname = users.stream().filter(u -> msid.equals(u.getMsid()) && u.getMajored() == 1)
                                    .map(EITeacherVo::getUsername).distinct().collect(Collectors.joining("、"));
            s.put("majorname", majorname);
            long einum;
            if (N_Utils.isNotEmpty(majorname)) {
                einum = 0;
            } else {
                einum = users.stream().filter(u -> msid.equals(u.getMsid()) && !N_Utils.isEmptyInteger(u.getClassid()))
                             .map(EITeacherVo::getClassid).distinct().count();
                einum = classnum - einum;
            }
            s.put("einum", einum);
            for (Map sc : schoolClasses) {
                List<Map> classList = (List<Map>) sc.get("classes");
                for (Map c : classList) {
                    Integer classid = (Integer) c.get("classid");
                    List<Map> teachers = new ArrayList<>();
                    for (EITeacherVo u : users) {
                        if (msid.equals(u.getMsid()) && (1 == u.getMajored() || classid.equals(u.getClassid()))) {
                            Map t = new HashMap();
                            t.put("teacherid", u.getTeacherid());
                            t.put("username", u.getUsername());
                            t.put("loginname", u.getLoginname());
                            teachers.add(t);
                        }
                    }
                    c.put("teachers", teachers.stream().distinct().collect(Collectors.toList()));
                }
            }
            //关闭引用检测，避免循环给classes赋值出现"$ref":"$[0]"现象
            String str = JSON.toJSONString(schoolClasses, SerializerFeature.DisableCircularReferenceDetect);
            s.put("schools", JSON.parseArray(str, Map.class));
        }
        map.put("subjects", subjects);
        return map;
    }

    //计算班级数量
    private int getClassNum(List<Map<String,Object>> schoolClasses) {
        int classnum = 0;
        for (Map<String,Object> s : schoolClasses) {
            List<Map<String,Object>> classlist = (List<Map<String,Object>>) s.get("classes");
            classnum = classnum + classlist.size();
        }
        return classnum;

    }

    /**
     * @Description 监考查看
     * @Date 2024/10/18 16:02
     * @Author YWX
     * @Param [msid]
     * @Return java.util.Map
     **/
    public Map listByMsId(Integer msid) {
        //获取考试科目关联考试id
        Map examMap = subjectMapper.getESubjectByMsId(msid);
        Integer examId = Integer.parseInt(examMap.get("examid").toString());
        Integer schoolId = Integer.parseInt(examMap.get("schoolid").toString());
        Map map = new HashMap();
        List<Map<String,Object>> list = classMapper.listSchoolClassByExamId(schoolId, examId);//考试班级
        List<Map> users = msSubjectInvigilateMapper.listByMsId(msid);//单科考试监考人
        map.put("schools", list);
        map.put("teachers", users);
        return map;
    }

    /**
     * @Description 删除单科考试监考人
     * @Date 2024/10/18 16:11
     * @Author YWX
     * @Param [msid]
     * @Return void
     **/
    public void delByMsId(Integer msid) {
        msSubjectInvigilateMapper.delByMsId(msid);
        subjectMapper.updateInvigilateStateByMsId(msid, 0);//更新考试科目监考设置状态为0未设置
    }

    private List<Map> setClassList(Map map) {
        List<Map> classes = JSON.parseArray(map.get("classnames").toString(), Map.class);
        List<Map> classList = new ArrayList<>();
        Integer majored = (Integer) map.get("majored");
        if (majored == 1) {//主监考
            classList.addAll(classes);
        } else {
            String[] classids2 = map.get("classids").toString().split(",");
            for (String classid : classids2) {
                classes.stream().filter(c -> c.get("classid").toString().equals(classid)).findFirst().ifPresent(classList::add);
            }
        }
        map.remove("classids");
        map.remove("classnames");
        return classList;
    }

    /**
     * @Description 教师监考-监控列表（兼容集团校）
     * @Date 2024/10/18 16:47
     * @Author YWX
     * @Param [examid, teacherid, esstate, schoolid]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listJtJkSubject(int examid, Integer teacherid, Integer msstate, Integer schoolid) {
        int timestamp = N_Utils.getSecondTimestamp();
        String strtime = N_Utils.getStrtimeTimestamp(timestamp, "yyyy-MM-dd HH:mm:ss");
        List<Map> list = msSubjectInvigilateMapper.listJkSubject(examid, teacherid, msstate, strtime);
        for (Map map : list) {
            List<Map> classList = setClassList(map);
            List<Map> schools = new ArrayList<>();
            Map<Integer, List<Map>> collect = classList.stream().collect(Collectors.groupingBy(c -> (Integer) c.get("schoolid")));
            for (Map.Entry<Integer, List<Map>> entry : collect.entrySet()) {
                List<Map> clist = entry.getValue();
                Map school = new HashMap();
                school.put("schoolid", entry.getKey());
                for (int i = 0; i < clist.size(); i++) {
                    Map c = clist.get(i);
                    if (i == 0) {
                        school.put("schoolname", c.get("schoolname"));
                    }
                    c.remove("schoolid");
                    c.remove("schoolname");
                }
                school.put("classes", clist);
                schools.add(school);
            }
            if (schools.size() > 1) {
                //把本校放在第一个位置
                for (int i = 0; i < schools.size(); i++) {
                    Map rtnMap = schools.get(i);
                    Integer schoolid2 = Integer.parseInt(rtnMap.get("schoolid").toString());
                    if (schoolid.equals(schoolid2)) {
                        Collections.swap(schools, i, 0);
                        break;
                    }
                }
            }
            map.put("schools", schools);
        }
        return list;
    }

    /**
     * @Description 获取待监考数量
     * @Date 2024/10/18 16:52
     * @Author YWX
     * @Param [teacherid]
     * @Return java.lang.Integer
     **/
    public Integer getJtJkSubjectNum(Integer teacherid) {
        return msSubjectInvigilateMapper.getJtJkSubjectNum(teacherid);
    }
}
