package com.xinelu.manage.service.nursestationconsumable.impl;

import com.xinelu.manage.domain.nursestation.NurseStation;
import com.xinelu.manage.domain.nursestationconsumable.NurseStationConsumable;
import com.xinelu.manage.dto.nursestationconsumable.NurseStationConsumableImportlDTO;
import com.xinelu.manage.mapper.nursestation.NurseStationMapper;
import com.xinelu.manage.mapper.nursestationconsumable.NurseStationConsumableMapper;
import com.xinelu.manage.service.nursestationconsumable.INurseStationConsumableService;
import com.xinelu.manage.vo.nursestationconsumable.NurseStationConsumableVO;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.core.domain.model.LoginUser;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 护理站耗材信息Service业务层处理
 *
 * @author 纪寒
 * @date 2022-09-05
 */
@Service
public class NurseStationConsumableServiceImpl implements INurseStationConsumableService {
    @Resource
    private NurseStationConsumableMapper nurseStationConsumableMapper;
    @Resource
    private GenerateSystemCodeUtil generateSystemCodeUtil;
    @Resource
    private NurseStationMapper nurseStationMapper;

    /**
     * 查询护理站耗材信息
     *
     * @param id 护理站耗材信息主键
     * @return 护理站耗材信息
     */
    @Override
    public NurseStationConsumableVO selectNurseStationConsumableById(Long id) {
        return nurseStationConsumableMapper.selectNurseStationConsumableById(id);
    }

    /**
     * 查询护理站耗材信息列表
     *
     * @param nurseStationConsumable 护理站耗材信息
     * @return 护理站耗材信息
     */
    @Override
    public List<NurseStationConsumableVO> selectNurseStationConsumableList(NurseStationConsumable nurseStationConsumable) {
        return nurseStationConsumableMapper.selectNurseStationConsumableList(nurseStationConsumable);
    }

    /**
     * 新增护理站耗材信息
     *
     * @param nurseStationConsumable 护理站耗材信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertNurseStationConsumable(List<NurseStationConsumable> nurseStationConsumable) throws Exception {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        for (NurseStationConsumable stationConsumable : nurseStationConsumable) {
            stationConsumable.setCreateBy(SecurityUtils.getUsername());
            stationConsumable.setCreateTime(LocalDateTime.now());
            stationConsumable.setUserId(loginUser.getUserId());
            stationConsumable.setConsumableCode(Constants.STATION_CONSUMABLE + generateSystemCodeUtil.generateSystemCode(Constants.STATION_CONSUMABLE));
        }
        int i = nurseStationConsumableMapper.insertNurseStationConsumable(nurseStationConsumable);
        if (i <= 0) {
            throw new Exception("新增护理站耗材信息失败, 请联系管理员！");
        }
        return AjaxResult.success();
    }

    /**
     * 导入护理站耗材信息列表
     *
     * @param list 输入参数
     * @return 导入数据
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult importData(List<NurseStationConsumableImportlDTO> list) throws Exception {
        //获取当前用户
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (CollectionUtils.isEmpty(list)) {
            AjaxResult.error("请添加护理站耗材导入数据！");
        }
        //获取护理站的名称
        List<String> stationNameList = list.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getNurseStationName())).map(NurseStationConsumableImportlDTO::getNurseStationName).distinct().collect(Collectors.toList());
        //获取所有的耗材信息
        List<NurseStationConsumableImportlDTO> nurseStationItemVo = nurseStationConsumableMapper.selectConsumableInfoList(stationNameList);
        //求出差集,进行新增
        Collection<NurseStationConsumableImportlDTO> subtractList = CollectionUtils.subtract(list, nurseStationItemVo);
        //求出并集,重复数据
        Collection<NurseStationConsumableImportlDTO> intersectionList = CollectionUtils.intersection(list, nurseStationItemVo);
        //如果差集为null直接返回
        if (CollectionUtils.isEmpty(subtractList)) {
            Map<String, Collection<NurseStationConsumableImportlDTO>> map = new HashMap<>();
            map.put("successList", subtractList);
            map.put("failList", intersectionList);
            return AjaxResult.success(map);
        }
        //获取到所有的护理站信息
        List<NurseStation> nurseStations = nurseStationMapper.selectNurseStationListByNames(stationNameList);
        Map<String, Long> nurseStationLabelMap = nurseStations.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getNurseStationName())).collect(Collectors.toMap(NurseStation::getNurseStationName, NurseStation::getId));
        //设置护理站id
        list.forEach(item -> item.setNurseStationId(nurseStationLabelMap.getOrDefault(item.getNurseStationName(), 0L)));
        //集合
        List<NurseStationConsumable> nurseStationConsumables = new ArrayList<>();
        //添加创建时间/护理站编号/判断如果没有护理站信息,添加0L
        subtractList.forEach(item -> {
            //设置编号
            item.setConsumableCode(Constants.STATION_CONSUMABLE + generateSystemCodeUtil.generateSystemCode(Constants.STATION_CONSUMABLE));
            item.setCreateTime(LocalDateTime.now());
            item.setUserId(loginUser.getUserId());
            //如果查找不到护理站id 就存0L
            if (item.getNurseStationId() == null) {
                item.setNurseStationId(0L);
            }
            NurseStationConsumable nurseStationConsumable = new NurseStationConsumable();
            BeanUtils.copyProperties(item, nurseStationConsumable);
            nurseStationConsumables.add(nurseStationConsumable);
        });
        int i = nurseStationConsumableMapper.insertNurseStationConsumable(nurseStationConsumables);
        if (i <= 0) {
            throw new Exception("护理站耗材信息导入失败，请联系管理员！");
        }
        Map<String, Collection<NurseStationConsumableImportlDTO>> map = new HashMap<>();
        map.put("successList", subtractList);
        map.put("failList", intersectionList);
        return AjaxResult.success(map);
    }

    /**
     * 修改护理站耗材信息
     *
     * @param nurseStationConsumable 护理站耗材信息
     * @return 结果
     */
    @Override
    public int updateNurseStationConsumable(NurseStationConsumable nurseStationConsumable) {
        nurseStationConsumable.setUpdateBy(SecurityUtils.getUsername());
        nurseStationConsumable.setUpdateTime(LocalDateTime.now());
        return nurseStationConsumableMapper.updateNurseStationConsumable(nurseStationConsumable);
    }

    /**
     * 批量删除护理站耗材信息
     *
     * @param ids 需要删除的护理站耗材信息主键
     * @return 结果
     */
    @Override
    public int deleteNurseStationConsumableByIds(Long[] ids) {
        return nurseStationConsumableMapper.deleteNurseStationConsumableByIds(ids);
    }

    /**
     * 删除护理站耗材信息信息
     *
     * @param id 护理站耗材信息主键
     * @return 结果
     */
    @Override
    public int deleteNurseStationConsumableById(Long id) {
        return nurseStationConsumableMapper.deleteNurseStationConsumableById(id);
    }
}
