package yangtz.cs.liu.campus.service.impl.schoolgrade;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.core.domain.Ztree;
import com.core.utils.HolidayDateUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yangtz.cs.liu.campus.domain.schoolClass.SchoolClass;
import yangtz.cs.liu.campus.domain.schoolgrade.SchoolGrade;
import yangtz.cs.liu.campus.mapper.schoolClass.SchoolClassMapper;
import yangtz.cs.liu.campus.mapper.schoolgrade.SchoolGradeMapper;
import yangtz.cs.liu.campus.service.schoolgrade.ISchoolGradeService;
import yangtz.cs.liu.campus.vo.schoolgrade.GradeTreeSelect;

import java.util.*;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank;
import static com.ruoyi.common.utils.StringUtils.isNotNull;
import static yangtz.cs.liu.campus.constant.ClassConstant.*;
import static yangtz.cs.liu.campus.constant.GradeConstant.*;

@Service
public class ISchoolGradeImpl extends ServiceImpl<SchoolGradeMapper, SchoolGrade> implements ISchoolGradeService {

    @Autowired
    private SchoolGradeMapper schoolGradeMapper;

    @Autowired
    private SchoolClassMapper classMapper;


    @Override
    public List<SchoolGrade> queryList(SchoolGrade schoolGrade) {
        LambdaQueryWrapper<SchoolGrade> lqw = new LambdaQueryWrapper<>();
        lqw
                .eq(isNotNull(schoolGrade.getSchoolYear()), SchoolGrade::getSchoolYear, schoolGrade.getSchoolYear())
                .eq(isNotNull(schoolGrade.getGradeValue()), SchoolGrade::getGradeValue, schoolGrade.getGradeValue())
                .eq(isNotBlank(schoolGrade.getSfzxxn()), SchoolGrade::getSfzxxn, schoolGrade.getSfzxxn())
                .orderByAsc(SchoolGrade::getSfzxxn)
                .orderByDesc(SchoolGrade::getSchoolYear)
                .orderByAsc(SchoolGrade::getGradeValue);
        return schoolGradeMapper.selectList(lqw);
    }


    @Override
    public List<String> selectSchoolYearGruoUp() {
        return schoolGradeMapper.selectSchoolYearGruoUp();
    }

    //判断所在班级所在级部（存在一个老师跨几个级部教学，比如体育老师，所以获取教授班级所在级部，随便选择某个级部即可）
    @Override
    public Long getGradeId(Long userId) {
        //获取当前学年
//        int schoolYear = HolidayDateUtil.getSchoolYear();
        // TODO 修改最新学年
        int schoolYear = schoolGradeMapper.isNewSchoolYear();
        //如果是管理员
        if(1L == userId){
            List<Long> idList = schoolGradeMapper.getGradeIdsByYear(schoolYear);
            if(StringUtils.isNull(idList) || idList.size() == 0){
                throw new ServiceException("当前学年为" + schoolYear + "学年，该学年没有级部信息");
            }
            return idList.get(0);
        }
        //教师通道
        List<Long> idList = schoolGradeMapper.getGradeId(userId, schoolYear);
        if (StringUtils.isNull(idList) || idList.size() == 0) {
            throw new ServiceException("当前学年为" + schoolYear + "学年，该学年没有您所在的级部信息");
        }
        return idList.get(0);
    }

    //判断级部成员所在级部（存在一个老师跨几个级部，随便选择某个级部即可）
    @Override
    public Long getMemberGrade(Long userId) {
        //获取当前学年
//        int schoolYear = HolidayDateUtil.getSchoolYear();
        // TODO 修改最新学年
        int schoolYear = schoolGradeMapper.isNewSchoolYear();
        //如果是级部成员
        List<Long> ids = schoolGradeMapper.getMemberGradeId(userId, schoolYear);
        if (StringUtils.isNull(ids) || ids.size() == 0) {

            throw new ServiceException("当前学年为" + schoolYear + "学年，该学年没有您所在的级部信息");
        }
        return ids.get(0);
    }

    @Override
    public List<GradeTreeSelect> buildGradeTreeList(List<SchoolGrade> gradeList) {
        // stream 先分组 年份->级部名称->年级列表
        Map<java.lang.String, Map<java.lang.String, List<SchoolGrade>>> map =
                gradeList.stream().collect(Collectors.groupingBy(SchoolGrade::getSchoolYear, LinkedHashMap::new,
                        Collectors.groupingBy(SchoolGrade::getGradeName, LinkedHashMap::new, Collectors.toList())));

        /**
         * id 表示年级的id
         *  label 表示 显示的标签
         *  children 表示子节点
         */
        List<GradeTreeSelect> resList = new ArrayList<>();
        // 年度
        for (Map.Entry<java.lang.String, Map<java.lang.String, List<SchoolGrade>>> yearEntry : map.entrySet()) {
            GradeTreeSelect year = new GradeTreeSelect();
            year.setId(0L);
            year.setLabel(yearEntry.getKey().toString());
            List<GradeTreeSelect> yearList = new ArrayList<>();
            year.setChildren(yearList);
            //级部名称
            for (Map.Entry<java.lang.String, List<SchoolGrade>> gradeEntry : yearEntry.getValue().entrySet()) {
                GradeTreeSelect select = new GradeTreeSelect();
                select.setLabel(gradeEntry.getValue().get(0).getGradeName());
                select.setId(gradeEntry.getValue().get(0).getId());
                select.setChildren(null);
                yearList.add(select);
            }
            year.setChildren(yearList);
            resList.add(year);
        }
        return resList;
    }


    @Override
    public SchoolGrade selectGradeByName(String gradName) {
        return schoolGradeMapper.selectGradeByName(gradName);
    }

    /**
     * 升级
     * （初始化三条数据后，可进行升级操作，新插入一条级部信息，上两个级部的学年和年级自动+1）
     * 级部信息发生变化，对应所在本级部的班级的有关级部的信息也要发生改变
     */
    @Override
    @Transactional
    public int upgrade() {
        //例如当前学年是2022学年，那么在2023年7月前点升级给提示：不允许升级。
        //获取当前最新学年
        int newSchoolYear = schoolGradeMapper.isNewSchoolYear();
        //获取当前年月
        Calendar cal = Calendar.getInstance();
        int nowYear = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        if (nowYear - newSchoolYear < 1 || (nowYear - newSchoolYear == 1 && month < 7)){
            throw new ServiceException("不允许升级");
        }
        //获取高一级部
        List<SchoolGrade> grade1List = schoolGradeMapper.selectGrades(GRADEVALUE1);
        //获取高二级部
        List<SchoolGrade> grade2List = schoolGradeMapper.selectGrades(GRADEVALUE2);



        if (StringUtils.isNull(grade1List) || grade1List.size() == 0) {
            throw new ServiceException("高一级部不存在，无法升级,请检查");
        }
        if (StringUtils.isNull(grade2List) || grade2List.size() == 0) {
            throw new ServiceException("高二级部不存在，无法升级,请检查");
        }

        int num = 0;
        //新增高一，万一库里存在2022学年高一，和2026学年高一呢，那就循环把，，，，
        //处理高一升高二
        for (SchoolGrade grade : grade1List) {
            //学年加1 年级数值+1

            int schoolYear = Integer.parseInt(grade.getSchoolYear()) + 1;
            grade.setSchoolYear(Integer.toString(schoolYear));
            grade.setGradeValue(grade.getGradeValue() + 1);
            grade.setRemark(G2);
            judge(grade);
            num += schoolGradeMapper.updateById(grade);
            //更新其对应的班级
            LambdaQueryWrapper<SchoolClass> lqw = new LambdaQueryWrapper<>();
            lqw.eq(SchoolClass::getGradeId, grade.getId());
            List<SchoolClass> list = classMapper.selectList(lqw);
            for (SchoolClass sc : list) {
                sc.setGradeValue(grade.getGradeValue());
                sc.setGradeName(GRADE2);
                sc.setClassAlias(G2 + sc.getClassName());
                classMapper.updateById(sc);
            }
            //新增高一
            SchoolGrade g = new SchoolGrade();
            g.setGradeValue(GRADEVALUE1);//一年级
            g.setSchoolYear(grade.getSchoolYear());
            g.setGradeYear(grade.getSchoolYear());
            g.setGradeName(grade.getSchoolYear() + "级部");
            g.setSfzxxn(NEWTERM);
            g.setRemark(G1);
            judge(g);
            schoolGradeMapper.insert(g);
        }
        //处理高二升高三
        for (SchoolGrade grade : grade2List) {
            //学年加1 年级数值+1
            int schoolYear = Integer.parseInt(grade.getSchoolYear()) + 1;
            grade.setSchoolYear(Integer.toString(schoolYear));
            grade.setGradeValue(grade.getGradeValue() + 1);
            grade.setRemark(G3);
            judge(grade);
            num += schoolGradeMapper.updateById(grade);
            //更新其对应的班级
            LambdaQueryWrapper<SchoolClass> lqw = new LambdaQueryWrapper<>();
            lqw.eq(SchoolClass::getGradeId, grade.getId());
            List<SchoolClass> list = classMapper.selectList(lqw);
            for (SchoolClass sc : list) {
                sc.setGradeValue(grade.getGradeValue());
                sc.setGradeName(GRADE3);
                sc.setClassAlias(G3 + sc.getClassName());
                classMapper.updateById(sc);
            }
        }

        return num == (grade1List.size() + grade2List.size()) ? 1 : 0;
    }

    /**
     * 判断要升级的级部，是否存在升级后的级部
     * * 譬如当前级部为 2022学年 高一，，，升级后变为2023学年高二，，，如果此时库里存在2023学年高二，则要进行抛异常
     * grade里的值已进行+1,还未进库
     **/
    public void judge(SchoolGrade grade) {
        LambdaQueryWrapper<SchoolGrade> lqw = new LambdaQueryWrapper<>();
        lqw
                .eq(SchoolGrade::getSchoolYear, grade.getSchoolYear())
                .eq(SchoolGrade::getGradeValue, grade.getGradeValue());
        List<SchoolGrade> list = schoolGradeMapper.selectList(lqw);
        if (StringUtils.isNotNull(list) && list.size() > 0) {
            if (StringUtils.isNotNull(grade.getId())) {
                throw new ServiceException("系统内存在" + grade.getGradeName() + "升级后的级部，无法升级,请检查");
            } else {
                throw new ServiceException("新增" + grade.getSchoolYear() + "学年的高一级部失败，失败原因是" + grade.getSchoolYear() + "学年的高一级部已存在");
            }
        }
    }

    /**
     * TODO 修改最新学年
     * 获取最新学年
     * @return
     */
    @Override
    public int isNewSchoolYear() {
        return schoolGradeMapper.isNewSchoolYear();
    }

    @Override
    public Long selectDdClassId(String ddId) {
        return schoolGradeMapper.selectDdClassId(ddId);
    }

    @Override
    public String selectUpToYear() {
        return schoolGradeMapper.selectUpToYear();
    }
}
