package com.yida.data.school.facility.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.CurrentUser;
import com.yida.data.common.core.entity.constant.StringConstant;
import com.yida.data.common.core.entity.school.EduDormitory;
import com.yida.data.common.core.entity.school.EduDormitoryMaster;
import com.yida.data.common.core.entity.school.EduDormitoryRoom;
import com.yida.data.common.core.entity.system.enums.DeptTypeEnum;
import com.yida.data.common.core.entity.system.enums.RoleEnum;
import com.yida.data.common.core.entity.user.EduStaff;
import com.yida.data.common.core.exception.FebsException;
import com.yida.data.common.core.utils.Asserts;
import com.yida.data.common.core.utils.FebsUtil;
import com.yida.data.school.dto.index.PageDormDTO;
import com.yida.data.school.facility.mapper.EduDormitoryMapper;
import com.yida.data.school.facility.mapper.EduDormitoryMasterMapper;
import com.yida.data.school.facility.mapper.EduDormitoryRoomMapper;
import com.yida.data.school.facility.service.EduDormitoryService;
import com.yida.data.school.vo.index.DormInfoVO;
import com.yida.data.user.dto.ListStaffDTO;
import com.yida.data.user.feign.RemoteStaffService;
import com.yida.data.user.feign.RemoteStudentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 宿舍楼 Service实现
 *
 * @author wjm
 * @date 2021-09-14 17:42:11
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class EduDormitoryServiceImpl extends ServiceImpl
    <EduDormitoryMapper, EduDormitory> implements EduDormitoryService {

    private final EduDormitoryRoomMapper eduDormitoryRoomMapper;
    private final EduDormitoryMasterMapper eduDormitoryMasterMapper;

    private final RemoteStudentService remoteStudentService;
    private final RemoteStaffService remoteStaffService;

    @Override
    public List<EduDormitory> listDormByMaster(Long masterId) {
        return baseMapper.listDormByMaster(masterId);
    }

    @Override
    public IPage<DormInfoVO> listDormPage(PageDormDTO dto) {

        if (Objects.nonNull(dto.getMasterId())) {
            List<EduDormitoryMaster> masterList = eduDormitoryMasterMapper
                .selectList(Wrappers.lambdaQuery(new EduDormitoryMaster())
                    .eq(EduDormitoryMaster::getMasterId, dto.getMasterId()).select(EduDormitoryMaster::getDormitoryId));
            if (CollUtil.isEmpty(masterList)) {
                return new Page<>();
            }
            dto.setDormIds(masterList.stream().map(EduDormitoryMaster::getDormitoryId)
                .distinct()
                .collect(Collectors.toList()));
        }
        IPage<DormInfoVO> dormPage = baseMapper.listDormPage(dto.toPage(), dto);
        // 查询宿管名称
        if (CollUtil.isNotEmpty(dormPage.getRecords())) {
            // 查询宿管id集合
            for (DormInfoVO dormInfoVO : dormPage.getRecords()) {
                List<Long> masterIds = eduDormitoryMasterMapper.selectList(Wrappers.lambdaQuery(new EduDormitoryMaster())
                    .eq(EduDormitoryMaster::getDormitoryId, dormInfoVO.getDormId())
                    .select(EduDormitoryMaster::getMasterId)
                ).stream().map(EduDormitoryMaster::getMasterId).collect(Collectors.toList());
                dormInfoVO.setMasterIds(masterIds);

                List<EduStaff> staffList = CollUtil.isNotEmpty(masterIds)
                    ? remoteStaffService.listStaff(ListStaffDTO.builder().ids(masterIds).build()).getData()
                    : Collections.emptyList();
                // 匹配宿管
                if (CollUtil.isNotEmpty(staffList)) {
                    dormInfoVO.setMasterName(staffList.stream().map(EduStaff::getName)
                        .collect(Collectors.joining(StringConstant.COMMA)));
                }
            }
        }
        return dormPage;
    }

    @Override
    public void saveDorm(EduDormitory dorm) {
        if (dorm.getSchoolId() == null) {
            CurrentUser currentUser = FebsUtil.getCurrentUser();
            if (DeptTypeEnum.SCHOOL_TYPE.getValue().equals(currentUser.getDeptType())) {
                dorm.setSchoolId(currentUser.getDeptId());
            } else {
                throw new FebsException("请选择学校");
            }
        }
        LambdaQueryWrapper<EduDormitory> condition = Wrappers.<EduDormitory>lambdaQuery()
            .eq(EduDormitory::getSchoolId, dorm.getSchoolId())
            .eq(EduDormitory::getName, dorm.getName());
        if (dorm.getId() != null) {
            condition.ne(EduDormitory::getId, dorm.getId());
        }
        Asserts.isTrue(count(condition) == 0, "该宿舍楼已存在");
        saveOrUpdate(dorm);

        // 删除旧宿管数据
        eduDormitoryMasterMapper
            .delete(Wrappers.<EduDormitoryMaster>lambdaQuery().in(EduDormitoryMaster::getDormitoryId, dorm.getId()));
        dorm.getMasterIds().forEach(masterId -> {
            EduDormitoryMaster master = EduDormitoryMaster.builder()
                .dormitoryId(dorm.getId())
                .masterId(masterId)
                .schoolId(dorm.getSchoolId())
                .build();
            eduDormitoryMasterMapper.insert(master);
        });
    }

    @Override
    public void delDormBatch(List<Long> ids) {
        List<EduDormitoryRoom> rooms = eduDormitoryRoomMapper.selectList(
            Wrappers.<EduDormitoryRoom>lambdaQuery().in(EduDormitoryRoom::getDormId, ids).select(EduDormitoryRoom::getId));
        //删除寝室
        eduDormitoryRoomMapper.delete(Wrappers.<EduDormitoryRoom>lambdaQuery().in(EduDormitoryRoom::getDormId, ids));
        // 删除宿舍楼
        removeByIds(ids);
        // 最后删除学生绑定的寝室  不需要使用全局事务
        if (CollUtil.isNotEmpty(rooms)) {
            remoteStudentService.unbindDormRoom(rooms.stream().map(EduDormitoryRoom::getId).collect(Collectors.toList()));
        }
    }

    @Override
    public EduDormitory getDorm(Long id) {
        EduDormitory eduDormitory = getById(id);
        Optional.ofNullable(eduDormitory).ifPresent(dormitory -> {
            // 查询宿管信息
            List<EduDormitoryMaster> masterList = eduDormitoryMasterMapper
                .selectList(Wrappers.lambdaQuery(new EduDormitoryMaster())
                    .eq(EduDormitoryMaster::getDormitoryId, dormitory.getId()).select(EduDormitoryMaster::getMasterId));
            if (CollUtil.isNotEmpty(masterList)) {
                dormitory.setEduStaffList(
                    remoteStaffService.listStaff(
                        ListStaffDTO.builder().ids(masterList.stream().map(EduDormitoryMaster::getMasterId)
                            .collect(Collectors.toList())).build())
                        .getData());
            }
        });
        return eduDormitory;
    }
}
