package com.srs.dormitory.service.impl;

import com.srs.common.core.domain.AjaxResult;
import com.srs.dormitory.domain.DmsDormitory;
import com.srs.dormitory.domain.DmsForeignApplication;
import com.srs.dormitory.domain.DmsForeignDormitory;
import com.srs.dormitory.domain.SrsDormitoryStudent;
import com.srs.dormitory.mapper.DmsForeignDormitoryMapper;
import com.srs.dormitory.service.IDmsDormitoryService;
import com.srs.dormitory.service.IDmsForeignApplicationService;
import com.srs.dormitory.service.IDmsForeignDormitoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.srs.dormitory.service.ISrsDormitoryStudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 外来人员宿舍关联表 服务实现类
 * </p>
 *
 * @author szz
 * @since 2023年08月04日
 */
@Service
public class IDmsForeignDormitoryServiceImpl extends ServiceImpl<DmsForeignDormitoryMapper, DmsForeignDormitory> implements IDmsForeignDormitoryService {
    @Autowired
    private IDmsForeignApplicationService dmsForeignApplicationService;
    @Autowired
    private ISrsDormitoryStudentService srsDormitoryStudentService;
    @Autowired
    private IDmsDormitoryService dmsDormitoryService;

    /**
     * 添加外来人员宿舍关联
     * @param dormitoryId 宿舍id
     * @param bedId 床位id
     * @param applicationId 申请表id
     * @return
     */
    @Transactional
    @Override
    public AjaxResult addForeignDormitory(Long dormitoryId, Long bedId, Long applicationId) {
        DmsForeignApplication application = dmsForeignApplicationService.lambdaQuery()
                .eq(DmsForeignApplication::getId, applicationId)
                .one();
        if (application==null||application.getStatus()!=2) return AjaxResult.error("该申请表当前无法分配床位");
        SrsDormitoryStudent dormitoryStudent = srsDormitoryStudentService.lambdaQuery()
                .eq(SrsDormitoryStudent::getDormitoryId, dormitoryId)
                .eq(SrsDormitoryStudent::getBedId, bedId)
                .one();
        DmsForeignDormitory foreignDormitory = lambdaQuery().eq(DmsForeignDormitory::getDormitoryId, dormitoryId)
                .eq(DmsForeignDormitory::getBedId, bedId)
                .one();
        if (dormitoryStudent!=null||foreignDormitory!=null) return AjaxResult.error("该床位当前已经有人");
        boolean updateDormitory = dmsDormitoryService.lambdaUpdate()
                .eq(DmsDormitory::getId, dormitoryId)
                .setSql("occupancy = occupancy + 1")
                .update();
        if (!updateDormitory) throw new RuntimeException("修改宿舍人数失败");
        boolean update = dmsForeignApplicationService.lambdaUpdate()
                .eq(DmsForeignApplication::getId, applicationId)
                .set(DmsForeignApplication::getStatus, 3)
                .update();
        if (!update) throw new RuntimeException("修改申请表状态失败");
        DmsForeignDormitory dmsForeignDormitory = new DmsForeignDormitory(null,dormitoryId,bedId,applicationId);
        boolean success = save(dmsForeignDormitory);
        if (!success) throw new RuntimeException("添加关联失败");
        return AjaxResult.success();
    }

    /**
     * 查看外来人员宿舍楼关联列表
     * @param buildingName 宿舍楼名字
     * @param applicationName 申请人姓名
     * @param contactName 校内联系人姓名
     * @return
     */
    @Override
    public List<Map<String, Object>> getForeignDormitoryList(String buildingName, String applicationName, String contactName) {
        return baseMapper.getForeignDormitoryList(buildingName,applicationName,contactName);
    }

    /**
     * 删除外来人员宿舍关联
     * @param id 外来人员宿舍关联id
     * @return
     */
    @Transactional
    @Override
    public AjaxResult deleteForeignDormitory(Long id) {
        DmsForeignDormitory foreignDormitory = getById(id);
        boolean updateDormitory = dmsDormitoryService.lambdaUpdate()
                .eq(DmsDormitory::getId, foreignDormitory.getDormitoryId())
                .setSql("occupancy = occupancy + 1")
                .update();
        if (!updateDormitory) throw new RuntimeException("修改宿舍人数失败");
        boolean remove = removeById(id);
        if (!remove) throw new RuntimeException("删除关联失败");
        return AjaxResult.success();
    }

    /**
     * 修改外来人员宿舍关联
     * @param id 关联id
     * @param dormitoryId 宿舍id
     * @param bedId 床位id
     * @return
     */
    @Override
    public AjaxResult updateForeignDormitory(Long id, Long dormitoryId, Long bedId) {
        DmsForeignDormitory foreignDormitory = getById(id);
        boolean isUpdateBed = false;
        if (foreignDormitory==null) return AjaxResult.error("关联id错误");
        if (dormitoryId!=null) foreignDormitory.setDormitoryId(dormitoryId);
        if (bedId!=null) {
            isUpdateBed = true;
            foreignDormitory.setBedId(bedId);
        }
        if (isUpdateBed){
            SrsDormitoryStudent one = srsDormitoryStudentService.lambdaQuery()
                    .eq(SrsDormitoryStudent::getDormitoryId, foreignDormitory.getDormitoryId())
                    .eq(SrsDormitoryStudent::getBedId, foreignDormitory.getBedId())
                    .one();
            if (one!=null) return AjaxResult.error("该床位已经有人占用");
        }
        boolean success = updateById(foreignDormitory);
        if (success) return AjaxResult.success();
        return AjaxResult.error();
    }

    /**
     * 批量删除外来人员宿舍关联
     * @param ids 关联id列表
     * @return
     */
    @Transactional
    @Override
    public AjaxResult batchDeleteForeignDormitory(List<Long> ids) {
        List<DmsForeignDormitory> foreignDormitoryList = baseMapper.selectBatchIds(ids);
        Map<Long,Integer> map = new HashMap<>();
        for (DmsForeignDormitory dmsForeignDormitory : foreignDormitoryList){
            map.merge(dmsForeignDormitory.getDormitoryId(), 1,Integer::sum);
        }
        for (Long key : map.keySet()){
            boolean updateDormitory = dmsDormitoryService.lambdaUpdate()
                    .eq(DmsDormitory::getId, key)
                    .setSql("occupancy = occupancy -" + map.get(key))
                    .update();
            if (!updateDormitory) throw new RuntimeException("修改宿舍人数失败");
        }
        boolean removeForeign = removeBatchByIds(ids);
        if (!removeForeign) throw new RuntimeException("删除关联失败");
        return AjaxResult.success();
    }
}
