package com.diagbot.facade;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.diagbot.dto.CheckDeptDTO;
import com.diagbot.dto.CheckJobDTO;
import com.diagbot.dto.CheckUserDTO;
import com.diagbot.dto.DeptCheckUserDTO;
import com.diagbot.entity.BasDeptInfo;
import com.diagbot.entity.MedCheckInfo;
import com.diagbot.entity.SysRole;
import com.diagbot.entity.SysUser;
import com.diagbot.entity.SysUserDept;
import com.diagbot.entity.SysUserRole;
import com.diagbot.enums.CheckJobTypeEnum;
import com.diagbot.enums.CheckerRoleEnum;
import com.diagbot.enums.IsDeleteEnum;
import com.diagbot.exception.CommonErrorCode;
import com.diagbot.exception.CommonException;
import com.diagbot.service.impl.MedCheckInfoServiceImpl;
import com.diagbot.util.DateUtil;
import com.diagbot.util.ListUtil;
import com.diagbot.util.StringUtil;
import com.diagbot.util.SysUserUtils;
import com.diagbot.vo.CheckJobPageVO;
import com.diagbot.vo.CheckUserVO;
import com.diagbot.vo.DistributionJobVO;
import com.diagbot.vo.MedCheckInfoAddVO;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author wangfeng
 * @Description:
 * @date 2020-07-06 13:27
 */
@Component
public class MedCheckInfoFacade extends MedCheckInfoServiceImpl {

    @Autowired
    SysUserFacade sysUserFacade;
    @Autowired
    SysUserRoleFacade sysUserRoleFacade;
    @Autowired
    SysRoleFacade sysRoleFacade;
    @Autowired
    SysUserDeptFacade sysUserDeptFacade;
    @Autowired
    BasDoctorInfoFacade basDoctorInfoFacade;
    @Autowired
    BasDeptInfoFacade basDeptInfoFacade;


    /**
     * @param medCheckInfoAddVO
     * @return
     */
    public Boolean addMedCheckInfos(MedCheckInfoAddVO medCheckInfoAddVO) {
        boolean res = false;
        Date now = DateUtil.now();
        //获取人员id 和 该人员的医院id
        Long hospitalId = Long.valueOf(SysUserUtils.getCurrentHospitalID());
        Long principleId = Long.valueOf(SysUserUtils.getCurrentPrincipleID());
        checkAppealRelation();
        QueryWrapper<SysUser> userQuer = new QueryWrapper<>();
        userQuer.eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("id", principleId)
                .eq("status", 1);
        SysUser user = sysUserFacade.getOne(userQuer);
        String principleName = user.getLinkman();
        Map<String, Object> mapAll = new HashMap<String, Object>();
        mapAll.put("is_deleted", IsDeleteEnum.N.getKey());
        mapAll.put("behospital_code", medCheckInfoAddVO.getBehospitalCode());
        mapAll.put("hospital_id", hospitalId);
        mapAll.put("check_type", medCheckInfoAddVO.getCheckType());
        QueryWrapper<MedCheckInfo> medCheckInfoQuerys = new QueryWrapper<>();
        medCheckInfoQuerys.allEq(mapAll);
        MedCheckInfo data = this.getOne(medCheckInfoQuerys, false);
        if (data != null) {
            //检验核查人是否是本人
            if (data.getCheckId().equals(principleId)) {
                res = saveNew(mapAll, now, hospitalId, principleId, principleName, medCheckInfoAddVO);
            } else {
                throw new CommonException(CommonErrorCode.NOT_EXISTS, "该数据已被人核查，您暂无权限！");
            }
        } else {
            //该病历没有核查的时候， 就添加核查记录
            MedCheckInfo medCheckInfo = new MedCheckInfo();
            medCheckInfo.setGmtCreate(now);
            medCheckInfo.setGmtModified(now);
            medCheckInfo.setHospitalId(hospitalId);
            medCheckInfo.setCheckId(principleId);
            medCheckInfo.setCheckName(principleName);
            medCheckInfo.setCheckTime(now);
            medCheckInfo.setCheckType(medCheckInfoAddVO.getCheckType());
            medCheckInfo.setStatus(medCheckInfoAddVO.getCheckStatus());
            medCheckInfo.setBehospitalCode(medCheckInfoAddVO.getBehospitalCode());
            res = this.save(medCheckInfo);
        }

        return res;
    }

    private void checkAppealRelation() {

    }

    /**
     * @param mapAll
     * @param now
     * @param hospitalId
     * @param principleId
     * @param principleName
     * @param medCheckInfoAddVO
     * @return
     */
    public boolean saveNew(Map<String, Object> mapAll, Date now, Long hospitalId, Long principleId, String principleName, MedCheckInfoAddVO medCheckInfoAddVO) {
        boolean res = false;
        UpdateWrapper<MedCheckInfo> medCheckInfoUpdate = new UpdateWrapper<>();
        medCheckInfoUpdate.allEq(mapAll).set("is_deleted", IsDeleteEnum.Y.getKey()).set("gmt_modified", now);
        res = this.update(medCheckInfoUpdate);
        //删除原来的成功后， 再新建一条核查数据
        if (res) {
            MedCheckInfo medCheckInfo = new MedCheckInfo();
            medCheckInfo.setGmtCreate(now);
            medCheckInfo.setGmtModified(now);
            medCheckInfo.setHospitalId(hospitalId);
            medCheckInfo.setCheckId(principleId);
            medCheckInfo.setCheckName(principleName);
            medCheckInfo.setCheckTime(now);
            medCheckInfo.setCheckType(medCheckInfoAddVO.getCheckType());
            medCheckInfo.setStatus(medCheckInfoAddVO.getCheckStatus());
            medCheckInfo.setBehospitalCode(medCheckInfoAddVO.getBehospitalCode());
            res = this.save(medCheckInfo);
        }
        return res;
    }

    /**
     * @Author songxl
     * @Description 获取操作用户的核查科室以及人员
     * @Date 2021/5/14
     * @Param []
     * @Return java.util.Map<java.lang.String, java.util.List < com.diagbot.dto.CheckDeptDTO>>
     * @MethodName getCheckUserMap
     */
    public IPage<CheckJobDTO> getUserCheckList(CheckJobPageVO checkJobVO) {
        //校验
        userCheckPageSet(checkJobVO);
        //质控管理员要判断该角色是否是质控科
        //1.获取质控科id
        //获取人员id 和 该人员的医院id
        Long hospitalId = Long.valueOf(SysUserUtils.getCurrentHospitalID());
        Long principleId = Long.valueOf(SysUserUtils.getCurrentPrincipleID());
        //获取核查监管相关角色id
        List<Long> checkRoleIds = sysRoleFacade.list(new QueryWrapper<SysRole>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .like("name", "监管人员")
        ).stream().map(SysRole::getId).collect(Collectors.toList());
        //查询该角色的所有角色id
        List<Long> roleIds = sysUserRoleFacade.list(new QueryWrapper<SysUserRole>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("user_id", principleId)
        ).stream().distinct().map(SysUserRole::getRoleId).collect(Collectors.toList());
        List<Long> searchRoleIds = new ArrayList<>();
        //当前用户是监管人员或者是超级管理员
        if (roleIds.contains(-1L)) {
            searchRoleIds.addAll(checkRoleIds);
        } else {
            searchRoleIds.addAll(containsRole(checkRoleIds, roleIds));
        }
        if (searchRoleIds.isEmpty()) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该用户不是核查监管人员!");
        }
        //质控科监管人员
        if (searchRoleIds.contains(CheckerRoleEnum.QUAT_SUPERVISOR.getKey() * 1l)
                && (CheckJobTypeEnum.QUAT_SUPERVISOR.getKey() + "").equals(checkJobVO.getJobType())) {
            //用户是不是质管科人员校验
            BasDeptInfo deptInfo = basDeptInfoFacade.getOne(new QueryWrapper<BasDeptInfo>()
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .eq("hospital_id", hospitalId)
                    .eq("station", "质管"));
            if (deptInfo == null || deptInfo.getDeptId() == null) {
                throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "科室质管科不存在,请联系管理员!");
            }
            //2.获取监管人员所在科室集合
            List<String> deptIds = sysUserDeptFacade.list(new QueryWrapper<SysUserDept>()
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .eq("hospital_id", hospitalId)
                    .eq("user_id", principleId)
            ).stream().map(SysUserDept::getDeptId).collect(Collectors.toList());
            //3.判断这个人是否在质控科
//            if(deptIds.contains(zkkDeptId))
//            {
//
//            }
            //质控科任务分配列表是任务类型是质控科的任务与科室无关
            return getCheckList(checkJobVO);
        }
        //临床科室监管人员 或 院级监管人员
        else if (searchRoleIds.contains(CheckerRoleEnum.DEPT_SUPERVISOR.getKey() * 1l)
                || searchRoleIds.contains(CheckerRoleEnum.HOSP_SUPERVISOR.getKey() * 1l)) {
            //查询没有指定科室
            if (checkJobVO.getDeptList() == null || checkJobVO.getDeptList().isEmpty()) {
                //科室获取待分配任务所在科室集合
                if (CheckJobTypeEnum.DEPT_SUPERVISOR.getKey() == Integer.parseInt(checkJobVO.getJobType())) {
                    List<String> deptIds = sysUserDeptFacade.list(new QueryWrapper<SysUserDept>()
                            .eq("is_deleted", IsDeleteEnum.N.getKey())
                            .eq("hospital_id", hospitalId)
                            .eq("user_id", principleId)
                    ).stream().map(SysUserDept::getDeptId).collect(Collectors.toList());

                    if (deptIds != null && !deptIds.isEmpty()) {
                        checkJobVO.setDeptList(deptIds);
                        return getCheckList(checkJobVO);
                    } else {
                        return new CheckJobPageVO();
                    }
                }
                //院区获取
                if (CheckJobTypeEnum.HOSP_SUPERVISOR.getKey() == Integer.parseInt(checkJobVO.getJobType())) {
//                    //获取管理员所在科室
//                    List<String> deptIds = sysUserDeptFacade.list(new QueryWrapper<SysUserDept>()
//                            .eq("is_deleted", IsDeleteEnum.N.getKey())
//                            .eq("hospital_id",hospitalId)
//                            .eq("user_id",principleId)
//                    ).stream().map(SysUserDept::getDeptId).collect(Collectors.toList());
//                    //获取所有院区核查人员所在科室
//                    CheckUserVO checkUserVOS = new CheckUserVO();
//                    checkUserVOS.setRoleIds(Lists.newArrayList(CheckerRoleEnum.HOSP_GENERAL.getKey()*1l));
//                    checkUserVOS.setDeptStations(Lists.newArrayList("住院"));
//                    checkUserVOS.setHospitalId(hospitalId);
//                    List<CheckUserDTO> checkUserDTOS = baseMapper.getCheckUser(checkUserVOS);
//                    Set<String> hospGeneralDeptIds= checkUserDTOS.stream()
//                            .map(CheckUserDTO::getDeptId).collect(Collectors.toSet());
//                    //去除管理员所在科室
//                    if(hospGeneralDeptIds!=null&&!hospGeneralDeptIds.isEmpty()&&deptIds!=null){
//                        hospGeneralDeptIds.removeAll(deptIds);
//                        checkJobVO.setDeptList(new ArrayList<>(hospGeneralDeptIds));
//                    }
                    return getCheckList(checkJobVO);
                }
            }
            return getCheckList(checkJobVO);
        } else {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该用户的角色和任务类型不对应！");
        }
    }

    /**
     * @Author songxl
     * @Description 待分配列表页面校验
     * @Date 2021/5/18
     * @Param [checkJobVO]
     * @Return void
     * @MethodName userCheckPageSet
     */
    private void userCheckPageSet(CheckJobPageVO checkJobVO) {
        if (StringUtil.isBlank(checkJobVO.getStartTime()) && StringUtil.isBlank(checkJobVO.getEndTime())
                && StringUtil.isBlank(checkJobVO.getBehosDateStart()) && StringUtil.isBlank(checkJobVO.getBehosDateEnd())) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "没有时间区间!");
        }
        if (StringUtil.isBlank(checkJobVO.getJobType())) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "没有任务类型!");
        }
        if (StringUtil.isNotBlank(checkJobVO.getBehosDateStart()) && StringUtil.isNotBlank(checkJobVO.getBehosDateEnd())) {
            if (DateUtil.after(DateUtil.parseDate(checkJobVO.getBehosDateStart()),
                    DateUtil.parseDate(checkJobVO.getBehosDateEnd()))) {
                throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "出院时间的开始时间必须小于结束时间！");
            }
        }
        if (StringUtil.isNotBlank(checkJobVO.getStartTime()) && StringUtil.isNotBlank(checkJobVO.getEndTime())) {
            if (DateUtil.after(DateUtil.parseDate(checkJobVO.getStartTime()),
                    DateUtil.parseDate(checkJobVO.getEndTime()))) {
                throw new CommonException(CommonErrorCode.PARAM_IS_ERROR, "任务生成的开始时间必须小于结束时间！");
            }
        }

    }

    /**
     * @Author songxl
     * @Description 获取操作用户的核查科室以及科室核查人员
     * @Date 2021/5/14
     * @Param []
     * @Return java.util.Map<java.lang.String, java.util.List < com.diagbot.dto.CheckDeptDTO>>
     * @MethodName getCheckUserMap
     */
    public Map<String, List<CheckDeptDTO>> getCheckUserMap() {

        //1.获取当前用户对应的管理员角色
        //获取人员id 和 该人员的医院id
        Long hospitalId = Long.valueOf(SysUserUtils.getCurrentHospitalID());
        Long principleId = Long.valueOf(SysUserUtils.getCurrentPrincipleID());
        //获取核查监管相关角色id
        List<Long> checkRoleIds = sysRoleFacade.list(new QueryWrapper<SysRole>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .like("name", "监管人员")
        ).stream().map(SysRole::getId).collect(Collectors.toList());
        //查询该角色的所有角色id
        List<Long> roleIds = sysUserRoleFacade.list(new QueryWrapper<SysUserRole>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("user_id", principleId)
        ).stream().distinct().map(SysUserRole::getRoleId).collect(Collectors.toList());
        List<Long> searchRoleIds = new ArrayList<>();
        //当前用户是监管人员或者是超级管理员
        if (roleIds.contains(-1L)) {
            searchRoleIds.addAll(checkRoleIds);
        } else {
            searchRoleIds.addAll(containsRole(checkRoleIds, roleIds));
        }
        if (searchRoleIds.isEmpty()) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "该用户不是核查监管人员!");
        }
        //2.获取相应角色对应的科室以及核查人员
        Map<String, List<CheckDeptDTO>> checkUserMap = getCheckRoleMap(searchRoleIds, hospitalId, principleId);
        return checkUserMap;
    }

    /**
     * @Author songxl
     * @Description 获取相应角色对应的科室以及核查人员
     * @Date 2021/5/14
     * @Param [searchRoleIds]
     * @Return java.util.Map<java.lang.String, java.util.List < java.util.Map < java.lang.String, java.lang.Object>>>
     * @MethodName getCheckRoleMap
     */

    private Map<String, List<CheckDeptDTO>> getCheckRoleMap(List<Long> searchRoleIds, Long hospitalId, Long principleId) {
        Map<String, List<CheckDeptDTO>> checkRoleMap = new HashMap<>();
        for (Long id : searchRoleIds) {
            try {
                //不同角色不同查询方式
                switch (id.intValue()) {
                    //临床科室监管人员
                    case 4:
                        getDeptCheckInfo(checkRoleMap, hospitalId, principleId);
                        break;
                    //质控科监管人员
                    case 5:
                        getZKKCheckInfo(checkRoleMap, hospitalId, principleId);
                        break;
                    //院级监管人员
                    case 6:
                        getYQCheckInfo(checkRoleMap, hospitalId, principleId);
                        break;
                    default:
                        break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return checkRoleMap;
    }

    /**
     * @Author songxl
     * @Description 院区管理员获取管理的科室以及科室包涵质控人员
     * @Date 2021/5/17
     * @Param [checkRoleMap, hospitalId, principleId]
     * @Return void
     * @MethodName getYQCheckInfo
     */
    private void getYQCheckInfo(Map<String, List<CheckDeptDTO>> checkRoleMap, Long hospitalId, Long principleId) {
        //1.获取院级质控人员有哪些
        //1.1获取院级质控人员角色id
        CheckUserVO checkUserVOS = new CheckUserVO();
        checkUserVOS.setRoleIds(Lists.newArrayList(CheckerRoleEnum.HOSP_GENERAL.getKey() * 1l));
        checkUserVOS.setDeptStations(Lists.newArrayList("住院"));
        checkUserVOS.setHospitalId(hospitalId);
        List<CheckUserDTO> checkUserDTOS = baseMapper.getCheckUser(checkUserVOS);
        //2.用户科室整合
        margeDept(checkRoleMap, checkUserDTOS, CheckerRoleEnum.HOSP_SUPERVISOR.getKey() + "");
        if (!ListUtil.isEmpty(checkRoleMap.get(CheckerRoleEnum.HOSP_SUPERVISOR.getKey() + ""))) {
            //2.3获取所有医生信息的核查数
            CheckUserVO checkUserVO = new CheckUserVO();
            checkUserVO.setJobType(CheckJobTypeEnum.HOSP_SUPERVISOR.getKey());
            //通过核查人员id获取核查人员的核查任务数
            List<DeptCheckUserDTO> userJobs = baseMapper.getDeptJobNumByUserId(checkUserVO);
            addCheckInfoMaps(checkRoleMap, null, userJobs, checkUserDTOS, CheckerRoleEnum.HOSP_SUPERVISOR.getKey(), CheckJobTypeEnum.HOSP_SUPERVISOR.getKey());
        } else {
            checkRoleMap.put(CheckerRoleEnum.HOSP_SUPERVISOR.getKey() + "", new ArrayList<>());
        }

    }

    /**
     * @Author songxl
     * @Description 院区人员用户科室合并
     * @Date 2021/6/1
     * @Param [checkRoleMap, checkUserDTOS, s]
     * @Return void
     * @MethodName margeDept
     */
    private void margeDept(Map<String, List<CheckDeptDTO>> checkRoleMap, List<CheckUserDTO> checkUserDTOS, String roleId) {
        if (ListUtil.isEmpty(checkUserDTOS)) {
            return;
        }
        Set<String> userIds = checkUserDTOS.stream().map(CheckUserDTO::getDoctorId).collect(Collectors.toSet());
        try {
            List<CheckDeptDTO> tempDepts = new ArrayList<>();
            //全部
            CheckDeptDTO allCheckDept = new CheckDeptDTO();
            allCheckDept.setDeptId("-1");
            allCheckDept.setDeptName("全部");
            userIds.stream().forEach(userId -> {
                //获取该用户的科室拼接
                StringBuilder deptIdBuilder = new StringBuilder();
                StringBuilder deptNameBuilder = new StringBuilder();
                StringBuilder userName = new StringBuilder();
                checkUserDTOS.stream().forEach(checkUserDTO -> {
                    if (userId.equals(checkUserDTO.getDoctorId())) {
                        deptIdBuilder.append(checkUserDTO.getDeptId()).append(",");
                        deptNameBuilder.append(checkUserDTO.getDeptName()).append(",");
                        if (userName.length() == 0) {
                            userName.append(checkUserDTO.getDoctorName());
                        }
                        //除了全部以外添加科室信息
                        if (!tempDepts.stream().map(CheckDeptDTO::getDeptId).collect(Collectors.toList())
                                .contains(checkUserDTO.getDeptId())) {
                            CheckDeptDTO oneCheckUser = new CheckDeptDTO();
                            oneCheckUser.setDeptId(checkUserDTO.getDeptId());
                            oneCheckUser.setDeptName(checkUserDTO.getDeptName());
                            tempDepts.add(oneCheckUser);
                        }
                    }
                });

                //合并科室
                String deptId = deptIdBuilder.substring(0, deptIdBuilder.length() - 1);
                String deptName = deptNameBuilder.substring(0, deptNameBuilder.length() - 1);
                //科室用户
                DeptCheckUserDTO deptCheckUserDTO = new DeptCheckUserDTO();
                deptCheckUserDTO.setDoctorId(userId);
                deptCheckUserDTO.setDoctorName(userName.toString());
                deptCheckUserDTO.setDeptId(deptId);
                deptCheckUserDTO.setDeptName(deptName);
                AtomicBoolean hasFlag = new AtomicBoolean(false);
                //全部处理
                if (ListUtil.isEmpty(allCheckDept.getDeptcheckUsers())) {
                    allCheckDept.getDeptcheckUsers().add(deptCheckUserDTO);
                }
                allCheckDept.getDeptcheckUsers().forEach(oneDeptCheckUser -> {
                    if (!userId.equals(oneDeptCheckUser.getDoctorId())) {
                        hasFlag.set(true);
                    }
                });
                if (hasFlag.get()) {
                    allCheckDept.getDeptcheckUsers().add(deptCheckUserDTO);
                }

                tempDepts.stream().forEach(checkDeptDTO -> {
                    if (deptId.contains(checkDeptDTO.getDeptId())) {
                        checkDeptDTO.getDeptcheckUsers().add(deptCheckUserDTO);
                    }
                });
            });
            tempDepts.add(0, allCheckDept);
            checkRoleMap.put(roleId + "", tempDepts);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * @Author songxl
     * @Description 质控科管理员获取管理的科室以及科室包涵质控人员
     * @Date 2021/5/17
     * @Param [checkRoleMap, hospitalId, principleId]
     * @Return void
     * @MethodName getZKKCheckInfo
     */
    private void getZKKCheckInfo(Map<String, List<CheckDeptDTO>> checkRoleMap, Long hospitalId, Long principleId) {
        //1.获取质控科id
        BasDeptInfo deptInfo = basDeptInfoFacade.getOne(new QueryWrapper<BasDeptInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("station", "质管"));
        if (deptInfo == null || deptInfo.getDeptId() == null) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "科室质管科不存在,请联系管理员!");
        }
//        //2.获取监管人员所在科室集合
//        List<String> deptIds = sysUserDeptFacade.list(new QueryWrapper<SysUserDept>()
//                .eq("is_deleted", IsDeleteEnum.N.getKey())
//                .eq("hospital_id",hospitalId)
//                .eq("user_id",principleId)
//        ).stream().map(SysUserDept::getDeptId).collect(Collectors.toList());
//        //3.判断这个人是否在质控科
//        if(deptIds.contains(zkkDeptId))
//        {
//
//
//        }
        CheckUserVO checkUserVOS = new CheckUserVO();
        //质管科人员角色
        checkUserVOS.setRoleIds(Lists.newArrayList(CheckerRoleEnum.QUAT_GENERAL.getKey() * 1l));
        //质管科
        checkUserVOS.setDeptStations(Lists.newArrayList("质管"));
        checkUserVOS.setDeptIds(Lists.newArrayList(deptInfo.getDeptId()));
        checkUserVOS.setHospitalId(hospitalId);
        List<CheckUserDTO> checkUserDTOS = baseMapper.getCheckUser(checkUserVOS);
        //2.1获取科室详情
        Map<String, String> deptMap = basDeptInfoFacade.list(new QueryWrapper<BasDeptInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .in("dept_id", Lists.newArrayList(deptInfo.getDeptId()))).stream()
                .collect(Collectors.toMap(BasDeptInfo::getDeptId, BasDeptInfo::getDeptName, (v1, v2) -> v2));
        if (deptMap != null && !deptMap.isEmpty()) {
            //2.3获取质控科核查人员的核查数
            List<String> doctorIds = checkUserDTOS.stream().map(CheckUserDTO::getDoctorId).collect(Collectors.toList());
            CheckUserVO checkUserVO = new CheckUserVO();
            checkUserVO.setJobType(CheckJobTypeEnum.QUAT_SUPERVISOR.getKey());
            checkUserVO.setUserList(doctorIds);
            //通过核查人员id获取核查人员的核查任务数
            List<DeptCheckUserDTO> userJobs = baseMapper.getDeptJobNumByUserId(checkUserVO);
            userJobs.stream().forEach(deptCheckUserDTO -> {
                deptCheckUserDTO.setDeptId(deptInfo.getDeptId());
            });
            addCheckInfoMaps(checkRoleMap, deptMap, userJobs, checkUserDTOS, CheckerRoleEnum.QUAT_SUPERVISOR.getKey(), CheckJobTypeEnum.QUAT_SUPERVISOR.getKey());
        } else {
            checkRoleMap.put(CheckerRoleEnum.QUAT_SUPERVISOR.getKey() + "", new ArrayList<>());
        }

    }

    /**
     * @Author songxl
     * @Description 临床科室管理员获取管理的科室以及科室包涵质控人员
     * @Date 2021/5/17
     * @Param [checkRoleMap, hospitalId, principleId]
     * @Return void
     * @MethodName getDeptCheckInfo
     */
    private void getDeptCheckInfo(Map<String, List<CheckDeptDTO>> checkRoleMap, Long hospitalId, Long principleId) {

        //1.获取监管人员所在科室集合
        List<String> deptIds = sysUserDeptFacade.list(new QueryWrapper<SysUserDept>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("user_id", principleId)
        ).stream().map(SysUserDept::getDeptId).collect(Collectors.toList());
        if (deptIds.isEmpty()) {
            return;
        }
        //1.2去除质管科
        BasDeptInfo deptInfo = basDeptInfoFacade.getOne(new QueryWrapper<BasDeptInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .eq("station", "质管"));
        if (deptInfo == null || deptInfo.getDeptId() == null) {
            throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "科室质管科不存在,请联系管理员!");
        }
        if (StringUtil.isNotBlank(deptInfo.getDeptId())) {
            deptIds.remove(deptInfo.getDeptId());
        }
        CheckUserVO checkUserVOS = new CheckUserVO();
        //科室普通核查人员角色筛选
        checkUserVOS.setRoleIds(Lists.newArrayList(CheckerRoleEnum.DEPT_GENERAL.getKey() * 1l));
        checkUserVOS.setDeptIds(deptIds);
        checkUserVOS.setDeptStations(Lists.newArrayList("住院"));
        checkUserVOS.setHospitalId(hospitalId);
        List<CheckUserDTO> checkUserDTOS = baseMapper.getCheckUser(checkUserVOS);
        //2.1获取科室详情
        Map<String, String> deptMap = basDeptInfoFacade.list(new QueryWrapper<BasDeptInfo>()
                .eq("is_deleted", IsDeleteEnum.N.getKey())
                .eq("hospital_id", hospitalId)
                .in("dept_id", deptIds)).stream()
                .collect(Collectors.toMap(BasDeptInfo::getDeptId, BasDeptInfo::getDeptName, (v1, v2) -> v2));
        if (deptMap != null && !deptMap.isEmpty()) {
            //2.3获取所有医生信息的核查数
            List<String> doctorIds = checkUserDTOS.stream().map(CheckUserDTO::getDoctorId).collect(Collectors.toList());
            CheckUserVO checkUserVO = new CheckUserVO();
            checkUserVO.setJobType(CheckJobTypeEnum.DEPT_SUPERVISOR.getKey());
            checkUserVO.setUserList(doctorIds);
            checkUserVO.setDeptIds(deptIds);
            //通过核查人员id获取核查人员的核查任务数
            List<DeptCheckUserDTO> userJobs = baseMapper.getDeptJobNumByUserId(checkUserVO);
            addCheckInfoMaps(checkRoleMap, deptMap, userJobs, checkUserDTOS, CheckerRoleEnum.DEPT_SUPERVISOR.getKey(), CheckJobTypeEnum.DEPT_SUPERVISOR.getKey());
        } else {
            checkRoleMap.put(CheckerRoleEnum.DEPT_SUPERVISOR.getKey() + "", new ArrayList<>());
        }


    }

    /**
     * @Author songxl
     * @Description 拼装科室、核查人员、任务数对象
     * @Date 2021/5/17
     * @Param [checkRoleMap, doctorInfos, userJobs, deptInfos, roleId]
     * @Return void
     * @MethodName addCheckInfoMap
     */
    private void addCheckInfoMaps(Map<String, List<CheckDeptDTO>> checkRoleMap, Map<String, String> deptMap,
                                  List<DeptCheckUserDTO> userJobs, List<CheckUserDTO> checkUserDTOS, int roleId, int jobType) {
        //非院区任务
        if (CheckJobTypeEnum.HOSP_SUPERVISOR.getKey() != jobType) {
            if (deptMap.isEmpty() || checkUserDTOS.isEmpty()) {
                return;
            }
            checkRoleMap.put(roleId + "", new ArrayList<>());
            //遍历科室
            for (String deptId : deptMap.keySet()) {
                //科室对象
                CheckDeptDTO checkDeptDTO = new CheckDeptDTO();
                checkDeptDTO.setDeptId(deptId);
                checkDeptDTO.setDeptName(deptMap.get(deptId));
                checkDeptDTO.setDeptcheckUsers(new ArrayList<DeptCheckUserDTO>());
                //遍历医生
                for (CheckUserDTO checkUserDTO : checkUserDTOS) {
                    //同一科室
                    if (checkDeptDTO.getDeptId().equals(checkUserDTO.getDeptId())) {
                        DeptCheckUserDTO deptCheckUserDTO = new DeptCheckUserDTO();
                        deptCheckUserDTO.setDeptId(checkUserDTO.getDeptId());
                        deptCheckUserDTO.setDeptName(checkUserDTO.getDeptName());
                        deptCheckUserDTO.setDoctorId(checkUserDTO.getDoctorId());
                        deptCheckUserDTO.setDoctorName(checkUserDTO.getDoctorName());
                        checkDeptDTO.getDeptcheckUsers().add(deptCheckUserDTO);
                    }
                }
                for (DeptCheckUserDTO deptCheckUserDTO : checkDeptDTO.getDeptcheckUsers()) {
                    //遍历数量
                    for (DeptCheckUserDTO jobNumDto : userJobs) {
                        //这个科室有这个人
                        if (deptCheckUserDTO.getDeptId().equals(jobNumDto.getDeptId())) {
                            if (deptCheckUserDTO.getDoctorId().equals(jobNumDto.getDoctorId())) {
                                if (jobNumDto.getStatus() == 0) {
                                    deptCheckUserDTO.setJobNum(jobNumDto.getJobNum());
                                }
                                if (jobNumDto.getStatus() == 1) {

                                    deptCheckUserDTO.setCheckNum(jobNumDto.getJobNum());
                                }
                            }

                        }
                    }
                }
                checkRoleMap.get(roleId + "").add(checkDeptDTO);
            }
        }
        //院区任务不是同一科室的人员数量增加
        else if (CheckJobTypeEnum.HOSP_SUPERVISOR.getKey() == jobType) {
            checkRoleMap.get(roleId + "").stream().forEach(checkDeptDTO -> {
                if (!ListUtil.isEmpty(checkDeptDTO.getDeptcheckUsers())) {
                    checkDeptDTO.getDeptcheckUsers().stream().forEach(deptCheckUser -> {
                        userJobs.stream().forEach(userJob -> {
                            if (deptCheckUser.getDoctorId().equals(userJob.getDoctorId())) {
                                if (userJob.getStatus() == 0) {
                                    deptCheckUser.setJobNum(userJob.getJobNum());
                                }
                                if (userJob.getStatus() == 1) {
                                    deptCheckUser.setCheckNum(userJob.getJobNum());
                                }
                            }
                        });
                    });
                }
            });
        }
    }


    /**
     * @Author songxl
     * @Description list求交集
     * @Date 2021/5/14
     * @Param [checkRoleIds, roleIds]
     * @Return java.util.List<java.lang.Long>
     * @MethodName containsRole
     */
    private List<Long> containsRole(List<Long> checkRoleIds, List<Long> roleIds) {

        List<Long> searchRoleIds = new ArrayList<>();
        for (Long id : roleIds) {
            if (checkRoleIds.contains(id)) {
                searchRoleIds.add(id);
            }
        }
        return searchRoleIds;
    }

    /**
     * @Author songxl
     * @Description 分配/取消核查任务
     * @Date 2021/5/17
     * @Param [distributionJobVO]
     * @Return boolean
     * @MethodName distributionJobs
     */
    public boolean distributionJobs(DistributionJobVO distributionJobVO) {

        //1非空校验
        if (StringUtil.isBlank(distributionJobVO.getCheckId()) ||
                StringUtil.isBlank(distributionJobVO.getCheckName()) ||
                StringUtil.isBlank(distributionJobVO.getDistributionType()) ||
                distributionJobVO.getBehospitalCodes() == null ||
                distributionJobVO.getBehospitalCodes().isEmpty()) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "入参为空");
        }
        if (StringUtil.isBlank(distributionJobVO.getCheckDept())) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "核查人科室（checkDept）为空");
        }
        if (distributionJobVO.getBehospitalDepts() == null
                || distributionJobVO.getBehospitalDepts().isEmpty()) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "核查任务科室集合（behospitalDepts）为空");
        }
        if (StringUtil.isEmpty(distributionJobVO.getJobType())) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "核查任务类型（jobType）为空");
        }
        //全院的话要判断院级核查人员和核查病历不是同一科室
        if (CheckJobTypeEnum.HOSP_SUPERVISOR.getKey() == Integer.parseInt(distributionJobVO.getJobType())) {
            for (String deptId : distributionJobVO.getCheckDept().split(",")) {
                if (distributionJobVO.getBehospitalDepts().contains(deptId)) {
                    throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "院级核查人员和核查病历是同一科室");
                }
            }

        }
        //获取人员id 和 该人员的医院id
        Long hospitalId = Long.valueOf(SysUserUtils.getCurrentHospitalID());
        Long principleId = Long.valueOf(SysUserUtils.getCurrentPrincipleID());
        //2.获取任务类型 0分配 1取消
        String distributionType = distributionJobVO.getDistributionType();
        //3 分配
        if (StringUtil.isNotBlank(distributionType) && "0".equals(distributionType)) {
            //3.1 任务未分配校验
            List<String> distributionNames = this.list(new QueryWrapper<MedCheckInfo>()
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .eq("hospital_id", hospitalId)
                    .in("behospital_code", distributionJobVO.getBehospitalCodes())
            ).stream().filter(s -> s.getJobDistributionName() != null).map(MedCheckInfo::getJobDistributionName)
                    .collect(Collectors.toList());
            if (distributionNames != null && distributionNames.size() > 0) {
                throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "待分配任务列表存在已分配任务！");
            }

            //获取分配用户信息
            QueryWrapper<SysUser> userQuer = new QueryWrapper<>();
            userQuer.eq("is_deleted", IsDeleteEnum.N.getKey())
                    .eq("id", principleId)
                    .eq("status", 1);
            SysUser user = sysUserFacade.getOne(userQuer);
            String principleName = user.getLinkman();
            //用户名称如果是null(目的：分配用户名为null表示用户未分配)
            if (principleName == null) {
                principleName = "";
            }
            Date now = DateUtil.now();
            //3.2分配核查任务
            return this.update(new UpdateWrapper<MedCheckInfo>()
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .eq("hospital_id", hospitalId)
                    .in("behospital_code", distributionJobVO.getBehospitalCodes())
                    .set("job_distributor", principleId)
                    .set("job_distribution_name", principleName)
                    .set("check_id", distributionJobVO.getCheckId())
                    .set("check_name", distributionJobVO.getCheckName())
                    .set("job_distribution_time", now));

        }
        //4 取消分配
        else if (StringUtil.isNotBlank(distributionType) && "1".equals(distributionType)) {
            //4.1 任务已取消校验
            Set<Long> checkIds = this.list(new QueryWrapper<MedCheckInfo>()
                    .eq("is_deleted", IsDeleteEnum.N.getKey())
                    .eq("hospital_id", hospitalId)
                    .in("behospital_code", distributionJobVO.getBehospitalCodes())
            ).stream().map(MedCheckInfo::getCheckId).collect(Collectors.toSet());
            //4.2获取出来的核查用户存在但不是一个
            if (checkIds == null || checkIds.isEmpty() ||
                    (checkIds.size() != 1 && checkIds.contains(distributionJobVO.getCheckId()))) {
                throw new CommonException(CommonErrorCode.SERVER_IS_ERROR, "待取消分配任务列表不存在或存在不是该用户的任务！");
            } else {
                Date now = DateUtil.now();
                //4.3取消分配
                Long a = null;
                return this.update(new UpdateWrapper<MedCheckInfo>()
                        .eq("is_deleted", IsDeleteEnum.N.getKey())
                        .eq("hospital_id", hospitalId)
                        .eq("check_id", distributionJobVO.getCheckId())
                        .in("behospital_code", distributionJobVO.getBehospitalCodes())
                        .set("job_distributor", a)
                        .set("job_distribution_name", a)
                        .set("check_id", a)
                        .set("check_name", a)
                        .set("job_distribution_time", now));
            }
        }

        return false;
    }

    /**
     * @Author songxl
     * @Description 获取指定核查人员的核查任务
     * @Date 2021/5/17
     * @Param [checkJobVO]
     * @Return java.util.List<com.diagbot.dto.CheckJobDTO>
     * @MethodName getCheckListByUserId
     */
    public IPage<CheckJobDTO> getCheckListByUserId(CheckJobPageVO checkJobVO) {
        //非空校验
        if (StringUtil.isBlank(checkJobVO.getCheckId())) {
            throw new CommonException(CommonErrorCode.PARAM_IS_NULL, "没有传核查用户id!");
        }
        IPage<CheckJobDTO> checkJobDTOS = baseMapper.getCheckListByUserId(checkJobVO);
        //获取当前登录人员
        Long principleId = Long.valueOf(SysUserUtils.getCurrentPrincipleID());
        List<CheckJobDTO> outCheckJobDTOS = new ArrayList<>();
        //判断分配人员是否是当前人员
        for (CheckJobDTO checkJobDTO : checkJobDTOS.getRecords()) {
            if (principleId.equals(checkJobDTO.getJobDistributor())) {
                checkJobDTO.setDelFlag(true);
            } else {
                checkJobDTO.setDelFlag(false);
            }
            outCheckJobDTOS.add(checkJobDTO);
        }
        checkJobDTOS.setRecords(outCheckJobDTOS);
        return checkJobDTOS;
    }
}
