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


import com.xinelu.common.config.XinELuConfig;
import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.enums.NurseClassifyInfoEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import com.xinelu.manage.domain.nurseclassifyinfo.NurseClassifyInfo;
import com.xinelu.manage.mapper.nurseclassifyinfo.NurseClassifyInfoMapper;
import com.xinelu.manage.service.nurseclassifyinfo.INurseClassifyInfoService;
import com.xinelu.manage.service.patientinfo.IPatientInfoService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 护理机构和护理项目分类信息Service业务层处理
 *
 * @author xinelu
 * @date 2023-02-08
 */
@Service
public class NurseClassifyInfoServiceImpl implements INurseClassifyInfoService {
    @Resource
    private NurseClassifyInfoMapper nurseClassifyInfoMapper;
    @Resource
    private GenerateSystemCodeUtil generateSystemCodeUtil;
    @Resource
    private IPatientInfoService patientInfoService;

    /**
     * 查询护理项目分类信息
     *
     * @param id 护理机构和护理项目分类信息主键
     * @return 护理机构和护理项目分类信息
     */
    @Override
    public NurseClassifyInfo selectNurseClassifyInfoById(Long id) {
        return nurseClassifyInfoMapper.selectNurseClassifyInfoById(id);
    }

    /**
     * 查询护理项目分类信息列表
     *
     * @param nurseClassifyInfo 护理机构和护理项目分类信息
     * @return 护理机构和护理项目分类信息
     */
    @Override
    public List<NurseClassifyInfo> selectNurseClassifyInfoList(NurseClassifyInfo nurseClassifyInfo) {
        nurseClassifyInfo.setClassifyType(NurseClassifyInfoEnum.NURSE_ITEM.getInfo());
        return nurseClassifyInfoMapper.selectNurseClassifyInfoList(nurseClassifyInfo);
    }

    /**
     * 新增护理项目分类信息
     *
     * @param nurseClassifyInfo 护理机构和护理项目分类信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertNurseClassifyInfo(List<NurseClassifyInfo> nurseClassifyInfo) {
        if (CollectionUtils.isEmpty(nurseClassifyInfo)) {
            return AjaxResult.error("请添加护理项目分类信息！");
        }
        //筛选护理项目分类名称,去重
        List<String> classifyNameList = nurseClassifyInfo.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getClassifyName())).map(NurseClassifyInfo::getClassifyName).collect(Collectors.toList());
        List<String> distinctClassifyNameList = classifyNameList.stream().distinct().collect(Collectors.toList());
        //集合取差集
        List<String> subtractNameList = new ArrayList<>(CollectionUtils.subtract(classifyNameList, distinctClassifyNameList));
        if (subtractNameList.size() > 0) {
            return AjaxResult.error("'" + subtractNameList.get(0) + "'已存在，请修改后重新录入！");
        }
        //从数据库去项目分类名称
        List<String> existClassNameList = nurseClassifyInfoMapper.selectNurseStationClassNameByList(distinctClassifyNameList, NurseClassifyInfoEnum.NURSE_ITEM.getInfo());
        //传入护理项目分类集合与数据库护理项目分类名称取交集
        List<String> existRetainAllNameList = new ArrayList<>(CollectionUtils.intersection(distinctClassifyNameList, existClassNameList));
        if (existRetainAllNameList.size() > 0) {
            return AjaxResult.error("'" + existRetainAllNameList.get(0) + "'名称重复，请重新输入！");
        }
        for (NurseClassifyInfo nurseClassify : nurseClassifyInfo) {
            // 设置创建人与创建时间 护理项目分类编码 以及护理项目类型
            nurseClassify.setCreateTime(LocalDateTime.now());
            nurseClassify.setCreateBy(SecurityUtils.getUsername());
            nurseClassify.setClassifyType(NurseClassifyInfoEnum.NURSE_ITEM.getInfo());
            nurseClassify.setClassifyCode(Constants.CLASSIFY_ITEM + generateSystemCodeUtil.generateSystemCode(Constants.CLASSIFY_ITEM));
        }
        int insertCount = nurseClassifyInfoMapper.insertNurseClassifyInfoList(nurseClassifyInfo);
        if (insertCount <= 0) {
            throw new ServiceException("新增护理项目分类信息失败，请联系管理员！");
        }
        return AjaxResult.success();
    }

    /**
     * 修改护理项目分类信息
     *
     * @param nurseClassifyInfo 护理机构和护理项目分类信息/classifyItem/info/list
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateNurseClassifyInfo(NurseClassifyInfo nurseClassifyInfo) {
        NurseClassifyInfo nurseClassifyInfoById = nurseClassifyInfoMapper.selectNurseClassifyInfoById(nurseClassifyInfo.getId());
        if (Objects.isNull(nurseClassifyInfoById)) {
            return AjaxResult.error("当前护理项目分类信息不存在，无法修改，请联系管理员！");
        }
        if (StringUtils.isNotBlank(nurseClassifyInfoById.getClassifyName()) && !nurseClassifyInfo.getClassifyName().equals(nurseClassifyInfoById.getClassifyName())) {
            //查询是否有相同名字的护理项目分类
            int classifyInfoByCount = nurseClassifyInfoMapper.selectNurseStationClassNameCount(nurseClassifyInfo.getClassifyName(), NurseClassifyInfoEnum.NURSE_ITEM.getInfo());
            if (classifyInfoByCount > 0) {
                return AjaxResult.error("'" + nurseClassifyInfo.getClassifyName() + "'名称重复，请重新输入！");
            }
        }
        // 设置更新人与更新时间
        nurseClassifyInfo.setUpdateTime(LocalDateTime.now());
        nurseClassifyInfo.setUpdateBy(SecurityUtils.getUsername());
        int updateNurseClassifyInfo = nurseClassifyInfoMapper.updateNurseClassifyInfo(nurseClassifyInfo);
        if (updateNurseClassifyInfo <= 0) {
            throw new ServiceException("修改护理项目分类信息失败，请联系管理员！");
        }
        //删除原有上传的分类图片
        if (StringUtils.isNotBlank(nurseClassifyInfo.getClassifyPictureUrl()) && StringUtils.isNotBlank(nurseClassifyInfoById.getClassifyPictureUrl())
                && !nurseClassifyInfo.getClassifyPictureUrl().equals(nurseClassifyInfoById.getClassifyPictureUrl())) {
            this.deletePictureUrl(nurseClassifyInfoById.getClassifyPictureUrl());
        }
        return AjaxResult.success();
    }

    /**
     * 批量删除护理项目分类信息
     *
     * @param ids 需要删除的护理机构和护理项目分类信息主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult deleteNurseClassifyInfoByIds(Long[] ids) {
        List<NurseClassifyInfo> nurseClassifyList = nurseClassifyInfoMapper.selectNurseStationClassByIds(ids);
        int count = nurseClassifyInfoMapper.deleteNurseClassifyInfoByIds(ids);
        if (count < 0) {
            throw new ServiceException("删除护理分类失败，请联系管理员！");
        }
        List<String> selectPictureUrl = nurseClassifyList.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getClassifyPictureUrl())).map(NurseClassifyInfo::getClassifyPictureUrl).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(selectPictureUrl)) {
            patientInfoService.updatePicture(selectPictureUrl);
        }
        return AjaxResult.success();
    }

    /**
     * 删除护理项目分类信息信息
     *
     * @param id 护理机构和护理项目分类信息主键
     * @return 结果
     */
    @Override
    public int deleteNurseClassifyInfoById(Long id) {
        return nurseClassifyInfoMapper.deleteNurseClassifyInfoById(id);
    }


    /**
     * 删除护理项目分类信息图片地址
     *
     * @param pictureUrl 护理项目分类信息图片地址
     **/
    private void deletePictureUrl(String pictureUrl) {
        if (StringUtils.isBlank(pictureUrl)) {
            return;
        }
        String picture = XinELuConfig.getProfile() + pictureUrl.replaceAll("/profile", "");
        File checkReportNameFile = new File(picture);
        if (checkReportNameFile.exists()) {
            boolean delete = checkReportNameFile.delete();
            if (BooleanUtils.isFalse(delete)) {
                throw new ServiceException("图片地址删除失败！");
            }
        }
    }

    /**
     * 查询护理机构分类信息列表
     *
     * @param nurseClassifyInfo 护理机构分类信息
     * @return 护理机构分类信息
     */
    @Override
    public List<NurseClassifyInfo> selectNurseStationClassifyList(NurseClassifyInfo nurseClassifyInfo) {
        nurseClassifyInfo.setClassifyType(NurseClassifyInfoEnum.NURSE_AGENCY.getInfo());
        return nurseClassifyInfoMapper.selectNurseClassifyInfoList(nurseClassifyInfo);
    }

    /**
     * 获取护理机构分类信息详细信息
     *
     * @param id 护理机构分类信息主键
     * @return 护理机构分类信息
     */
    @Override
    public NurseClassifyInfo selectNurseStationClassifyById(Long id) {
        return nurseClassifyInfoMapper.selectNurseClassifyInfoById(id);
    }

    /**
     * 新增护理机构分类信息
     *
     * @param nurseClassifyInfoList 护理机构分类信息集合
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertNurseStationClassifyInfo(List<NurseClassifyInfo> nurseClassifyInfoList) {
        if (CollectionUtils.isEmpty(nurseClassifyInfoList)) {
            return AjaxResult.error("请添加护理机构分类！");
        }
        //筛选传入名称 去重
        List<String> classifyNameList = nurseClassifyInfoList.stream().filter(Objects::nonNull).map(NurseClassifyInfo::getClassifyName).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(classifyNameList)) {
            return AjaxResult.success();
        }
        List<String> distinctClassifyNameList = classifyNameList.stream().distinct().collect(Collectors.toList());
        //集合取差集
        List<String> subtractNameList = new ArrayList<>(CollectionUtils.subtract(classifyNameList, distinctClassifyNameList));
        if (subtractNameList.size() > 0) {
            return AjaxResult.error("'" + subtractNameList.get(0) + "'重复，请修改后重新录入！");
        }
        //根据传入资讯名称查询数据库名称集合
        List<String> existNameList = nurseClassifyInfoMapper.selectNurseStationClassNameByList(distinctClassifyNameList, NurseClassifyInfoEnum.NURSE_AGENCY.getInfo());
        //集合取交集
        List<String> existRetainAllNameList = new ArrayList<>(CollectionUtils.intersection(existNameList, distinctClassifyNameList));
        if (existRetainAllNameList.size() > 0) {
            return AjaxResult.error("'" + existRetainAllNameList.get(0) + "'名称重复，请重新输入！");
        }
        for (NurseClassifyInfo nurseClassifyInfo : nurseClassifyInfoList) {
            // 设置创建人与创建时间
            nurseClassifyInfo.setCreateTime(LocalDateTime.now());
            nurseClassifyInfo.setCreateBy(SecurityUtils.getUsername());
            //增加护理机构类型
            nurseClassifyInfo.setClassifyType(NurseClassifyInfoEnum.NURSE_AGENCY.getInfo());
            //编号生成
            nurseClassifyInfo.setClassifyCode(Constants.NURSE_AGENCY + generateSystemCodeUtil.generateSystemCode(Constants.NURSE_AGENCY));
        }
        //批量新增
        int count = nurseClassifyInfoMapper.insertNurseStationClassifyList(nurseClassifyInfoList);
        if (count < 0) {
            throw new ServiceException("增加护理机构分类失败，请联系管理员！");
        }
        return AjaxResult.success();
    }

    /**
     * 修改护理机构分类信息
     *
     * @param nurseClassifyInfo 护理机构分类信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateNurseStationClassifyInfo(NurseClassifyInfo nurseClassifyInfo) {
        NurseClassifyInfo selectNurseStationClassify = nurseClassifyInfoMapper.selectNurseClassifyInfoById(nurseClassifyInfo.getId());
        if (Objects.isNull(selectNurseStationClassify)) {
            return AjaxResult.error("当前护理机构分类信息不存在，无法修改，请联系管理员！");
        }
        if (StringUtils.isNotBlank(selectNurseStationClassify.getClassifyName()) &&
                !nurseClassifyInfo.getClassifyName().equals(selectNurseStationClassify.getClassifyName())) {
            int nameCount = nurseClassifyInfoMapper.selectNurseStationClassNameCount(nurseClassifyInfo.getClassifyName(), NurseClassifyInfoEnum.NURSE_AGENCY.getInfo());
            if (nameCount > 0) {
                return AjaxResult.error("'" + nurseClassifyInfo.getClassifyName() + "'名称重复，请重新输入！");
            }
        }
        // 设置更新人与更新时间
        nurseClassifyInfo.setUpdateTime(LocalDateTime.now());
        nurseClassifyInfo.setUpdateBy(SecurityUtils.getUsername());
        nurseClassifyInfoMapper.updateNurseClassifyInfo(nurseClassifyInfo);
        //删除原有上传的分类图片
        if (StringUtils.isNotBlank(nurseClassifyInfo.getClassifyPictureUrl()) && StringUtils.isNotBlank(selectNurseStationClassify.getClassifyPictureUrl())
                && !nurseClassifyInfo.getClassifyPictureUrl().equals(selectNurseStationClassify.getClassifyPictureUrl())) {
            deletePictureUrl(selectNurseStationClassify.getClassifyPictureUrl());
        }
        return AjaxResult.success();
    }

    /**
     * 删除护理机构分类信息
     *
     * @param ids 需要删除的护理机构分类信息主键集合
     * @return AjaxResult
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult deleteNurseStationClassifyByIds(Long[] ids) {
        List<NurseClassifyInfo> nurseClassifyList = nurseClassifyInfoMapper.selectNurseStationClassByIds(ids);
        int count = nurseClassifyInfoMapper.deleteNurseClassifyInfoByIds(ids);
        if (count < 0) {
            throw new ServiceException("删除护理机构分类失败，请联系管理员！");
        }
        List<String> selectPicture = nurseClassifyList.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getClassifyPictureUrl())).map(NurseClassifyInfo::getClassifyPictureUrl).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(selectPicture)) {
            patientInfoService.updatePicture(selectPicture);
        }
        return AjaxResult.success();
    }
}