package com.xhkjedu.sexam.service.exam;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xhkjedu.sexam.mapper.exam.EBaseMapper;
import com.xhkjedu.sexam.mapper.exam.EClassMapper;
import com.xhkjedu.sexam.mapper.exam.ESubjectInvigilateMapper;
import com.xhkjedu.sexam.mapper.exam.ESubjectMapper;
import com.xhkjedu.sexam.model.exam.ESubjectInvigilate;
import com.xhkjedu.sexam.vo.exam.EITeacherVo;
import com.xhkjedu.sexam.vo.paper.EPTeacherVo;
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;

@Service
public class ESubjectInvigilateService {
    @Resource
    private ESubjectInvigilateMapper eSubjectInvigilateMapper;
    @Resource
    private EBaseMapper eBaseMapper;
    @Resource
    private ESubjectMapper eSubjectMapper;
    @Resource
    private EClassMapper eClassMapper;

    //设置监考人--设置
    @Transactional(rollbackFor = Exception.class)
    public void setTeacher(Integer esid, String subjectid, Integer createid, List<ESubjectInvigilate> teachers) {
        eSubjectInvigilateMapper.delByEsId(esid);//删除考试科目监考教师
        int timestamp = N_Utils.getSecondTimestamp();
        teachers.forEach(t -> {
            t.setEsid(esid);
            t.setSubjectid(subjectid);
            t.setCreateid(createid);
            t.setCreatetime(timestamp);
        });
        eSubjectInvigilateMapper.insertList(teachers);
    }

    //监考设置列表
    public Map listSubject(Integer examid) {
        Map map = eBaseMapper.findById(examid);
        List<Map> subjects = eSubjectInvigilateMapper.listSubject(examid);//监考设置列表
        String esids = subjects.stream().map(s -> s.get("esid").toString()).collect(Collectors.joining(","));
        List<EITeacherVo> users = eSubjectInvigilateMapper.listUserByEsIds(esids);
        Integer schoolid = Integer.parseInt(map.get("schoolid").toString());
        List<Map> schoolClasses = eClassMapper.listSchoolClassByExamid(schoolid,examid);//考试班级
        int classnum = getClassNum(schoolClasses);
        for (Map s : subjects) {
            Integer esid = (Integer) s.get("esid");
            if (N_Utils.isListEmpty(users)) users = new ArrayList<>();
            String majorname = users.stream().filter(u -> esid.equals(u.getEsid()) && u.getMajored() == 1)
                    .map(u -> u.getUsername()).distinct().collect(Collectors.joining("、"));
            s.put("majorname", majorname);
            long einum;
            if (N_Utils.isNotEmpty(majorname)) {
                einum = 0;
            } else {
                einum = users.stream().filter(u -> esid.equals(u.getEsid()) && !N_Utils.isEmptyInteger(u.getClassid()))
                        .map(u -> u.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(esid.equals(u.getEsid())&& (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> schoolClasses){
        int classnum = 0;
        for(Map s : schoolClasses){
            List<Map> classlist = (List<Map>) s.get("classes");
            classnum = classnum + classlist.size();
        }
        return classnum;

    }

    /*
     * @Description 监考查看
     * @Date 2023/8/29 15:54:57
     * @Author WN
     * @Param [esid 考试科目id]
     * @Return java.util.Map
     **/
    public Map listByEsId(Integer esid) {
        //获取考试科目关联考试id
        Map examMap = eSubjectMapper.getESubjectByEsId(esid);
        Integer examId = Integer.parseInt(examMap.get("examid").toString());
        Integer schoolId = Integer.parseInt(examMap.get("schoolid").toString());
        Map map = new HashMap();
        List<Map> list = eClassMapper.listSchoolClassByExamid(schoolId,examId);//考试班级
        List<Map> users = eSubjectInvigilateMapper.listByEsId(esid);//考试监考人
        map.put("schools", list);
        map.put("teachers", users);
        return map;
    }


    //监考人删除
    public void delByEsId(Integer esid) {
        eSubjectInvigilateMapper.delByEsId(esid);//删除考试科目监考教师
    }

    //教师监考-监控列表
    public List<Map> listJkSubject(Integer examid, Integer teacherid, Integer esstate) {
        int timestamp = N_Utils.getSecondTimestamp();
        String strtime = N_Utils.getStrtimeTimestamp(timestamp, "yyyy-MM-dd HH:mm:ss");
        List<Map> list = eSubjectInvigilateMapper.listJkSubject(examid, teacherid, esstate, strtime);
        for (Map map : list) {
            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) {
                    Map cmap = classes.stream().filter(c -> c.get("classid").toString().equals(classid)).findFirst().orElse(null);
                    if (cmap != null) classList.add(cmap);
                }
            }
            map.remove("classids");
            map.remove("classnames");
            map.put("classList", classList);
        }
        return list;
    }

    /**
     * @Description 教师监考-监控列表（兼容集团校）
     * @Date 2023/8/30 15:24
     * @Author YWX
     * @Param [examid, teacherid, esstate, schoolid]
     * @Return java.util.List<java.util.Map>
     **/
    public List<Map> listJtJkSubject(Integer examid, Integer teacherid, Integer esstate, Integer schoolid) {
        int timestamp = N_Utils.getSecondTimestamp();
        String strtime = N_Utils.getStrtimeTimestamp(timestamp, "yyyy-MM-dd HH:mm:ss");
        List<Map> list = eSubjectInvigilateMapper.listJkSubject(examid, teacherid, esstate, strtime);
        for (Map map : list) {
            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) {
                    Map cmap = classes.stream().filter(c -> c.get("classid").toString().equals(classid)).findFirst().orElse(null);
                    if (cmap != null) classList.add(cmap);
                }
            }
            map.remove("classids");
            map.remove("classnames");
            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;
    }

    //根据考试科目id获取考试科目基本信息
    public Map getESubjectByEsId(Integer esid) {
        return eSubjectMapper.getESubjectByEsId(esid);
    }

    //缺考学生列表
    public List<Map> listMissStu(EPTeacherVo vo) {
        return eSubjectInvigilateMapper.listMissStu(vo);
    }

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