package com.xjrsoft.module.room.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.toolkit.MPJWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.xjrsoft.common.enums.DeleteMark;
import com.xjrsoft.common.enums.GenderDictionaryEnum;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.utils.VoToColumnUtil;
import com.xjrsoft.module.base.entity.BaseClass;
import com.xjrsoft.module.base.mapper.BaseClassMapper;
import com.xjrsoft.module.room.dto.AdjustBedPageDto;
import com.xjrsoft.module.room.dto.AdjustClassPageDto;
import com.xjrsoft.module.room.dto.AdjustStudentBedDto;
import com.xjrsoft.module.room.dto.DistributeClassPageDto;
import com.xjrsoft.module.room.dto.DistributeRoomBedDto;
import com.xjrsoft.module.room.dto.DistributeRoomBedPageDto;
import com.xjrsoft.module.room.dto.RoomBedPageDto;
import com.xjrsoft.module.room.entity.Room;
import com.xjrsoft.module.room.entity.RoomBed;
import com.xjrsoft.module.room.entity.RoomBedRecord;
import com.xjrsoft.module.room.mapper.RoomBedMapper;
import com.xjrsoft.module.room.mapper.RoomBedRecordMapper;
import com.xjrsoft.module.room.mapper.RoomMapper;
import com.xjrsoft.module.room.service.IRoomBedService;
import com.xjrsoft.module.room.vo.AdjustBedClassPageVo;
import com.xjrsoft.module.room.vo.AdjustBedClassStudentPageVo;
import com.xjrsoft.module.room.vo.AdjustBedStudentPageVo;
import com.xjrsoft.module.room.vo.ClassStudentCountVo;
import com.xjrsoft.module.room.vo.DistributeClassPageVo;
import com.xjrsoft.module.room.vo.DistributeResultClassVo;
import com.xjrsoft.module.room.vo.DistributeResultListVo;
import com.xjrsoft.module.room.vo.DistributeRoomBedPageVo;
import com.xjrsoft.module.room.vo.NoBedStudentPageVo;
import com.xjrsoft.module.room.vo.RoomBedExcelVo;
import com.xjrsoft.module.room.vo.RoomBedPageVo;
import com.xjrsoft.module.room.vo.RoomClassCountVo;
import com.xjrsoft.module.room.vo.RoomClassExistentVo;
import com.xjrsoft.module.room.vo.StudentPayStatusVo;
import com.xjrsoft.module.student.entity.BaseStudent;
import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
import com.xjrsoft.module.student.mapper.BaseStudentMapper;
import com.xjrsoft.module.teacher.entity.XjrUser;
import com.xjrsoft.module.teacher.mapper.XjrUserMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @title: 寝室床位
* @Author dzx
* @Date: 2023-12-27
* @Version 1.0
*/
@Service
@AllArgsConstructor
public class RoomBedServiceImpl extends MPJBaseServiceImpl<RoomBedMapper, RoomBed> implements IRoomBedService {
    private final RoomMapper roomMapper;
    private final RoomBedMapper roomBedMapper;
    private final BaseStudentMapper baseStudentMapper;
    private final BaseClassMapper baseClassMapper;
    private final XjrUserMapper xjrUserMapper;
    private final RoomBedRecordMapper roomBedRecordMapper;
    @Override
    public Page<RoomBedPageVo> getPage(Page<RoomBedPageVo> page, RoomBedPageDto dto) {
        Page<RoomBedPageVo> result = roomBedMapper.getPage(page, dto);
        return result;
    }

    @Override
    public List<RoomBedExcelVo> getList(RoomBedPageDto dto) {
        return roomBedMapper.getList(dto);
    }

    @Override
    public Boolean clearStudentInfo(List<Long> ids) {
        for (Long id : ids) {
            RoomBed roomBed = roomBedMapper.selectById(id);
            roomBed.setStudentUserId(null);
//            RoomBed roomBedData = BeanUtil.toBean(roomBed, RoomBed.class);
//            roomBedMapper.updateById(new RoomBed(){{
//                setId(id);
//                setStudentUserId(null);
//            }});
            UpdateWrapper<RoomBed> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", id);
            updateWrapper.setSql("student_user_id = null");
            updateWrapper.setSql("is_check_in = 0");
            roomBedMapper.update(roomBed, updateWrapper);
        }
        return true;
    }

    @Override
    public Boolean clearStudentInfoByRoomId(Long id) {
        List<RoomBed> bedList = roomBedMapper.selectList(
            MPJWrappers.<RoomBed>lambdaJoin().eq(RoomBed::getRoomId, id)
        );
        for (RoomBed roomBed : bedList) {
            UpdateWrapper<RoomBed> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", roomBed.getId());
            updateWrapper.setSql("student_user_id = null");
            updateWrapper.setSql("is_check_in = 0");
            roomBedMapper.update(roomBed, updateWrapper);
        }
        Room room = roomMapper.selectById(id);
        room.setIsMax(0);
        roomMapper.updateById(room);
        return true;
    }

    @Override
    public Boolean clearStudentInfoByBedId(Long id) {
        UpdateWrapper<RoomBed> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id);
        updateWrapper.setSql("student_user_id = null");
        updateWrapper.setSql("is_check_in = 0");

        RoomBed roomBed = roomBedMapper.selectById(id);
        roomBedMapper.update(roomBed, updateWrapper);
        //如果寝室的人只剩下一个班级，将混合寝室改为否
        List<Long> roomIds = new ArrayList<>();
        roomIds.add(roomBed.getRoomId());
        List<RoomClassCountVo> classCountVoList = roomMapper.getRoomClassCount(roomIds);
        for (RoomClassCountVo roomClassCountVo : classCountVoList) {
            if(roomClassCountVo.getClassCount() == 1){
                Room updRoom = roomMapper.selectById(roomClassCountVo.getId());
                updRoom.setIsMax(0);
                roomMapper.updateById(updRoom);
            }
        }
        return true;
    }

    @Override
    public Page<DistributeClassPageVo> getDistributeClassInfo(Page<DistributeClassPageDto> page, DistributeClassPageDto dto) {
        Page<DistributeClassPageVo> classInfo = roomBedMapper.getDistributeClassInfo(page, dto);
        List<DistributeClassPageVo> records = classInfo.getRecords();
        //查询所有班级需要安排住宿的人数，并组装成map备用
        List<ClassStudentCountVo> allStayCount = roomBedMapper.getAllStayCount();
        Map<String, Integer> allStayCountMap = new HashMap<>();
        for (ClassStudentCountVo classStudentCountVo : allStayCount) {
            allStayCountMap.put(classStudentCountVo.getClassId(), classStudentCountVo.getStudentCount());
        }

        //查询所有班级需要安排住宿的男生人数，并组装成map备用
        List<ClassStudentCountVo> allStayMaleCount = roomBedMapper.getAllStayMaleCount();
        Map<String, Integer> allStayMaleCountMap = new HashMap<>();
        for (ClassStudentCountVo classStudentCountVo : allStayMaleCount) {
            allStayMaleCountMap.put(classStudentCountVo.getClassId(), classStudentCountVo.getStudentCount());
        }

        //查询所有班级需要安排住宿的女生人数，并组装成map备用
        List<ClassStudentCountVo> allStayFemaleCount = roomBedMapper.getAllStayFemaleCount();
        Map<String, Integer> allStayFemaleCountMap = new HashMap<>();
        for (ClassStudentCountVo classStudentCountVo : allStayFemaleCount) {
            allStayFemaleCountMap.put(classStudentCountVo.getClassId(), classStudentCountVo.getStudentCount());
        }

        //查询所有班级已经安排住宿的总人数，并组装成map备用
        List<ClassStudentCountVo> allArrangedCount = roomBedMapper.getAllArrangedCount();
        Map<String, Integer> allArrangedCountMap = new HashMap<>();
        for (ClassStudentCountVo classStudentCountVo : allArrangedCount) {
            allArrangedCountMap.put(classStudentCountVo.getClassId(), classStudentCountVo.getStudentCount());
        }

        //查询所有班级已经安排住宿的男生人数，并组装成map备用
        List<ClassStudentCountVo> allArrangedMaleCount = roomBedMapper.getAllArrangedMaleCount();
        Map<String, Integer> allArrangedMaleCountMap = new HashMap<>();
        for (ClassStudentCountVo classStudentCountVo : allArrangedMaleCount) {
            allArrangedMaleCountMap.put(classStudentCountVo.getClassId(), classStudentCountVo.getStudentCount());
        }

        //查询所有班级已经安排住宿的女生人数，并组装成map备用
        List<ClassStudentCountVo> allArrangedFemaleCount = roomBedMapper.getAllArrangedFemaleCount();
        Map<String, Integer> allArrangedFemaleCountMap = new HashMap<>();
        for (ClassStudentCountVo classStudentCountVo : allArrangedFemaleCount) {
            allArrangedFemaleCountMap.put(classStudentCountVo.getClassId(), classStudentCountVo.getStudentCount());
        }

        for (DistributeClassPageVo record : records) {
            Integer needCout = 0;
            Integer distributeCount = 0;
            Integer maleCount = 0, femaleCount = 0;
            record.setMaleCount(maleCount);
            record.setFemaleCount(femaleCount);

            if("SB10001".equals(dto.getGender()) && allStayMaleCountMap.get(record.getId()) != null){
                if(allStayMaleCountMap.get(record.getId()) != null){
                    maleCount = allStayMaleCountMap.get(record.getId()) - (allArrangedMaleCountMap.get(record.getId()) == null ? 0 : allArrangedMaleCountMap.get(record.getId()));
                }
                if(maleCount < 0){
                    maleCount = 0;
                }
                record.setMaleCount(maleCount);
                needCout = allStayMaleCountMap.get(record.getId());
                if(allArrangedMaleCountMap.get(record.getId()) != null){
                    distributeCount = (allArrangedMaleCountMap.get(record.getId()) == null ? 0 : allArrangedMaleCountMap.get(record.getId()));
                }

            }else if("SB10002".equals(dto.getGender())){
                if(allStayFemaleCountMap.get(record.getId()) != null){
                    femaleCount = allStayFemaleCountMap.get(record.getId()) - (allArrangedFemaleCountMap.get(record.getId()) == null ? 0 : allArrangedFemaleCountMap.get(record.getId()));
                }
                if(femaleCount < 0){
                    femaleCount = 0;
                }
                record.setFemaleCount(femaleCount);
                needCout = femaleCount;
                if(allArrangedFemaleCountMap.get(record.getId()) != null){
                    distributeCount = (allArrangedFemaleCountMap.get(record.getId()) == null ? 0 : allArrangedFemaleCountMap.get(record.getId()));
                }
            }else{
                needCout = allStayCountMap.get(record.getId());
                if(allArrangedCountMap.get(record.getId()) != null){
                    distributeCount = (allArrangedCountMap.get(record.getId()) == null ? 0 : allArrangedCountMap.get(record.getId()));
                }
                if(allStayMaleCountMap.get(record.getId()) != null){
                    maleCount = allStayMaleCountMap.get(record.getId()) - (allArrangedMaleCountMap.get(record.getId()) == null ? 0 : allArrangedMaleCountMap.get(record.getId()));
                }
                if(maleCount < 0){
                    maleCount = 0;
                }
                record.setMaleCount(maleCount);
                if(allStayFemaleCountMap.get(record.getId()) != null){
                    femaleCount = allStayFemaleCountMap.get(record.getId()) - (allArrangedFemaleCountMap.get(record.getId()) == null ? 0 : allArrangedFemaleCountMap.get(record.getId()));
                }
                if(femaleCount < 0){
                    femaleCount = 0;
                }
                record.setFemaleCount(femaleCount);
            }
            if(needCout == null){
                needCout = 0;
            }
            if(distributeCount == null){
                distributeCount = 0;
            }

            record.setNeedCount(needCout);
            record.setDistributeCount(distributeCount);
        }

        return classInfo;
    }

    @Override
    public Page<DistributeRoomBedPageVo> getDistributeRoomBedInfo(Page<DistributeRoomBedPageDto> page, DistributeRoomBedPageDto dto) {
        return roomBedMapper.getDistributeRoomBedInfo(page, dto);
    }

    /**
     * 分配床位
     * @param dto
     * @return
     */
    @Override
    public Boolean distributeRoomBed(DistributeRoomBedDto dto) {
        List<Room> roomList = roomMapper.selectList(new QueryWrapper<Room>().lambda().in(Room::getId, dto.getRoomIds()));
        Set<String> genderSet = new HashSet<>();
        //存入每个寝室已经入住的班级id
        Map<Long, Long> roomClassMaps = new HashMap<>();
        for (Room room : roomList) {
            genderSet.add(room.getGender());
            roomClassMaps.put(room.getId(), null);
        }
        //
        List<RoomClassExistentVo> roomClassExistent = roomMapper.getRoomClassExistent(dto.getRoomIds());
        Map<Long, String> roomClassExistentMaps = new HashMap<>();
        for (RoomClassExistentVo roomClassExistentVo : roomClassExistent) {
            roomClassExistentMaps.put(roomClassExistentVo.getId(), roomClassExistentVo.getClassIds());
        }
        Date modifyDate = new Date();
        Long modifyUserId = StpUtil.getLoginIdAsLong();
        //查询每个班的学生，修改床位信息
        Map<Long, Integer> classDistributeBedNumber = new HashMap<>();
        Map<Long, Integer> classStudent = new HashMap<>();
        //查询学生住宿费缴费状态
        List<StudentPayStatusVo> studentPayStatus = roomBedMapper.getStudentPayStatus(dto);
        Map<Long, Integer> payStatusMap = new HashMap<>();
        for (StudentPayStatusVo payStatus : studentPayStatus) {
            payStatusMap.put(payStatus.getId(), (payStatus.getPayStatus() == null?0:payStatus.getPayStatus()));
        }
        //按照性别分组分配
        for (String genderNumber : genderSet) {
            int i = 0;
            //根据性别查询出所有空床位信息
            List<RoomBed> bedInfoList = roomBedMapper.selectList(
                new MPJLambdaWrapper<RoomBed>()
                .select(RoomBed::getId)
                .select(RoomBed.class, x -> VoToColumnUtil.fieldsToColumns(RoomBed.class).contains(x.getProperty()))
                .innerJoin(Room.class, Room::getId, RoomBed::getRoomId)
                .eq(Room::getGender, genderNumber)
                .isNull(RoomBed::getStudentUserId)
                .eq(RoomBed::getIsCheckIn, 0)
                .in(RoomBed::getRoomId, dto.getRoomIds())
            );
            //按照班级分配
            for (Long classId : dto.getClassIds()) {
                //先查询出班上的在读住校生
                List<BaseStudent> studentList = baseStudentMapper.selectList(
                    MPJWrappers.<BaseStudent>lambdaJoin()
                    .select(BaseStudent::getUserId)
                    .eq(BaseClass::getId, classId)
                    .eq(XjrUser::getGender, genderNumber)
                    .eq(BaseStudentSchoolRoll::getStduyStatus, "FB3002")
                    .eq(BaseStudentSchoolRoll::getArchivesStatus, "FB2901")//只查询在读学生
                    .eq(BaseStudent::getDeleteMark, DeleteMark.NODELETE.getCode())
                    .eq(XjrUser::getDeleteMark, DeleteMark.NODELETE.getCode())
                    .innerJoin(XjrUser.class, XjrUser::getId, BaseStudent::getUserId)
                    .leftJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, BaseStudent::getUserId)
                    .leftJoin(BaseClass.class, BaseClass::getId, BaseStudentSchoolRoll::getClassId)
                );
                //已分配床位数
                int distributeBedNumber = 0;
                //先分配已缴费的，再分配未交费的，把已缴费的学生排序到一起
                List<BaseStudent> studentOrderList = new ArrayList<>();
                for (BaseStudent baseStudent : studentList) {
                    if(payStatusMap.get(baseStudent.getUserId()) != null && payStatusMap.get(baseStudent.getUserId()) == 1){
                        studentOrderList.add(baseStudent);
                    }
                }
                for (BaseStudent baseStudent : studentList) {
                    if(payStatusMap.get(baseStudent.getUserId()) == null || payStatusMap.get(baseStudent.getUserId()) == 0){
                        studentOrderList.add(baseStudent);
                    }
                }
                //判断生成策略，是否需要混合寝室
                if(dto.getIsNeedMaxRoom() == 0 && i <= bedInfoList.size()){
                    //预先查看下一个床位所属寝室是否已经有其他班级入住，有就直接跳过
                    for (int j = i; j < bedInfoList.size(); j ++) {
                        Long roomId = bedInfoList.get(j).getRoomId();
                        if((roomClassMaps.get(roomId) != null
                                && !classId.equals(roomClassMaps.get(roomId)))
                                && (roomClassExistentMaps.get(roomId) != null && roomClassExistentMaps.get(roomId).contains(classId.toString()))){
                            i ++;
                        }
                    }
                }
                //执行床位分配
                for (BaseStudent studentInfoVo : studentOrderList) {
                    if(i >= bedInfoList.size()){
                        continue;
                    }
                    RoomBed roomBed = bedInfoList.get(i);
                    roomBed.setStudentUserId(studentInfoVo.getUserId());
                    roomBed.setModifyDate(modifyDate);
                    roomBed.setModifyUserId(modifyUserId);
                    roomBedMapper.updateById(roomBed);
                    i ++;
                    distributeBedNumber ++;
                    //分配好一个学生之后，将这个寝室已入住的班级存入
                    roomClassMaps.putIfAbsent(roomBed.getRoomId(), classId);
                }
                classDistributeBedNumber.put(classId, distributeBedNumber);
                classStudent.put(classId, studentList.size());
            }
        }

        Map<Long, Long> classGradeMap = new HashMap<>();
        baseClassMapper.selectList(
            MPJWrappers.<BaseClass>lambdaJoin().in(BaseClass::getId, dto.getClassIds())
        ).forEach((baseClass)->{
            classGradeMap.put(baseClass.getId(), baseClass.getGradeId());
        });
        //插入记录表 room_bed_record
        Integer maxSortCode = roomBedRecordMapper.getMaxSortCode();
        for (Long classId : classGradeMap.keySet()) {
            maxSortCode ++;
//            Integer studentCount = classStudent.get(classId);
            RoomBedRecord record = new RoomBedRecord();
            record.setClassId(classId);
            record.setGradeId(classGradeMap.get(classId));
            record.setCreateDate(modifyDate);
            record.setSortCode(maxSortCode);
            record.setNeedBedNumber(classStudent.get(classId));
            record.setDistributeBedNumber(classDistributeBedNumber.get(classId));
            record.setDeleteMark(DeleteMark.NODELETE.getCode());
            roomBedRecordMapper.insert(record);
        }
        if(dto.getIsNeedMaxRoom() == 1){
            roomMapper.setIsmaxTrue();
        }
        //查询每个寝室住入的班级数量，大于2的设置为混合寝室
//        List<RoomClassCountVo> classCountVoList = roomMapper.getRoomClassCount(dto.getRoomIds());
//        for (RoomClassCountVo roomClassCountVo : classCountVoList) {
//            if(roomClassCountVo.getClassCount() > 1){
//                Room updRoom = roomMapper.selectById(roomClassCountVo.getId());
//                updRoom.setIsMax(1);
//                roomMapper.updateById(updRoom);
//            }
//        }
        return true;
    }

    @Override
    public List<DistributeResultClassVo> getDistributeResult(DistributeRoomBedDto dto) {
        List<DistributeResultListVo> list = roomBedMapper.getDistributeResult(dto);
        List<BaseClass> classList = baseClassMapper.selectList(
            Wrappers.lambdaQuery(BaseClass.class).in(BaseClass::getId, dto.getClassIds())
            .select(BaseClass.class, x -> VoToColumnUtil.fieldsToColumns(BaseClass.class).contains(x.getProperty()))
        );
        List<DistributeResultClassVo> result =  new ArrayList<>();
        for (BaseClass baseClass : classList) {
            DistributeResultClassVo classVo = new DistributeResultClassVo();
            classVo.setClassName(baseClass.getName());
            List<DistributeResultListVo> studentList = new ArrayList<>();
            for (DistributeResultListVo listVo : list) {
                if(listVo.getClassId() == null || !listVo.getClassId().equals(baseClass.getId().toString())){
                    continue;
                }
                studentList.add(listVo);
            }
            classVo.setStudentList(studentList);
            result.add(classVo);
        }
        return result;
    }

    @Override
    public List<AdjustBedClassPageVo> getClassStudetBed(AdjustClassPageDto dto) {
        List<AdjustBedClassPageVo> classList = roomBedMapper.getClassTeacherInfo(dto);
        List<AdjustBedClassPageVo> result = new ArrayList<>();
        List<AdjustBedClassStudentPageVo> allStudent = roomBedMapper.getClassStudetBed(dto);

        //查询缴费状态
        DistributeRoomBedDto distributeRoomBedDto = new DistributeRoomBedDto();
        List<Long> classIds = new ArrayList<>();
        for (AdjustBedClassPageVo baseClass : classList) {
            classIds.add(Long.parseLong(baseClass.getId()));
        }
        if(!classIds.isEmpty()){
            distributeRoomBedDto.setClassIds(classIds);
        }

//        List<StudentPayStatusVo> studentPayStatusVoList = roomBedMapper.getStudentPayStatus(distributeRoomBedDto);
//        Map<Long, Integer> payStatusMap = new HashMap<>();
//        for (StudentPayStatusVo statusVo : studentPayStatusVoList) {
//            Integer payStatus = 0;
//            if(statusVo.getPayStatus() != null){
//                payStatus = statusVo.getPayStatus();
//            }
//            payStatusMap.put(statusVo.getId(), payStatus);
//        }
        for (AdjustBedClassPageVo classOne : classList) {
            List<AdjustBedClassStudentPageVo> studentList = new ArrayList<>();
            for (AdjustBedClassStudentPageVo adjustBedClassStudentPageVo : allStudent) {
                if(!classOne.getId().toString().equals(adjustBedClassStudentPageVo.getClassId())){
                    continue;
                }
//                Integer payStatus = payStatusMap.get(Long.valueOf(adjustBedClassStudentPageVo.getUserId()));
//                if(payStatus == null){
//                    payStatus = 0;
//                }
//                adjustBedClassStudentPageVo.setPayStatus(payStatus);
                studentList.add(adjustBedClassStudentPageVo);
            }
            if(studentList.isEmpty()){
                continue;
            }
            AdjustBedClassPageVo adjustBedClassPageVo = BeanUtil.toBean(classOne, AdjustBedClassPageVo.class);
            adjustBedClassPageVo.setStudentList(studentList);
            result.add(adjustBedClassPageVo);
        }
        
        return result;
    }

    @Override
    public List<AdjustBedStudentPageVo> getBedStudetInfo(AdjustBedPageDto dto) {
        return roomBedMapper.getBedStudentInfo(dto);
    }

    @Override
    public Page<NoBedStudentPageVo> getNoBedStudent(Page<AdjustBedPageDto> page, AdjustBedPageDto dto) {
        return roomBedMapper.getNoBedStudent(page, dto);
    }

    @Override
    public Boolean adjustBed(AdjustStudentBedDto dto) {
        //查询学生的性别
        XjrUser xjrUser = xjrUserMapper.selectById(dto.getStudentUserId());
        String studentGender = xjrUser.getGender();
//        if(1 == xjrUser.getGender()){
//            studentGender = "SB10001";
//        }else if(2 == xjrUser.getGender()){
//            studentGender = "SB10002";
//        }
        RoomBed roomBedInfo = roomBedMapper.selectById(dto.getBedId());
        Room room = roomMapper.selectById(roomBedInfo.getRoomId());
        if(room == null){
            throw new MyException("为查询到该床位");
        }
        if(!room.getGender().equals(studentGender)){
            String genderStr = "";
            if("SB10001".equals(room.getGender())){
                genderStr = "男";
            }else if("SB10002".equals(room.getGender())){
                genderStr = "女";
            }
            throw new MyException("该学生无法入住" + genderStr + "寝室");
        }

        //先清空学生原来的床位
        UpdateWrapper<RoomBed> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("student_user_id", dto.getStudentUserId());
        updateWrapper.setSql("student_user_id = null");
        updateWrapper.setSql("is_check_in = 0");

        List<Long> roomIds = new ArrayList<>();

        List<RoomBed> roomBedList = roomBedMapper.selectList(new QueryWrapper<RoomBed>().lambda().eq(RoomBed::getStudentUserId, dto.getStudentUserId()));
        for (RoomBed roomBed : roomBedList) {
            roomBedMapper.update(roomBed, updateWrapper);
            roomIds.add(roomBed.getRoomId());
        }

        //再把学生保存到新的床位
        roomBedMapper.updateById(new RoomBed(){{
            setId(dto.getBedId());
            setStudentUserId(dto.getStudentUserId());
        }});
        if(roomIds.isEmpty()){
            roomIds = null;
        }
        //如果寝室的人是多个班级，将混合寝室改为是
        List<RoomClassCountVo> classCountVoList = roomMapper.getRoomClassCount(roomIds);
        for (RoomClassCountVo roomClassCountVo : classCountVoList) {
            if(roomClassCountVo.getClassCount() > 1){
                Room updRoom = roomMapper.selectById(roomClassCountVo.getId());
                updRoom.setIsMax(1);
                roomMapper.updateById(updRoom);
            }
        }

        return true;
    }

    /**
     * 1、先做性别校验，如果学生性别和入住寝室的性别不一致，不进行数据保存并返回学生的姓名到前端
     * 2、参数中可能存在学生id不为空，床位id为空的，根据学生id清空学生相应的床位信息
     * 3、如果一个学生被安排了多个床位，需要新增提示
     * @param dtoList
     * @return
     */
    @Override
    public Boolean adjustBedBatch(List<AdjustStudentBedDto> dtoList) {
        //存分配到女生寝室的男生名字
        Set<String> boyStudents = new HashSet<>();
        //存分配到男生寝室的女生名字
        Set<String> girlStudents = new HashSet<>();
        //需要清空床位的学生
        List<AdjustStudentBedDto> todoStudents = new ArrayList<>();

        Map<Long, Long> bedStudentMap = new HashMap<>();
        Map<Long, String> studentNameMap = new HashMap<>();
        for (AdjustStudentBedDto dto : dtoList) {
            if(dto.getStudentUserId() != null && dto.getBedId() != null){
                bedStudentMap.put(dto.getBedId(), dto.getStudentUserId());
                //查询学生的性别
                XjrUser xjrUser = xjrUserMapper.selectById(dto.getStudentUserId());
                studentNameMap.put(dto.getStudentUserId(), xjrUser.getName());

                String studentGender = xjrUser.getGender();

                RoomBed roomBedInfo = roomBedMapper.selectById(dto.getBedId());
                Room room = roomMapper.selectById(roomBedInfo.getRoomId());
                if(!room.getGender().equals(studentGender)){
                    if(GenderDictionaryEnum.MALE.getCode().equals(room.getGender())){//男生
                        boyStudents.add(xjrUser.getName());
                    }else if(GenderDictionaryEnum.FEMALE.getCode().equals(room.getGender())){//女生
                        girlStudents.add(xjrUser.getName());
                    }
                    continue;
                }
                //校验通过
                todoStudents.add(dto);
            }
        }
        //存被安排了多个床位的学生
        List<String> moreBedStudents = new ArrayList<>();
        for (Map.Entry<Long, Long> entry : bedStudentMap.entrySet()) {
            Long value = entry.getValue();

            if (bedStudentMap.entrySet().stream().filter(e -> e.getValue().equals(value)).count() > 1) {
                moreBedStudents.add(studentNameMap.get(value));
            }
        }

        //存这次处理过的寝室，查看是否需要设置为混合寝室
        List<Long> roomIds = new ArrayList<>();
        if(boyStudents.isEmpty() && girlStudents.isEmpty() && moreBedStudents.isEmpty()){
            for (AdjustStudentBedDto todoStudent : todoStudents) {
                //先清空原来的床位
                UpdateWrapper<RoomBed> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("student_user_id", todoStudent.getStudentUserId());
                updateWrapper.setSql("student_user_id = null");
                updateWrapper.setSql("is_check_in = 0");
                List<RoomBed> roomBedList = roomBedMapper.selectList(new QueryWrapper<RoomBed>().lambda().eq(RoomBed::getStudentUserId, todoStudent.getStudentUserId()));
                for (RoomBed roomBed : roomBedList) {
                    roomBedMapper.update(roomBed, updateWrapper);
                }
                //再把学生保存到新的床位
                roomBedMapper.updateById(new RoomBed(){{
                    setId(todoStudent.getBedId());
                    setStudentUserId(todoStudent.getStudentUserId());
                }});
            }
            //将有多个班级的寝室设置为混合寝室
            roomMapper.setIsmaxTrue();
            //将没有多个班级的混合寝室清除掉
            roomMapper.setIsmaxFalse();
        }else{
            String boyMsg = "学生";
            int i = 0;
            for (String boyStudent : boyStudents) {
                if(i > 0){
                    boyMsg += "、";
                }
                boyMsg += boyStudent;
                i ++;
            }
            boyMsg += "被分配到女生寝室";

            String girlMsg = "学生";
            i = 0;
            for (String girlStudent : girlStudents) {
                if(i > 0){
                    girlMsg += "、";
                }
                girlMsg += girlStudent;
                i ++;
            }
            girlMsg += "被分配到男生寝室";

            String moreBedMsg = "学生";
            for (int j = 0; j < moreBedStudents.size(); j ++){
                if(j > 0){
                    moreBedMsg += "、";
                }
                moreBedMsg += moreBedStudents.get(j);
            }
            moreBedMsg += "被分配多个床位";
            String msg = "";
            if(!boyStudents.isEmpty()){
                msg += boyMsg + "；";
            }
            if(!girlStudents.isEmpty()){
                msg += girlMsg + "；";
            }
            if(!moreBedStudents.isEmpty()){
                msg += moreBedMsg + "；";
            }
            throw new MyException(msg);
        }
        return true;
    }

    @Override
    public String getRoomNameByStudentUserId(Long id) {
        return roomBedMapper.getRoomNameByStudentUserId(id);
    }

}
