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

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.CurrentUser;
import com.yida.data.common.core.entity.constant.CachePrefixConstant;
import com.yida.data.common.core.entity.school.EduDormitoryRoom;
import com.yida.data.common.core.exception.FebsException;
import com.yida.data.common.core.utils.Asserts;
import com.yida.data.common.core.utils.ExcelUtil;
import com.yida.data.common.core.vo.ImportPercentVO;
import com.yida.data.school.dto.facility.BatchGenerateDormRoomDTO;
import com.yida.data.school.dto.index.EditPersonNumDTO;
import com.yida.data.school.dto.index.ImportDormRoomDTO;
import com.yida.data.school.dto.index.ListDormRoomDTO;
import com.yida.data.school.dto.index.PageDormRoomDTO;
import com.yida.data.school.facility.listener.ImportDormRoomListener;
import com.yida.data.school.facility.mapper.EduDormitoryMapper;
import com.yida.data.school.facility.mapper.EduDormitoryRoomMapper;
import com.yida.data.school.facility.service.EduDormitoryRoomService;
import com.yida.data.school.vo.index.DormRoomInfoVO;
import com.yida.data.user.feign.RemoteStudentService;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 宿舍楼-寝室房间 Service实现
 *
 * @author wjm
 * @date 2021-09-14 17:42:13
 */
@Service
@RequiredArgsConstructor
@Transactional
public class EduDormitoryRoomServiceImpl extends ServiceImpl
    <EduDormitoryRoomMapper, EduDormitoryRoom> implements EduDormitoryRoomService {

    private final EduDormitoryMapper eduDormitoryMapper;

    private final RemoteStudentService remoteStudentService;

    private final RedisService redisService;

    @Override
    public IPage<DormRoomInfoVO> listDormRoomPage(PageDormRoomDTO dto) {
        return baseMapper.listDormRoomPage(dto.toPage(), dto);
    }

    @Override
    public void batchGenerateRoom(List<BatchGenerateDormRoomDTO> dto) {
        Long dormId = dto.get(0).getDormId();
        List<EduDormitoryRoom> saveList = new ArrayList<>();
        for (BatchGenerateDormRoomDTO roomDTO : dto) {
            // 门牌最大位数
            int maxLen = Math.max(String.valueOf(roomDTO.getEndNum()).length(), 2);
            for (int i = roomDTO.getStartNum(); i <= roomDTO.getEndNum(); i++) {
                EduDormitoryRoom room = new EduDormitoryRoom();
                room.setName(roomDTO.getFloor().toString() + StrUtil.fillBefore(String.valueOf(i), '0', maxLen));
                room.setDormId(dormId);
                room.setFloor(roomDTO.getFloor());
                room.setBedNum(roomDTO.getBedNum());
                saveList.add(room);
            }
        }
        // 查询已经保存的寝室
        List<EduDormitoryRoom> existRoom = baseMapper.listExistRoom(
            saveList.stream().map(EduDormitoryRoom::getName).collect(Collectors.toList()), dormId);
        if (CollUtil.isNotEmpty(existRoom)) {
            List<String> existNames = existRoom.stream().map(EduDormitoryRoom::getName).collect(Collectors.toList());
            saveList = saveList.stream().filter(x -> !existNames.contains(x.getName())).collect(Collectors.toList());
        }
        if (CollUtil.isNotEmpty(saveList)) {
            saveBatch(saveList);
        }
    }

    @Override
    public void delDormRoomBatch(List<Long> ids) {
        remoteStudentService.unbindDormRoom(ids);
        removeByIds(ids);
    }

    @Override
    public List<EduDormitoryRoom> listDormRoom(ListDormRoomDTO dto) {
        return baseMapper.listDormRoom(dto);
    }

    @Override
    public EduDormitoryRoom getDormRoom(Long id) {
        return baseMapper.getDormRoom(id);
    }

    @Override
    public void editPersonNum(List<EditPersonNumDTO> dtos) {
        for (EditPersonNumDTO dto : dtos) {
            EduDormitoryRoom room = getById(dto.getDormRoomId());
            Asserts.isTrue(room.getCheckInNum() + dto.getNum() <= room.getBedNum(), "超过宿舍最大床位");
            room.setCheckInNum(room.getCheckInNum() + dto.getNum());
            updateById(room);
        }
    }

    @Override
    public void importDormRoom(MultipartFile file, Long dormId, CurrentUser currentUser) {
        ImportPercentVO percent =
            (ImportPercentVO) redisService.hget(CachePrefixConstant.IMPORT_DORM_ROOM,
                dormId.toString());
        Asserts.isTrue(percent == null || percent.getFinish() == 1, "有文件正在导入，请稍后重试");
        try {
            int rowNum = ExcelUtil.readExcel(file.getInputStream(), "xlsx").getSheetAt(0).getLastRowNum();
            ImportPercentVO percentVO = new ImportPercentVO();
            percentVO.setTotal(Long.valueOf(rowNum));
            EasyExcel.read(file.getInputStream(), ImportDormRoomDTO.class,
                new ImportDormRoomListener(redisService, eduDormitoryMapper, this, percentVO, dormId,
                    currentUser.getDeptId(), dormId.toString())).sheet().doRead();
        } catch (IOException e) {
            log.error("导入失败", e);
            throw new FebsException("导入失败");
        }
    }
}
