package yangtz.cs.liu.campus.controller.schoolClass;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.core.utils.HolidayDateUtil;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import yangtz.cs.liu.campus.domain.SchoolStudentIntegral.SchoolStudentIntegral;
import yangtz.cs.liu.campus.domain.schoolClass.SchoolClass;
import yangtz.cs.liu.campus.domain.schoolClass.SchoolClassHeadmaster;
import yangtz.cs.liu.campus.domain.schoolClass.SchoolClassMentor;
import yangtz.cs.liu.campus.domain.schoolgrade.SchoolGrade;
import yangtz.cs.liu.campus.service.ISchoolStudentIntegra.ISchoolStudentIntegralService;
import yangtz.cs.liu.campus.service.schoolClass.ISchoolClassHeadmasterService;
import yangtz.cs.liu.campus.service.schoolClass.ISchoolClassMentorService;
import yangtz.cs.liu.campus.service.schoolClass.ISchoolClassService;
import yangtz.cs.liu.campus.service.schoolgrade.ISchoolGradeService;
import yangtz.cs.liu.campus.service.student.ISchoolStudentService;
import yangtz.cs.liu.campus.vo.schoolClass.ClassBatchVo;
import yangtz.cs.liu.campus.vo.schoolClass.ClassTreeSelect;
import yangtz.cs.liu.campus.vo.schoolClass.SchoolClassDrVo;
import yangtz.cs.liu.campus.vo.student.SchoolStudentVO;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import static com.ruoyi.common.utils.StringUtils.isNotNull;
import static org.apache.commons.lang3.StringUtils.isNotBlank;


/**
 * 班级管理
 */
@RestController
@RequestMapping("/schoolClass")
public class SchoolClassController extends BaseController {

    private Logger log = LoggerFactory.getLogger(SchoolClassController.class);

    @Autowired
    private ISchoolClassService schoolClassService;

    @Autowired
    private ISchoolGradeService schoolGradeService;

    @Autowired
    private ISchoolClassMentorService schoolClassMentorService;

    @Autowired
    private ISchoolStudentService schoolStudentService;

    @Autowired
    private ISchoolClassHeadmasterService headmasterService;

    @Autowired
    private ISchoolStudentIntegralService integralService;



    /**
     * 查询班级列表
     *
     * @param schoolClass
     * @return
     */
    @GetMapping("/list")
    public TableDataInfo list(SchoolClass schoolClass) {
        try {
            startPage();
            List<SchoolClass> list = schoolClassService.selectSchoolClassList(schoolClass);
            return getDataTable(list);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("班级管理列表异常");
        }
    }

    /**
     * 查询单个班级列表
     *
     * @param id
     * @return
     */
    @GetMapping("/queryOne/{id}")
    public AjaxResult queryOne(@PathVariable("id") Long id) {
        SchoolClass schoolClass = schoolClassService.getById(id);
        return AjaxResult.success(schoolClass);
    }

    /**
     * 新增学校班级
     *
     * @param schoolClass
     * @return
     */
    @PostMapping("/add")
    public AjaxResult add(@RequestBody @Validated SchoolClass schoolClass) {
        //根据所选学年，年级，查询所在年级id,并根据所选年级判断当前班级是否是最新学年
        SchoolGrade grade = new SchoolGrade();
        grade.setSchoolYear(schoolClass.getSchoolYear().toString());
        grade.setGradeValue(schoolClass.getGradeValue());
        List<SchoolGrade> gradeList = schoolGradeService.queryList(grade);
        if(StringUtils.isNull(gradeList) || gradeList.size() == 0){
            throw new ServiceException("所选学年，年级级部不存在");
        }
        SchoolGrade schoolGrade = gradeList.get(0);
        schoolClass.setGradeId(schoolGrade.getId());
        schoolClass.setSfzxxn(schoolGrade.getSfzxxn());
        //校验班级是否存在
        checkClassUnique(schoolClass);
        //班级类型先默认为高中
        schoolClass.setClassType("4");
        schoolClassService.save(schoolClass);
        return toAjax(isHaveTeacher(schoolClass));
    }

    /**
     * 修改学校班级
     *
     * @param schoolClass
     * @return
     */
    @PutMapping("/edit")
    public AjaxResult edit(@RequestBody @Validated SchoolClass schoolClass) {
        if (StringUtils.isNull(schoolClass.getId())) {
            throw new BaseException("修改主键id不能为空");
        }
        checkClassUnique(schoolClass);
        schoolClassService.updateById(schoolClass);
        return toAjax(isHaveTeacher(schoolClass));
    }

    private void checkClassUnique(SchoolClass schoolClass) {
        /**
         * edit on 10-29
         * 新增或修改班级管理时校验是否已经存在班级
         */
        LambdaQueryWrapper<SchoolClass> lqw = new LambdaQueryWrapper<>();
        lqw
                .eq(SchoolClass::getSchoolYear, schoolClass.getSchoolYear())
                .eq(SchoolClass::getGradeValue, schoolClass.getGradeValue())
                .eq(SchoolClass::getClassValue, schoolClass.getClassValue())
        ;
        SchoolClass aClass = schoolClassService.getOne(lqw);
        if (StringUtils.isNotNull(aClass)) {
            if (StringUtils.isNotNull(schoolClass.getId()) && schoolClass.getId().equals(aClass.getId())) {
                return;
            }
            throw new ServiceException("班级已存在");
        }
    }

    /**
     * 删除学校班级
     *
     * @param ids
     * @return
     */
    @DeleteMapping("/remove/{ids}")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult remove(@PathVariable("ids") List<Long> ids) {
        try {
            //删除班主任班级关系，班主任任期时间为当前时间
            LambdaUpdateWrapper<SchoolClassHeadmaster> masterLuw = new LambdaUpdateWrapper<>();
            masterLuw.in(SchoolClassHeadmaster::getClassId,ids).set(SchoolClassHeadmaster::getEndTime,DateUtils.getNowDate());
            headmasterService.update(masterLuw);

            //删除任科教师与班级关系，任课教师任期截止时间为当前时间
            LambdaUpdateWrapper<SchoolClassMentor> mentorLuw = new LambdaUpdateWrapper<>();
            mentorLuw.in(SchoolClassMentor::getClassId,ids).set(SchoolClassMentor::getEndTime,DateUtils.getNowDate());
            schoolClassMentorService.update(mentorLuw);

            LambdaQueryWrapper<SchoolClassMentor> lqw = new LambdaQueryWrapper<>();
            lqw.in(SchoolClassMentor::getClassId, ids);
            schoolClassMentorService.remove(lqw);
            return toAjax(schoolClassService.removeByIds(ids));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("删除数据异常");
        }
    }

    /**
     * 上传班徽
     *
     * @param file
     * @return
     */
    @PostMapping("/upload")
    public AjaxResult upload(@RequestParam("avatarfile") MultipartFile file) {
        try {
            if (!file.isEmpty()) {
                String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file);
                return AjaxResult.success(avatar);
            }
            return error();
        } catch (Exception e) {
            log.error("上传头像失败！", e);
            return error(e.getMessage());
        }
    }

    /**
     * 批量更新是否为毕业状态
     *
     * @param ids
     * @return
     */
    @PutMapping("/update/{ids}")
    public AjaxResult update(@PathVariable("ids") List<Long> ids) {

        LambdaUpdateWrapper<SchoolClass> lqw = new LambdaUpdateWrapper<>();
        lqw.in(SchoolClass::getId, ids).set(SchoolClass::getIsGraduated, 1);
        schoolClassService.update(lqw);
        return AjaxResult.success();
    }

    /**
     * @author lyric
     * @date 2022/10/30 9:49
     * <p>
     * 更改毕业状态
     */
    @PutMapping("/updateState/{id}")
    public AjaxResult updateState(@PathVariable("id") Long id, String state) {
        SchoolClass schoolClass = new SchoolClass();
        schoolClass.setIsGraduated(state);
        schoolClass.setId(id);
        return toAjax(schoolClassService.updateById(schoolClass));
    }


    /**
     * 导出
     *
     * @param response
     * @param ids
     */
    @PostMapping("/export/{ids}")
    public void export(HttpServletResponse response, @PathVariable("ids") List<Long> ids) {
        List<SchoolClass> list = schoolClassService.listByIds(ids);
        ExcelUtil<SchoolClass> util = new ExcelUtil<>(SchoolClass.class);
        util.exportExcel(response, list, "班级基本信息");
    }

    /**
     * 导出全部
     *
     * @param response
     */
    @PostMapping("/export")
    public void exportAll(HttpServletResponse response, SchoolClass schoolClass) {
        List<SchoolClass> list = schoolClassService.selectSchoolClassList(schoolClass);
        ExcelUtil<SchoolClass> util = new ExcelUtil<>(SchoolClass.class);
        util.exportExcel(response, list, "班级基本信息");
    }


    /**
     * 下载模板
     * TODO 修改班级管理导入
     * @return
     */
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil<SchoolClassDrVo> util = new ExcelUtil<>(SchoolClassDrVo.class);
        util.importTemplateExcel(response, "班级表");
    }

    /**
     * 导入
     * TODO 修改班级管理导入
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file) throws Exception {
        ExcelUtil<SchoolClassDrVo> util = new ExcelUtil<SchoolClassDrVo>(SchoolClassDrVo.class);
        List<SchoolClassDrVo> list = util.importExcel(file.getInputStream());
        //校验
        schoolClassService.checkImport(list);
        //导入
        String message = schoolClassService.importExamDetail(list);
        return AjaxResult.success(message);
    }

//    /**
//     * 下载模板
//     *
//     * @return
//     */
//    @PostMapping("/importTemplate")
//    public void importTemplate(HttpServletResponse response) {
//        ExcelUtil<SchoolClass> util = new ExcelUtil<>(SchoolClass.class);
//        util.importTemplateExcel(response, "班级表");
//    }
//
//    /**
//     * 导入
//     *
//     * @param file
//     * @return
//     * @throws Exception
//     */
//    @PostMapping("/importData")
//    public AjaxResult importData(MultipartFile file) throws Exception {
//        ExcelUtil<SchoolClass> util = new ExcelUtil<SchoolClass>(SchoolClass.class);
//        List<SchoolClass> list = util.importExcel(file.getInputStream());
//        //校验
//        schoolClassService.checkImport(list);
//        //导入
//        String message = schoolClassService.importExamDetail(list);
//        return AjaxResult.success(message);
//    }



    /**
     * 班级下拉列表，班主任工作
     */
    @GetMapping("/getClassTreeForHeader")
    public AjaxResult getClassTreeForHeader(SchoolClass schoolClass) {
        LambdaQueryWrapper<SchoolClass> lwq = new LambdaQueryWrapper<>();
        lwq
                .like(isNotBlank(schoolClass.getClassAlias()), SchoolClass::getClassAlias, schoolClass.getClassAlias())
                .eq(isNotNull(schoolClass.getSchoolYear()), SchoolClass::getSchoolYear, schoolClass.getSchoolYear())
                .eq(isNotNull(schoolClass.getClassValue()), SchoolClass::getClassValue, schoolClass.getClassValue())
                .eq(SchoolClass::getTeacherId,getUserId())
                .select(SchoolClass::getId, SchoolClass::getSchoolYear,
                        SchoolClass::getClassType, SchoolClass::getGradeValue, SchoolClass::getGradeName,
                        SchoolClass::getClassValue, SchoolClass::getClassName, SchoolClass::getClassAlias)
                .orderByAsc(SchoolClass::getSchoolYear, SchoolClass::getClassType, SchoolClass::getGradeValue, SchoolClass::getClassValue);
        List<SchoolClass> schoolClassList = schoolClassService.list(lwq);
        try {
            List<ClassTreeSelect> resList = schoolClassService.buildClassTreeList(schoolClassList);
            return AjaxResult.success(resList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("返回班级集合错误");
        }
    }

    /**
     * 班级下拉列表，教师工作
     */
    @GetMapping("/getClassTreeForMentor")
    public AjaxResult getClassTreeListForTeacher(SchoolClass schoolClass) {
        LambdaQueryWrapper<SchoolClassMentor> mentorLqw= new LambdaQueryWrapper<>();
        mentorLqw.select(SchoolClassMentor::getClassId).eq(SchoolClassMentor::getTeacherId, getUserId());
        List<SchoolClassMentor> list = schoolClassMentorService.list(mentorLqw);
        List<Long> classIds = new ArrayList<>();
        if(StringUtils.isNotNull(list) && list.size() > 0){
            for (SchoolClassMentor mentor:list){
                classIds.add(mentor.getClassId());
            }
        }else{
            return AjaxResult.success();
        }
        LambdaQueryWrapper<SchoolClass> lwq = new LambdaQueryWrapper<>();
        lwq
                .like(isNotBlank(schoolClass.getClassAlias()), SchoolClass::getClassAlias, schoolClass.getClassAlias())
                .eq(isNotNull(schoolClass.getSchoolYear()), SchoolClass::getSchoolYear, schoolClass.getSchoolYear())
                .eq(isNotNull(schoolClass.getClassValue()), SchoolClass::getClassValue, schoolClass.getClassValue())
                .in(isNotNull(classIds),SchoolClass::getId,classIds)
                .select(SchoolClass::getId, SchoolClass::getSchoolYear,
                        SchoolClass::getClassType, SchoolClass::getGradeValue, SchoolClass::getGradeName,
                        SchoolClass::getClassValue, SchoolClass::getClassName, SchoolClass::getClassAlias)
                .orderByAsc(SchoolClass::getSchoolYear, SchoolClass::getClassType, SchoolClass::getGradeValue, SchoolClass::getClassValue);
        List<SchoolClass> schoolClassList = schoolClassService.list(lwq);
        try {
            List<ClassTreeSelect> resList = schoolClassService.buildClassTreeList(schoolClassList);
            return AjaxResult.success(resList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("返回班级集合错误");
        }
    }

    /**
     * 班级下拉列表,智能排课（全部班级）
     */
    @GetMapping("/getClassTreeList")
    public AjaxResult getGradeClassTreeList(SchoolClass schoolClass) {
        LambdaQueryWrapper<SchoolClass> lwq = new LambdaQueryWrapper<>();
        lwq
                .like(isNotBlank(schoolClass.getClassAlias()), SchoolClass::getClassAlias, schoolClass.getClassAlias())
                .eq(isNotNull(schoolClass.getSchoolYear()), SchoolClass::getSchoolYear, schoolClass.getSchoolYear())
                .eq(isNotNull(schoolClass.getClassValue()), SchoolClass::getClassValue, schoolClass.getClassValue())
                .select(SchoolClass::getId, SchoolClass::getSchoolYear,
                        SchoolClass::getClassType, SchoolClass::getGradeValue, SchoolClass::getGradeName,
                        SchoolClass::getClassValue, SchoolClass::getClassName, SchoolClass::getClassAlias)
                .orderByAsc(SchoolClass::getSchoolYear, SchoolClass::getClassType, SchoolClass::getGradeValue, SchoolClass::getClassValue);
        List<SchoolClass> schoolClassList = schoolClassService.list(lwq);
        try {
            List<ClassTreeSelect> resList = schoolClassService.buildClassTreeList(schoolClassList);
            return AjaxResult.success(resList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("返回班级集合错误");
        }
    }


    /**
     * 查询班级学生信息（pc端）
     * 传了班级id，，，传了schoolYear
     * 涉及到积分，，，，查当前是上学期还是下学期，再根据学年和学期查询积分，每学期100分，在这基础上加减
     * @return
     */
    @GetMapping("/getStudentList/{classId}")
    public TableDataInfo getStudentList(@PathVariable Long classId, SchoolStudentVO schoolStudent) {
        SchoolStudentVO vo = new SchoolStudentVO();
        vo.setClassId(classId);
        startPage();
        List<SchoolStudentVO> list = schoolStudentService.queryList(vo);
        int term = HolidayDateUtil.getTerm();
        for(SchoolStudentVO studentVO : list){
            double sum=100;
            SchoolStudentIntegral i = new SchoolStudentIntegral();
            i.setStudentId(studentVO.getId());
            i.setSchoolYear(schoolStudent.getSchoolYear());
            i.setTerm(term);
            List<SchoolStudentIntegral> integrals = integralService.selectSchoolStudentIntegralList(i);
            if(StringUtils.isNotNull(integrals) && integrals.size() > 0){
                for(SchoolStudentIntegral integral : integrals){
                    //“0”惩罚。。。“1”奖励
                    if("0".equals(integral.getIsReward())){
                        sum = sum - integral.getScore();
                    }else {
                        sum = sum + integral.getScore();
                    }
                }
            }
            studentVO.setScore(sum);
        }
       /* LambdaQueryWrapper<SchoolStudent> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SchoolStudent::getClassId, classId);
        return getDataTable(schoolStudentService.list(lqw));*/
        return getDataTable(list);
    }

    /**
     * 查询班级老师信息（pc端）
     *
     * @return
     */
    @GetMapping("/getTeacherList/{classId}")
    public TableDataInfo getTeacherList(@PathVariable Long classId, SchoolClassMentor schoolClassMentor) {
        schoolClassMentor.setClassId(classId);
        startPage();
        return getDataTable(schoolClassService.getTeacherList(schoolClassMentor));
    }

    //判断班级是否选择了班主任，如果选择了班主任，则需要写入班主任和班级表，班主任修改时，写入班主任和班级表，原班主任和班级关系删掉
    private boolean isHaveTeacher(SchoolClass schoolClass) {
        //判断是否有班主任
        if (StringUtils.isNull(schoolClass.getTeacherId())) {
            return true;
        }
        //判断是新增还是修改
        LambdaQueryWrapper<SchoolClassHeadmaster> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SchoolClassHeadmaster::getClassId, schoolClass.getId());
        //查询这个班之前是否有班主任
        SchoolClassHeadmaster formHeadmaster = headmasterService.getOne(lqw);
        //如果之前没有班主任
        if (StringUtils.isNull(formHeadmaster)) {
            if (StringUtils.isNotNull(schoolClass.getTeacherId())) {
                SchoolClassHeadmaster headmaster = new SchoolClassHeadmaster();
                headmaster.setTeacherId(schoolClass.getTeacherId());
                headmaster.setClassId(schoolClass.getId());
                headmaster.setStartTime(DateUtils.getNowDate());
                headmaster.insert();
                return headmasterService.save(headmaster);
            }
            //之前没有班主任，新增班级时也没有选择班主任
            return true;
        }
        //修改，有班主任，判断班主任是否更换
        if (StringUtils.isNotNull(schoolClass.getTeacherId())) {
            //班主任没有发生更换
            if (formHeadmaster.getTeacherId().equals(schoolClass.getTeacherId())) {
                return true;
            }

            //班主任发生更换，删除原班主任班级关系，再添加新的关系
            formHeadmaster.setEndTime(DateUtils.getNowDate());
            formHeadmaster.update();
            headmasterService.updateById(formHeadmaster);
            headmasterService.removeById(formHeadmaster.getId());

            SchoolClassHeadmaster headmaster = new SchoolClassHeadmaster();
            headmaster.setTeacherId(schoolClass.getTeacherId());
            headmaster.setClassId(schoolClass.getId());
            headmaster.setStartTime(DateUtils.getNowDate());
            headmaster.insert();
            return headmasterService.save(headmaster);
        }
        //修改时，没有选择班主任，或者是将原来的班主任划掉了， 将原来选择的班主任与班级关系去掉
        formHeadmaster.setEndTime(DateUtils.getNowDate());
        formHeadmaster.update();
        headmasterService.updateById(formHeadmaster);
        return headmasterService.removeById(formHeadmaster.getId());
    }


    /**
     * 异动新增页面的班级下拉框
     * 班级下拉列表 （全部班级）
     */
    @GetMapping("/getClassTree")
    public AjaxResult getClassTree() {
        int y = getNewYear();
        LambdaQueryWrapper<SchoolClass> lwq = new LambdaQueryWrapper<>();
        lwq
                .eq( SchoolClass::getSchoolYear, y)
                .select(SchoolClass::getId, SchoolClass::getSchoolYear,
                        SchoolClass::getClassType, SchoolClass::getGradeValue, SchoolClass::getGradeName,
                        SchoolClass::getClassValue, SchoolClass::getClassName, SchoolClass::getClassAlias)
                .orderByAsc(SchoolClass::getSchoolYear, SchoolClass::getClassType, SchoolClass::getGradeValue, SchoolClass::getClassValue);
        List<SchoolClass> schoolClassList = schoolClassService.list(lwq);
        try {
            List<ClassTreeSelect> resList = schoolClassService.buildClassTreeList(schoolClassList);
            return AjaxResult.success(resList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("返回班级集合错误");
        }
    }

    /**获取最新学年值*/
    public int getNewYear(){
        Calendar cal = Calendar.getInstance();
        //获取当前年月
        int nowYear = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        //设置当前学期
        int term = 1;
        //2-7为第二学期，8-1为第一学期
        //如果当前月份小于8月，则该学年应为当前年-1 到 当前年,例如当前年月为2023年7月，则该学年为2022-2023年的第二学期
        if (month < 8) {
            nowYear = nowYear - 1;
        }
        if (month >= 2 && month < 8) {
            term = 2;
        }
        return nowYear;
    }

    /**批量设置*/
    @PostMapping("/batchAdd")
    public AjaxResult batchAdd(@RequestBody @Validated ClassBatchVo vo) {
        //首先判断该学年是否已存在班级，如果存在，则不能新增班级
        LambdaQueryWrapper<SchoolClass> lqw = new LambdaQueryWrapper<>();
        lqw.eq(SchoolClass::getSchoolYear,vo.getSchoolYear());
        List<SchoolClass> list = schoolClassService.list(lqw);
        if(StringUtils.isNotNull(list) && list.size() > 0){
            throw new ServiceException("当前学年已存在班级，不允许批量新增");
        }
        //先做下限制
        if(vo.getClassNum1() > 32 || vo.getClassNum2() > 32 || vo.getClassNum3() > 32){
            throw new ServiceException("目前只支持最大创建32个班级");
        }
        return toAjax(schoolClassService.batchAdd(vo));
    }

}
