package com.xhkjedu.sexam.controller.exam;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xhkjedu.annotation.Action;
import com.xhkjedu.sexam.model.exam.EBase;
import com.xhkjedu.sexam.model.exam.EClassStudent;
import com.xhkjedu.sexam.model.exam.ESubject;
import com.xhkjedu.sexam.model.notice.TMsg;
import com.xhkjedu.sexam.model.notice.TNotice;
import com.xhkjedu.sexam.model.notice.TNoticeUser;
import com.xhkjedu.sexam.service.exam.EBaseService;
import com.xhkjedu.sexam.service.notice.NoticeService;
import com.xhkjedu.sexam.service.report.EReportGenerateService;
import com.xhkjedu.sexam.vo.exam.EBaseVo;
import com.xhkjedu.sexam.vo.exam.ExamVo;
import com.xhkjedu.vo.exam.EPaperVo;
import com.xhkjedu.utils.DatesUtil;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.utils.PageUtil;
import com.xhkjedu.vo.PageResult;
import com.xhkjedu.vo.ResultVo;
import com.xhkjedu.vo.system.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author ywx
 * @classname EBaseController
 * @description 考试基础信息
 * @date 2022/7/18 9:26
 **/
@Slf4j
@RestController
@RequestMapping("/eb")
public class EBaseController {
    @Resource
    private EBaseService eBaseService;
    @Resource
    private NoticeService noticeService;
    @Resource
    private EReportGenerateService eReportGenerateService;

    /**
     * 发起考试
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/7/18 10:15
     **/
    @PostMapping("/add")
    @Action("考试测评-增加")
    public ResultVo add(@RequestBody EBase eBase) {
        if (N_Utils.isListEmpty(eBase.getClassids())) return new ResultVo(1, "考试班级不能为空");
        if (N_Utils.isListEmpty(eBase.getSubjects())) return new ResultVo(1, "考试科目不能为空");
        if (DatesUtil.dateNan(eBase.getExamdate())) {
            return new ResultVo(1, "日期格式不正确");
        }
        return eBaseService.save(eBase);
    }

    /**
     * 考试设置
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [subjects]
     * @Author ywx
     * @Date 2022/7/18 10:52
     **/
    @PostMapping("/set_exam")
    @Action("考试测评-设置时间")
    public ResultVo setExam(@RequestBody ExamVo map) {
        Integer notice = map.getNotice();//是否发送通知1发送2不发送
        Integer msg = map.getMsg();//是否发送短信1发送2不发送
        List<ESubject> subjects = map.getSubjects();
        Integer schoolid = map.getSchoolid();
        Integer createid = map.getHandleid();
        Integer examid = map.getExamid();
        N_Utils.validation(new Object[]{schoolid, "学校id", 1, createid, "操作人id", 1, examid, "考试id", 1});
        EBaseVo vo = eBaseService.getExamStateAndMode(examid);
        if (2 <= vo.getExamstate()) return new ResultVo(1, "考试已结束禁止操作");

        if (DatesUtil.dateNan(JSON.toJSONString(subjects))) {
            return new ResultVo(1, "日期格式不正确");
        }
        if (vo.getExammode() == 1) {//线上的考试必须有时间
            for (ESubject es : subjects) {
                if (N_Utils.isEmpty(es.getSdate()) || N_Utils.isEmpty(es.getBegintime()) || N_Utils.isEmpty(es.getEndtime())) {
                    return new ResultVo(1, "考试时间不能为空");
                }
            }
        }
        List<TNotice> noticeList = new ArrayList<>();
        List<TMsg> msgList = new ArrayList<>();
        String examname = eBaseService.getNameByExamId(examid);
        String noticetitle = examname + "-考试设置";
        Integer gradeid = vo.getGradeid();
        for (ESubject s : subjects) {
            try {
                N_Utils.validation(new Object[]{s.getSubjectid(), "科目id", 2});
                s.setExamid(examid);
                Integer teacherid = s.getTeacherid();
                if (N_Utils.isEmptyInteger(teacherid)) continue;
                String noticecontent = "【" + s.getSubjectname() + "】";
                if (N_Utils.isNotEmpty(s.getSdate())) {
                    noticecontent += s.getSdate() + " " + s.getBegintime() + "-" + s.getEndtime() + "\n请在规定时间段出卷";
                }
                if (notice == 1) {
                    TNotice n = new TNotice();
                    n.setNoticetitle(noticetitle);
                    n.setNoticecontent(noticecontent);
                    TNoticeUser nt = new TNoticeUser();
                    nt.setUserid(teacherid);
                    nt.setGradeid(gradeid);
                    nt.setSubjectid(s.getSubjectid());
                    n.setUsers(Arrays.asList(nt));
                    noticeList.add(n);
                }
                if (msg == 1) {
                    TMsg m = new TMsg();
                    m.setMsgtxt(noticetitle + "\n" + noticecontent);
                    m.setUserid(teacherid);
                    msgList.add(m);
                }
            } catch (Exception e) {
                return new ResultVo(1, e.getMessage());
            }
        }
        eBaseService.setExam(subjects, createid);
        
        noticeService.batchSave(noticeList, msgList, schoolid, createid, 2);
        return new ResultVo(0, "设置成功");
    }

    /**
     * 考试删除
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/7/18 11:30
     **/
    @PostMapping("/delete")
    @Action("考试测评-删除")
    public ResultVo delete(@RequestBody EBase eBase) {
        N_Utils.validation(new Object[]{eBase.getExamid(), "考试id", 1});
        eBaseService.deleteById(eBase.getExamid());
        return new ResultVo(0, "删除成功");
    }

    /**
     * 考试修改
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/7/18 11:30
     **/
    @PostMapping("/update")
    @Action("考试测评-修改")
    public ResultVo update(@RequestBody EBase eBase) {
        N_Utils.validation(new Object[]{eBase.getExamid(), "考试id", 1});
        return eBaseService.update(eBase);
    }

    @PostMapping("/detail")
    public ResultVo detail(@RequestBody EBase eBase) {
        Map base = eBaseService.findById(eBase.getExamid());
        return new ResultVo(0, "获取详情成功", base);
    }

    @PostMapping("/list")
    public ResultVo list(@RequestBody EBase eBase) {
        N_Utils.validation(new Object[]{eBase.getSchoolid(), "学校id"
                , 1, eBase.getPage(), "页码", 1, eBase.getPageSize(), "显示条数", 1});
        if(N_Utils.isTrueInteger(eBase.getCreateid())){
            Integer usertype = eBaseService.getUsertypeByUserid(eBase.getCreateid());
            if(usertype==0){
                eBase.setCreateid(0);
            }
        }
        PageHelper.startPage(eBase.getPage(), eBase.getPageSize());
        List<Map> list = eBaseService.listAll(eBase);
        PageResult pageResult = PageUtil.getPageResult(new PageInfo(list));
        return new ResultVo(0, "获取列表成功", pageResult);
    }

    /**
     * 发布考试
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/7/18 15:21
     **/
    @PostMapping("/fb")
    @Action("考试测评-发布考试")
    public ResultVo postExam(@RequestBody ExamVo vo) {
        Integer notice = vo.getNotice();//是否发送通知1发送2不发送
        Integer msg = vo.getMsg();//是否发送短信1发送2不发送
        String examcomm = vo.getExamcomm();
        Integer createid = vo.getHandleid();
        Integer examid = vo.getExamid();
        N_Utils.validation(new Object[]{examid, "考试id", 1, examcomm, "考试公告", 2, createid, "操作人id", 1});
        EBaseVo exam = eBaseService.getExamStateById(examid);//根据考试id获取考试状态
        String examname = exam.getExamname();
        Integer schoolid = exam.getSchoolid();
        if (exam.getExammode() == 1 && " :00".equals(exam.getStrtime())) return new ResultVo(1, "还有考试试卷未设置时间");
        if (exam.getWwcnum() != 0) return new ResultVo(1, "还有考试试卷未设置完成");
        if (exam.getAnswered() == 0) return new ResultVo(1, "还有考试试卷未设置正确答案");
        if (exam.getExamstate() != 0) return new ResultVo(0, "发布成功");

        List<UserVo> students = eBaseService.listStuByExamId(examid);//获取考生
        Integer code = eBaseService.updateExamStateStart(examid, examcomm, students, exam.getExammode(),schoolid);//发布考试
        if (code == 1) return new ResultVo(1, "发布考试失败");

        if (notice == 2 && msg == 2) return new ResultVo(0, "发布成功");

        vo.setSchoolid(schoolid);
        vo.setHandleid(createid);
        vo.setExamname(examname);
        vo.setGradeid(exam.getGradeid());
        noticeService.batchSave2(vo, students);
        return new ResultVo(0, "发布成功");
    }

    /*
     * 保存发布信息
     * @Param [vo]
     * @Author ywx
     * @Date 9:09 2022/8/2
     * @return com.xhkjedu.vo.ResultVo
     **/
    @PostMapping("/save_fb")
    @Action("考试测评-保存发布信息")
    public ResultVo savePostExam(@RequestBody ExamVo vo) {
        String examcomm = vo.getExamcomm();
        Integer examid = vo.getExamid();
        N_Utils.validation(new Object[]{examid, "考试id", 1, examcomm, "考试公告", 2});
        Integer examstate = eBaseService.getExamState(examid);
        if (2 <= examstate) return new ResultVo(1, "考试已结束禁止操作");
        eBaseService.savePostExam(examid, examcomm);
        return new ResultVo(0, "保存成功");
    }

    /**
     * 结束考试
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/7/18 15:28
     **/
    @PostMapping("/js")
    @Action("考试测评-结束考试")
    public ResultVo endExam(@RequestBody EBase eBase) {
        Integer examid = eBase.getExamid();
        Integer createid = eBase.getCreateid();
        N_Utils.validation(new Object[]{examid, "考试id", 1, createid, "操作人id", 1});
        EBaseVo vo = eBaseService.getExamStateAnseredById(examid);//获取考试状态和是否设置答案
        //非进行中的考试结束不处理数据，直接返回结束成功
        Integer exammode = vo.getExammode();
        if (2 == exammode && 1 != vo.getAnswered()) return new ResultVo(1, "试卷未设答案");
        //没有一科结束的考试不能结束
        if (1 == exammode && 0 == vo.getAnswered()) return new ResultVo(1, "考试未结束");
        if (1 != vo.getExamstate()) return new ResultVo(0, "结束成功");
        try {
            eBase.setExammode(exammode);
            eBaseService.updateExamStateEnd(eBase);

            eReportGenerateService.generateExamReport(eBase.getExamid(), eBase.getCreateid());
            return new ResultVo(0, "结束成功");
        } catch (Exception e) {
            log.error("结束出错："+e.getMessage());
            return new ResultVo(1, "结束失败");
        }
    }

    /**
     * 获取考试班级
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/7/18 16:12
     **/
    @PostMapping("/list_class")
    public ResultVo listClass(@RequestBody EBase eBase) {
        Integer examid = eBase.getExamid();
        N_Utils.validation(new Object[]{examid, "考试id", 1});
        List<Map> list = eBaseService.listClass(examid);
        return new ResultVo(0, "获取考试班级成功", list);
    }

    /**
     * 考生管理--获取考试和班级信息
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/7/19 10:56
     **/
    @PostMapping("/get_eclass")
    public ResultVo getExamAndClass(@RequestBody EBase eBase) {
        Integer examid = eBase.getExamid();
        N_Utils.validation(new Object[]{examid, "考试id", 1});
        Map map = eBaseService.getExamAndClass(examid);
        return new ResultVo(0, "获取考试班级成功", map);
    }

    /**
     * 考生管理--获取考试学生
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/7/18 16:57
     **/
    @PostMapping("/list_stu")
    public ResultVo listStu(@RequestBody EClassStudent cs) {
        Integer examid = cs.getExamid();
        Integer schoolid = cs.getSchoolid();
        Integer page = cs.getPage();
        Integer pageSize = cs.getPageSize();
        N_Utils.validation(new Object[]{examid, "考试id", 1,schoolid,"学校id",1});
        if (N_Utils.isEmptyInteger(page)) {
            List<Map> list = eBaseService.listStu(cs);
            return new ResultVo(0, "获取考试学生成功", list);
        } else {
            PageHelper.startPage(page, pageSize);
            List<Map> list = eBaseService.listStu(cs);
            PageResult pageResult = PageUtil.getPageResult(new PageInfo<>(list));
            return new ResultVo(0, "获取考试学生成功", pageResult);
        }
    }

    /**
     * 考生管理--移除学生
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [student]
     * @Author ywx
     * @Date 2022/7/19 11:34
     **/
    @PostMapping("/del_stu")
    @Action("考试测评-删除学生")
    public ResultVo delStu(@RequestBody EClassStudent student) {
        Integer ecsid = student.getEcsid();
        N_Utils.validation(new Object[]{ecsid, "考试id", 1});
        return eBaseService.delStu(ecsid);
    }

    /**
     * 考试科目列表
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/7/19 9:03
     **/
    @PostMapping("/list_subject")
    public ResultVo listSubject(@RequestBody EBase eBase) {
        Integer examid = eBase.getExamid();
        N_Utils.validation(new Object[]{examid, "考试id", 1});
        Map map = eBaseService.listSubject(examid);
        return new ResultVo(0, "获取考试科目列表成功", map);
    }

    /**
     * 设置出卷人
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [subject]
     * @Author ywx
     * @Date 2022/7/27 17:28
     **/
    @PostMapping("/set_st")
    @Action("考试测评-设置出卷人")
    public ResultVo setSubjectTeacher(@RequestBody ESubject subject) {
        Integer esid = subject.getEsid();
        Integer teacherid = subject.getTeacherid();
        N_Utils.validation(new Object[]{esid, "考试科目id", 1, teacherid, "出卷人", 1});
        Integer examstate = eBaseService.getExamStateByEsId(esid);
        if (2 <= examstate) return new ResultVo(1, "考试已结束禁止修改");
        eBaseService.setSubjectTeacher(subject);
        return new ResultVo(0, "设置成功");
    }

    /**
     * 考试设置状态
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/7/28 9:37
     **/
    @PostMapping("/get_set")
    public ResultVo getSetState(@RequestBody EBase eBase) {
        Integer examid = eBase.getExamid();
        N_Utils.validation(new Object[]{examid, "考试id", 1});
        Map map = eBaseService.getSetState(examid);
        return new ResultVo(0, "获取考试设置状态成功", map);
    }

    /**
     * 获取mac编号
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [mac]
     * @Author ywx
     * @Date 2022/8/10 17:40
     **/
    @PostMapping("/get_mn")
    public ResultVo getMacNumber(@RequestBody String mac) {
        N_Utils.validation(new Object[]{mac, "硬件地址", 2});
        String macNumber = eBaseService.getMacNumber(mac);
        return new ResultVo(0, "获取mac编号成功", macNumber);
    }

    /**
     * 考试科目选择列表
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/9/7 14:23
     **/
    @PostMapping("/list_selsub")
    public ResultVo listSubjectForSel(@RequestBody EBase eBase) {
        Integer examid = eBase.getExamid();
        N_Utils.validation(new Object[]{examid, "考试id", 1});
        List<Map> list = eBaseService.listSubjectForSel(examid);
        return new ResultVo(0, "获取考试科目列表成功", list);
    }

    /**
     * 生成考试报告
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/9/8 9:56
     **/
    @PostMapping("/scbg")
    @Action("考试测评-生成报告")
    public ResultVo generateExamReport(@RequestBody EBase eBase) {
        Integer examid = eBase.getExamid();
        Integer createid = eBase.getCreateid();
        N_Utils.validation(new Object[]{examid, "考试id", 1, createid, "操作人", 1});
        try {
            eBaseService.generateExamReport(examid, createid);
            return new ResultVo(0, "生成成功");
        } catch (Exception e) {
            log.error("生成失败：" + e.getMessage());
            return new ResultVo(1, "生成失败");
        }
    }

    /**
     * 班级选择列表
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/9/15 11:35
     **/
    @PostMapping("/list_bj")
    public ResultVo listBj(@RequestBody EBase eBase) {
        Integer schoolid = eBase.getSchoolid();
        N_Utils.validation(new Object[]{schoolid, "学校id", 1});
        List<Map> list = eBaseService.listBj(schoolid, eBase.getCreateid());
        return new ResultVo(0, "获取班级列表成功", list);
    }

    /**
     * 获取考试状态
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/9/30 14:28
     **/
    @PostMapping("/get_zt")
    public ResultVo getExamState(@RequestBody EBase eBase) {
        Integer examid = eBase.getExamid();
        N_Utils.validation(new Object[]{examid, "考试id", 1});
        Integer examstate = eBaseService.getExamState(examid);
        return new ResultVo(0, "获取考试状态成功", examstate);
    }

    @PostMapping("/gettime")
    public ResultVo getNowTimestamp(@RequestBody EBase eBase) {
        Integer timestamp = N_Utils.getSecondTimestamp();
        return new ResultVo(0, "获取当前时间戳", timestamp);
    }

    /*
     * 考试未批阅试题数量
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/10/31 23:04
     * @return com.xhkjedu.vo.ResultVo
     **/
    @PostMapping("/ncn")
    public ResultVo getNoCheckNum(@RequestBody EBase eBase) {
        Integer examid = eBase.getExamid();
        N_Utils.validation(new Object[]{examid, "考试id", 1});
        Integer num = eBaseService.getNoCheckNum(examid);
        return new ResultVo(0, "获取考试未批阅试题数量成功", num);
    }

    /*
     * 缺考详情
     * @Param [vo]
     * @Author ywx
     * @Date 2022/11/9 17:24
     * @return com.xhkjedu.vo.ResultVo
     **/
    @PostMapping("/list_qkd")
    public ResultVo listQkDetail(@RequestBody EPaperVo vo) {
        Integer epid = vo.getEpid();
        Integer schoolid = vo.getSchoolid();
        N_Utils.validation(new Object[]{epid, "试卷id", 1,schoolid,"学校id",1});
        List<Map> list = eBaseService.listQkDetail(epid,schoolid);
        return new ResultVo(0, "获取缺考详情成功", list);
    }

    /*
     * 设置学生报告排名显示
     * @Param [eBase]
     * @Author ywx
     * @Date 2022/11/14 15:19
     * @return com.xhkjedu.vo.ResultVo
     **/
    @PostMapping("/set_show")
    public ResultVo setShowRank(@RequestBody EBase eBase) {
        N_Utils.validation(new Object[]{eBase.getExamid(), "考试id", 1});
        eBaseService.setShowRank(eBase);
        return new ResultVo(0, "设置成功");
    }

    /*
     * @Description 获取考试关联学校
     * @Date 2023/8/29 14:17:16
     * @Author WN
     * @Param [eBase]
     * @Return com.xhkjedu.vo.ResultVo
     **/
    @PostMapping("/list_school")
    public ResultVo listExamSchool(@RequestBody EBase eBase) {
        N_Utils.validation(new Object[]{eBase.getExamid(), "考试id", 1});
        List<Map> list = eBaseService.listSchoolsByExamid(eBase.getExamid());
        return new ResultVo(0, "获取考试关联学校成功",list);
    }

    /*
     * 处理班级试题作答详情和满分
     * @Param []
     * @Author ywx
     * @Date 2022/11/23 15:13
     * @return com.xhkjedu.vo.ResultVo
     **/
    @GetMapping("/handle_answerjson")
    public ResultVo handleAnswerjson() {
        eReportGenerateService.handleAnswerjson();
        return new ResultVo(0, "设置成功");
    }

    @GetMapping("/handle_action")
    public ResultVo handleClassAction() {
        eReportGenerateService.updateClassStuAction();
        return new ResultVo(0, "设置成功");
    }
}
