package com.ruoyi.system.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.constant.SysPostEnum;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysUserPost;
import com.ruoyi.system.domain.UserPostAuthority;
import com.ruoyi.system.domain.excel.SysPostExcelBean;
import com.ruoyi.system.domain.excel.SysPostExcelBeanErrUser;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.mapper.SysPostMapper;
import com.ruoyi.system.mapper.SysUserPostMapper;
import com.ruoyi.system.service.ISysPostService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 岗位信息 服务层处理
 *
 * @author ruoyi
 */
@Service
@Slf4j
public class SysPostServiceImpl implements ISysPostService {
    @Autowired
    private SysPostMapper postMapper;
    @Autowired
    private SysUserPostMapper userPostMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;


    @Autowired
    private ISysUserService sysUserService;


    /**
     * 查询岗位信息集合
     *
     * @param post 岗位信息
     * @return 岗位信息集合
     */
    @Override
    public List<SysPost> selectPostList(SysPost post) {
        return postMapper.selectPostList(post);
    }

    /**
     * 查询所有岗位
     *
     * @return 岗位列表
     */
    @Override
    public List<SysPost> selectPostAll() {
        return postMapper.selectPostAll(null);
    }

    @Override
    public List<SysPost> selectPostByDeptId(Long deptId) {
        if (deptId == null) {
            return new ArrayList<>();
        }
        return postMapper.selectPostAll(deptId);
    }

    /**
     * 通过岗位ID查询岗位信息
     *
     * @param postId 岗位ID
     * @return 角色对象信息
     */
    @Override
    public SysPost selectPostById(Long postId) {
        return postMapper.selectPostById(postId);
    }

    /**
     * 根据用户ID获取岗位选择框列表
     *
     * @param userId 用户ID
     * @return 选中岗位ID列表
     */
    @Override
    public List<Long> selectPostListByUserId(Long userId) {
        return postMapper.selectPostListByUserId(userId);
    }

    /**
     * 根据部门ID集合查询下面的岗位列表
     *
     * @param deptIds
     * @return
     */
    @Override
    public List<SysPost> selectPostListByDeptIds(List<Long> deptIds) {
        return postMapper.selectPostListByDeptIds(deptIds);
    }

    /**
     * 校验岗位名称是否唯一
     *
     * @param post 岗位信息
     * @return 结果
     */
    @Override
    public boolean checkPostNameUnique(SysPost post) {
        Long postId = post.getPostId();
        if (postId == null) {
            return UserConstants.UNIQUE;
        }

        SysPost info = postMapper.checkPostNameUnique(post.getPostName(), post.getDeptId());
        if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验岗位编码是否唯一
     *
     * @param post 岗位信息
     * @return 结果
     @Override public boolean checkPostCodeUnique(SysPost post) {
     Long postId = StringUtils.isNull(post.getPostId()) ? -1L : post.getPostId();
     SysPost info = postMapper.checkPostCodeUnique(post.getPostCode());
     if (StringUtils.isNotNull(info) && info.getPostId().longValue() != postId.longValue()) {
     return UserConstants.NOT_UNIQUE;
     }
     return UserConstants.UNIQUE;
     }
     */

    /**
     * 通过岗位ID查询岗位使用数量
     *
     * @param postId 岗位ID
     * @return 结果
     */
    @Override
    public int countUserPostById(Long postId) {
        return userPostMapper.countUserPostById(postId);
    }

    /**
     * 删除岗位信息
     *
     * @param postId 岗位ID
     * @return 结果
     */
    @Override
    public int deletePostById(Long postId) {
        return postMapper.deletePostById(postId);
    }

    /**
     * 批量删除岗位信息
     *
     * @param postIds 需要删除的岗位ID
     * @return 结果
     */
    @Override
    public int deletePostByIds(Long[] postIds) {
        for (Long postId : postIds) {
            SysPost post = selectPostById(postId);
            if (countUserPostById(postId) > 0) {
                throw new ServiceException(String.format("%1$s已分配,不能删除", post.getPostName()));
            }
        }
        return postMapper.deletePostByIds(postIds);
    }

    /**
     * 新增保存岗位信息
     *
     * @param post 岗位信息
     * @return 结果
     */
    @Override
    public int insertPost(SysPost post) {
        Long deptId = post.getDeptId();
        Integer postLevel = post.getPostLevel();
        Integer importantType = post.getImportantType();
        if (deptId == null || postLevel == null ) {
            throw new BaseException("部门ID、岗位编码、岗位级别等必选参数为空，请检查！");
        }

        if (postLevel != SysPostEnum.DEFAULT.getValue() && postLevel != SysPostEnum.SET_MANAGER.getValue() && postLevel != SysPostEnum.SET_LEADER.getValue()) {
            throw new BaseException("无效的岗位级别，请检查！");
        }

        if (importantType != SysPostEnum.IMPORTANT_TYPE_YES.getValue() && importantType != SysPostEnum.IMPORTANT_TYPE_NO.getValue()) {
            throw new BaseException("无效的关键岗位标识，请检查！");
        }

        SysDept sysDept = sysDeptMapper.selectDeptById(deptId);
        if (sysDept == null) {
            throw new BaseException("无效的部门ID，请检查！");
        } else {
            String status = sysDept.getStatus();//部门状态（0正常 1停用）
            if (status == null || "1".equals(status)) {
                throw new BaseException("部门状态异常，请检查！");
            }
        }


        post.setPostId(Long.parseLong(IdWorker.getIdStr().substring(4)));
        post.setPostCode(post.getPostId().toString());
        return postMapper.insertPost(post);
    }

    /**
     * 修改保存岗位信息
     *
     * @param post 岗位信息
     * @return 结果
     */
    @Override
    public int updatePost(SysPost post) {

        Long deptId = post.getDeptId();
        Integer postLevel = post.getPostLevel();

        Integer importantType = post.getImportantType();

        if (deptId == null || postLevel == null || importantType == null) {
            throw new BaseException("部门ID、岗位编码、岗位级别、关键岗位等必选参数为空，请检查！");
        }

        if (postLevel != SysPostEnum.DEFAULT.getValue() && postLevel != SysPostEnum.SET_MANAGER.getValue() && postLevel != SysPostEnum.SET_LEADER.getValue()) {
            throw new BaseException("无效的岗位级别，请检查！");
        }

        if (importantType != SysPostEnum.IMPORTANT_TYPE_YES.getValue() && importantType != SysPostEnum.IMPORTANT_TYPE_NO.getValue()) {
            throw new BaseException("无效的关键岗位标识，请检查！");
        }

        SysDept sysDept = sysDeptMapper.selectDeptById(deptId);
        if (sysDept == null) {
            throw new BaseException("无效的部门ID，请检查！");
        } else {
            String status = sysDept.getStatus();//部门状态（0正常 1停用）
            if (status == null || "1".equals(status)) {
                throw new BaseException("部门状态异常，请检查！");
            }
        }

        return postMapper.updatePost(post);
    }


    /**
     * 查询部门经理级别岗位下的人员列表
     *
     * @param deptId    部门ID
     * @param postLevel 岗位级别
     * @return
     */
    @Override
    public List<UserPostAuthority> userPostAuthorityList(Long deptId, Integer postLevel) {
        return postMapper.userPostAuthorityList(deptId, postLevel);
    }

    /**
     * 当前登录用户是否为部门经理级别
     *
     * @param deptId 部门ID
     * @return
     */
    @Override
    public boolean userHaveAuthority(Long deptId) {
        Long userId = SecurityUtils.getUserId();
        // 判断岗位是否在权限范围内
        List<UserPostAuthority> userPostAuthorityList = userPostAuthorityList(deptId, SysPostEnum.SET_MANAGER.getValue());
        if (CollectionUtils.isEmpty(userPostAuthorityList)) {
            return false;
        }
        List<Long> haveAuthorityUserList = userPostAuthorityList.stream().map(t -> t.getUserId()).collect(Collectors.toList());
        if (haveAuthorityUserList.contains(userId)) {
            return true;
        }
        return false;
    }

    /**
     * 根据部门编码查询经理级别岗位下的用户列表
     *
     * @param deptCode 部门编码
     * @return
     */
    @Override
    public List<Long> userHaveAuthorityList(String deptCode) {
        // 判断岗位是否在权限范围内
        List<UserPostAuthority> userPostAuthorityList = postMapper.userHaveAuthorityList(deptCode, SysPostEnum.SET_MANAGER.getValue());
        if (CollectionUtils.isEmpty(userPostAuthorityList)) {
            return new ArrayList<>();
        }
        List<Long> userHaveAuthorityList = userPostAuthorityList.stream().map(t -> t.getUserId()).collect(Collectors.toList());
        return userHaveAuthorityList;
    }

    /**
     * 导入岗位Excel
     *
     * @param fileName 文件名，含后缀、含相对路径
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult batchImport(String fileName) throws Exception {

        if (StringUtils.isBlank(fileName)) {
            throw new BaseException("您未上传文件，请检查！");
        }
        String localPath = RuoYiConfig.getProfile();
        // 文件绝对磁盘路径（含文件名称）
        String downloadPath = localPath + fileName;
        File file = new File(downloadPath);
        InputStream inputStream = new FileInputStream(file);
        ExcelUtil excelUtil = new ExcelUtil(SysPostExcelBean.class);
        List<SysPostExcelBean> postExcelList = excelUtil.importExcel(inputStream);

        StringBuffer errorMsg = new StringBuffer();

        //1、查全部用户：用户ID、用户名、姓名、部门ID、部门名称、部门状态（启用、禁用）
        List<SysUser> sysUserList = sysUserService.postUserList(null, null, null, null, null, null, null);

        //2、查全部部门：部门ID、部门名称、部门状态（启用、禁用）
        List<SysDept> sysDeptList = sysDeptMapper.selectDeptListByCondition(new SysDept());

        //3、查全部岗位：岗位ID、岗位名、部门ID、部门名称、部门状态（启用、禁用）
        List<SysPost> sysPostList = postMapper.selectPostDeptList(new SysPost());


        //4、用 部门名称 与 Excel中信息做对比：并set 部门ID 到Excel中 -> 如果发现无法匹配的项目，返回页面提示错误信息
        // 收集停用的部门
        Map<String, List<SysDept>> sysDeptListMap = sysDeptList.stream().collect(Collectors.groupingBy(SysDept::getDeptName));
        for (int i = 0; i < postExcelList.size(); i++) {
            SysPostExcelBean postExcelBean = postExcelList.get(i);
            String deptName = postExcelBean.getDeptName();
            if (!sysDeptListMap.containsKey(deptName)) {
                errorMsg.append("第").append(i + 2).append("行").append("系统管理->部门管理：不存在【").append(deptName).append("】，");
                continue;
            }
            List<SysDept> sysDeptListForMap = sysDeptListMap.get(deptName);
            if (sysDeptListForMap.size() != 1) {
                errorMsg.append("第").append(i + 2).append("行").append("系统管理->部门管理：该部门名称重复【").append(deptName).append("】，");

            }
            SysDept sysDept = sysDeptListForMap.get(0);
            String deptStatus = sysDept.getStatus();
            //部门状态（0正常 1停用）
            if ("0".equals(deptStatus)) {
                Long deptId = sysDept.getDeptId();
                postExcelBean.setDeptId(deptId);
            } else {
                errorMsg.append("第").append(i + 2).append("行").append("系统管理->部门管理：该部门已停用【").append(deptName).append("】，");
            }
        }

        //注意：优先用 岗位持有人域账号ID 如果岗位持有人域账号ID没有值再用 姓名 + 部门名称 匹配检查
        //5、用 姓名 + 部门名称 与 Excel中信息做对比：：并set 用户ID 到Excel中 -> 如果发现无法匹配的项目，返回页面提示错误信息（提示建议在Excel中补充 岗位持有人域账号ID 再重新导入）
        List<SysPostExcelBeanErrUser> sysPostExcelBeanErrUserList = new ArrayList<>();
        for (int i = 0; i < postExcelList.size(); i++) {
            SysPostExcelBean postExcelBean = postExcelList.get(i);
            String userName = postExcelBean.getUserName();

            String nickName = postExcelBean.getNickName();
            String deptName = postExcelBean.getDeptName();
            Long userId = null;
            if (StringUtils.isNotBlank(userName)) {
                userId = getUserIdForUserName(sysUserList, userName);
            } else {
                try {
                    userId = getUserIdForNickNameAndDeptName(sysUserList, deptName, nickName);
                } catch (Exception e) {
                    //系统管理->用户管理：相同部门下发现重复的用户昵称（岗位持有人）【" + deptName + "/" + nickName + "】 "
//                    errorMsg.append("第").append(i + 2).append("行").append(e.getMessage());
                    SysPostExcelBeanErrUser sysPostExcelBeanErrUser = new SysPostExcelBeanErrUser();
                    sysPostExcelBeanErrUser.setRowNo(i + 2);
                    sysPostExcelBeanErrUser.setDeptNameExcel(deptName);
                    sysPostExcelBeanErrUser.setNickName(nickName);
                    sysPostExcelBeanErrUser.setMsg(e.getMessage());
                    sysPostExcelBeanErrUserList.add(sysPostExcelBeanErrUser);
                    continue;
                }
            }
            if (userId == null) {
//                errorMsg.append("第").append(i + 2).append("行").append("系统管理->用户管理：不存在").append("【" + deptName + "/" + nickName + "】").append("，");
                SysPostExcelBeanErrUser sysPostExcelBeanErrUser = new SysPostExcelBeanErrUser();
                sysPostExcelBeanErrUser.setRowNo(i + 2);
                sysPostExcelBeanErrUser.setDeptNameExcel(deptName);
                sysPostExcelBeanErrUser.setNickName(nickName);
                sysPostExcelBeanErrUser.setMsg("系统管理->用户管理：不存在改用户");
                sysPostExcelBeanErrUserList.add(sysPostExcelBeanErrUser);
            }
            postExcelBean.setUserId(userId);
        }


        String dataFileStr = "";
        //查询岗检系统中不存在的EHR人员是否为，岗检系统下其他部门的人员，并导出Excel：EHR上在 A 部门 岗检系统上在 B 部门
        AjaxResult excelUserAjaxResult = exportNotExistExcelUser(sysPostExcelBeanErrUserList, sysUserList, postExcelList);
        if (HttpStatus.SUCCESS != Integer.parseInt(excelUserAjaxResult.get(AjaxResult.CODE_TAG).toString())) {
            String notExistExcelUserFileName = excelUserAjaxResult.get(AjaxResult.MSG_TAG).toString();
            dataFileStr = notExistExcelUserFileName;
        }


        //TODO 甲方确认-张在奎，以EHR为准，不关心岗检系统人员是否被EHR定义
        if (false) {
            // 筛选出文件中未出现的人员信息：EHR的Excel文件未对岗检系统中的这些人员设置岗位信息（不包含禁用部门下的人员）
            AjaxResult sysUserAjaxResult = exportNotExistSysUser(sysUserList, postExcelList);
            if (HttpStatus.SUCCESS != Integer.parseInt(sysUserAjaxResult.get(AjaxResult.CODE_TAG).toString())) {
                String notExistExcelUserFileName = sysUserAjaxResult.get(AjaxResult.MSG_TAG).toString();
                if (StringUtils.isBlank(dataFileStr)) {
                    dataFileStr = notExistExcelUserFileName;
                } else {
                    dataFileStr += "," + notExistExcelUserFileName;
                }
            }
        }

        if (StringUtils.isNotBlank(dataFileStr)) {
            return AjaxResult.error("岗位导入失败，发现无法匹配的人员信息，详见反馈的Excel文件！" + errorMsg.toString(), dataFileStr);
        }

        //返回信息到前台
        if (errorMsg.length() > 0) {
            return AjaxResult.error(errorMsg.toString());
        }

        //TODO lyp测试：岗位导入时，文件校验完成后，直接返回成功暂不更新数据库
//        if (true) {
//            return AjaxResult.success("//TODO lyp测试：岗位导入时，文件校验完成后，直接返回成功暂不更新数据库");
//        }


        //6、用 部门名称 + 岗位名称 与 Excel中信息做对比：并set 岗位ID 到Excel中
        //7、得到新增岗位：Excel中 set 岗位ID后 岗位ID为空的记录，未去重，行单位是人非岗位
        List<SysPostExcelBean> addSysPostExcelBeanList = new ArrayList<>();
        for (int i = 0; i < postExcelList.size(); i++) {
            SysPostExcelBean postExcelBean = postExcelList.get(i);
            String deptName = postExcelBean.getDeptName();
            String postName = postExcelBean.getPostName();

            Long postId = getPostIdForDeptNameAndPostName(sysPostList, deptName, postName);
            if (postId == null) {
//                errorMsg.append("第").append(i + 2).append("岗位持有人").append(deptName).append("系统中不存在，");
                log.warn("【导入岗位】：第{}行岗位名称【{}】为新增项目", i + 2, deptName + "/" + postName);
                addSysPostExcelBeanList.add(postExcelBean);
            }
            postExcelBean.setPostId(postId);
        }


        //7、收集待插入数据库的新增岗位对象（去重，行单位转换为岗位）：遍历Excel新增岗位集合 set岗位ID 后复制到岗位对象
        List<SysPost> addSysPostList = getAddSysPostList(addSysPostExcelBeanList);


        //8、得到删除岗位：得到Excel中岗位ID集合，遍历数据库岗位没有在前面集合中出现的岗位都是删除数据
        List<SysPost> delSysPostList = getDelSysPostList(sysPostList, postExcelList);

        //9、插入新增岗位：set 新的 岗位ID 到Excel中
        postMapper.batchInsertPost(addSysPostList);

        //10、删除岗位
        List<Long> delSysPostIdList = delSysPostList.stream().map(SysPost::getPostId).collect(Collectors.toList());
        postMapper.deletePostByIds(delSysPostIdList.toArray(new Long[delSysPostList.size()]));


        //11、删除 岗位 与 部门 的关联关系表：更新岗位表的部门ID外键
        //新增岗位已插入
        //删除岗位已删除
        //剩余的是没有发生变化的，无需更新（保持不变，无需操作）


        //12、删除 岗位 与 人员 的关联关系表
        List<SysUserPost> userPostList = userPostMapper.selectUserPostList();
        Set<Long> userIdSet = userPostList.stream().map(SysUserPost::getUserId).collect(Collectors.toSet());
        Long[] delUserIdList = userIdSet.toArray(new Long[userIdSet.size()]);
        userPostMapper.deleteUserPost(delUserIdList);

        //13、插入 岗位 与 部门 的关联关系表
        //新增岗位时已维护好关系
        //无变化的，不需要重新维护（保持不变，无需操作）


        //14、重写，去重：插入 岗位 与 人员 的关联关系表
        Set<SysUserPost> sysUserPostSet = new HashSet<>();
        for (SysPostExcelBean postExcelBean : postExcelList) {
            Long userId = postExcelBean.getUserId();
            Long postId = postExcelBean.getPostId();
            SysUserPost sysUserPost = new SysUserPost(userId, postId);
            sysUserPostSet.add(sysUserPost);
        }

        List<SysUserPost> sysUserPostList = new ArrayList<>(sysUserPostSet);
/*
        //14、插入 岗位 与 人员 的关联关系表
        List<SysUserPost> sysUserPostList = new ArrayList<>();
        for (SysPostExcelBean postExcelBean : postExcelList) {
            Long userId = postExcelBean.getUserId();
            Long postId = postExcelBean.getPostId();
            SysUserPost sysUserPost = new SysUserPost(userId, postId);
            sysUserPostList.add(sysUserPost);
        }*/
        userPostMapper.batchUserPost(sysUserPostList);

        return AjaxResult.success("岗位信息导入成功！");
    }


    /**
     * 查询岗检系统中不存在的EHR人员是否为，岗检系统下其他部门的人员，并导出Excel：EHR上在 A 部门 岗检系统上在 B 部门
     *
     * @param sysPostExcelBeanErrUserList 岗检系统中不存在的用户（EHR导出用户）
     * @param sysUserList                 岗检用户
     * @param postExcelList               EHR用户-有用户ID的为已匹配项，反之未匹配到对应用户
     * @return 如果没有未匹配人员，返回成功，否则返回 错误人员的Excel文件，通知前端下载展示
     */
    private AjaxResult exportNotExistExcelUser(List<SysPostExcelBeanErrUser> sysPostExcelBeanErrUserList, List<SysUser> sysUserList, List<SysPostExcelBean> postExcelList) {

        //如果没有未匹配人员，返回成功
        if (CollectionUtils.isEmpty(sysPostExcelBeanErrUserList)) {
            return AjaxResult.success();
        }

        //岗检系统用户
        Map<String, List<SysUser>> sysUserListMapByNickName = sysUserList.stream().collect(Collectors.groupingBy(p -> p.getNickName()));

        //EHR已绑定的岗检系统用户ID
        List<Long> excelUserIdList = postExcelList.stream().map(SysPostExcelBean::getUserId).collect(Collectors.toList());

        for (SysPostExcelBeanErrUser excelBeanErrUser : sysPostExcelBeanErrUserList) {
            //检查岗检系统是否存在 相同 姓名 用户
            String nickName = excelBeanErrUser.getNickName();
            //存在相同 姓名 用户：可能是跨部门的
            if (sysUserListMapByNickName.containsKey(nickName)) {
                //岗检系统中 姓名 = A 的用户集合
                List<SysUser> userList = sysUserListMapByNickName.get(nickName);

                for (SysUser sysUser : userList) {
                    //未被EHR绑定过的岗检用户对象
                    if (!excelUserIdList.contains(sysUser.getUserId())) {
                        String deptName = sysUser.getDeptName();
                        String deptNameSys = excelBeanErrUser.getDeptNameSys();
                        if (StringUtils.isBlank(deptNameSys)) {
                            deptNameSys = "【" + deptName + "】";
                        } else {
                            deptNameSys += " 【" + deptName + "】";
                        }
                        excelBeanErrUser.setDeptNameSys(deptNameSys);
                    }
                }
                /*
                //岗检系统中 姓名 = A 的用户集合：按用户ID分组
                Map<Long, List<SysUser>> sysUserListMapByUserId = userList.stream().collect(Collectors.groupingBy(SysUser::getUserId));

                //收集未被绑定的岗检系统用户部门名称如下：
                for (Long userId : sysUserListMapByUserId.keySet()) {
                    if (!excelUserIdList.contains(userId)) {
                        SysUser sysUser = sysUserListMapByUserId.get(userId).get(0);
                        String deptName = sysUser.getDeptName();
                        String deptNameSys = excelBeanErrUser.getDeptNameSys();
                        if (StringUtils.isBlank(deptNameSys)) {
                            deptNameSys = "【" + deptName + "】";
                        } else {
                            deptNameSys += " 【" + deptName + "】";
                        }
                        excelBeanErrUser.setDeptNameSys(deptNameSys);
                    }
                }*/
            }
        }

        // public AjaxResult exportExcel(List<T> list, String sheetName)
        ExcelUtil excelUtil = new ExcelUtil(SysPostExcelBeanErrUser.class);
        AjaxResult exportExcel = excelUtil.exportExcel(sysPostExcelBeanErrUserList, "岗检系统中不存在的EHR人员", "岗检系统中不存在的EHR人员");
        System.out.println();
        System.out.println("查询岗检系统中不存在的EHR人员 -> " + exportExcel);
        System.out.println();


        return AjaxResult.error(exportExcel.get(AjaxResult.MSG_TAG).toString());
    }

    /**
     * 筛选出文件中未出现的人员信息：EHR的Excel文件未对岗检系统中的这些人员设置岗位信息（不包含禁用部门下的人员）
     *
     * @param sysUserList
     * @param postExcelList
     * @return
     */
    private AjaxResult exportNotExistSysUser(List<SysUser> sysUserList, List<SysPostExcelBean> postExcelList) {
        List<SysUser> notExistUserList = new ArrayList<>();
        List<Long> excelUserIdList = postExcelList.stream().map(SysPostExcelBean::getUserId).collect(Collectors.toList());
        for (SysUser sysUser : sysUserList) {
            Long userId = sysUser.getUserId();
            String deptStatus = sysUser.getDeptStatus();//部门状态（0正常 1停用）
            if (!excelUserIdList.contains(userId) && "0".equals(deptStatus)) {
                notExistUserList.add(sysUser);
            }
        }
        //导出未匹配用户为Excel文件：岗检系统中有 EHR中没有的 用户
        if (CollectionUtils.isEmpty(notExistUserList)) {
            return AjaxResult.success();//如果没有未匹配人员，返回成功
        }

        //排序：相同部门的人员放到一起
        Collections.sort(notExistUserList, new Comparator<SysUser>() {
            @Override
            public int compare(SysUser o1, SysUser o2) {
                Long deptId1 = o1.getDeptId();
                Long deptId2 = o2.getDeptId();

                long m = deptId1 - deptId2;
                if (m == 0) {
                    return 0;
                } else if (m > 0) {

                    return 1;
                } else {
                    return -1;

                }

            }
        });

        // public AjaxResult exportExcel(List<T> list, String sheetName)
        ExcelUtil excelUtilUser = new ExcelUtil(SysUser.class);
        excelUtilUser.hideColumn("delFlag", "userId", "email", "phonenumber", "sex", "status", "loginIp", "loginDate", "dept", "deptStatus", "postName", "sourceId", "casUserPback");
        AjaxResult exportExcel = excelUtilUser.exportExcel(notExistUserList, "EHR中不存在的岗检系统人员", "EHR中不存在的岗检系统人员");
        System.out.println();
        System.out.println("EHR中不存在的岗检系统人员 -> " + exportExcel);
        System.out.println();

        return AjaxResult.error(exportExcel.get(AjaxResult.MSG_TAG).toString());
    }


    /**
     * 得到待插入的岗位集合：属性复制 + 设置默认值
     *
     * @param addSysPostExcelBeanList
     * @return
     */
    private List<SysPost> getAddSysPostList(List<SysPostExcelBean> addSysPostExcelBeanList) {
        List<SysPost> addSysPostList = new ArrayList<>();

        //按 部门 + 岗位 分组
        Map<String, List<SysPostExcelBean>> sysPostListMap = addSysPostExcelBeanList.stream().collect(Collectors.groupingBy(p -> p.getDeptName() + p.getPostName()));

        for (String postFlag : sysPostListMap.keySet()) {
            //相同岗位的ID设置为同一个
            Long postId = Long.parseLong(IdWorker.getIdStr().substring(4));
            List<SysPostExcelBean> excelBeanList = sysPostListMap.get(postFlag);
            for (SysPostExcelBean postExcelBean : excelBeanList) {
                postExcelBean.setPostId(postId);
            }

            //一个岗位一行
            //将新增岗位对象保存起来
            SysPost sysPost = new SysPost();
            BeanUtils.copyProperties(excelBeanList.get(0), sysPost);
            sysPost.setPostCode("0");
            sysPost.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
            sysPost.setStatus("0");
            sysPost.setPostLevel(SysPostEnum.DEFAULT.getValue());
            sysPost.setImportantType(SysPostEnum.IMPORTANT_TYPE_NO.getValue());
            sysPost.setPostSort(0);
            addSysPostList.add(sysPost);
        }
        return addSysPostList;

        /*List<SysPost> addSysPostList = new ArrayList<>();
        for (SysPostExcelBean sysPostExcelBean : addSysPostExcelBeanList) {
            sysPostExcelBean.setPostId(Long.parseLong(IdWorker.getIdStr().substring(4)));

            SysPost sysPost = new SysPost();
            BeanUtils.copyProperties(sysPostExcelBean, sysPost);
            sysPost.setPostCode("0");
            sysPost.setCreateBy(SecurityUtils.getLoginUser().getUser().getNickName());
            sysPost.setStatus("0");
            sysPost.setPostLevel(SysPostEnum.DEFAULT.getValue());
            sysPost.setImportantType(SysPostEnum.IMPORTANT_TYPE_NO.getValue());
            sysPost.setPostSort(0);
            addSysPostList.add(sysPost);
        }
        return addSysPostList;*/
    }

    /**
     * 查询删除的岗位：得到Excel中岗位ID集合，遍历数据库岗位没有再前面集合中出现的岗位都是删除数据
     *
     * @param sysPostList   系统岗位
     * @param excelPostList Excel岗位
     * @return
     */
    private List<SysPost> getDelSysPostList(List<SysPost> sysPostList, List<SysPostExcelBean> excelPostList) {
        //待删除岗位集合
        List<SysPost> delPostListResult = new ArrayList<>();
        //Excel匹配上的岗位
        List<Long> excelPostIdList = excelPostList.stream().map(SysPostExcelBean::getPostId).collect(Collectors.toList());
        //收集未匹配的岗位
        for (SysPost sysPost : sysPostList) {
            Long postId = sysPost.getPostId();
            if (!excelPostIdList.contains(postId)) {
                delPostListResult.add(sysPost);
            }
        }
        return delPostListResult;
    }

    /**
     * 查询岗位ID：根据部门名称 + 岗位名称
     *
     * @param sysPostList
     * @param deptName    部门名称
     * @param postName    岗位名称
     * @return
     */
    private Long getPostIdForDeptNameAndPostName(List<SysPost> sysPostList, String deptName, String postName) {
        Map<String, List<SysPost>> sysPostListMap = sysPostList.stream().collect(Collectors.groupingBy(p -> p.getDeptName() + p.getPostName()));

        if (!sysPostListMap.containsKey(deptName + postName)) {
            return null;
        }

        List<SysPost> sysPostListByMap = sysPostListMap.get(deptName + postName);
        if (sysPostListByMap.size() != 1) {
            throw new BaseException("系统管理->岗位管理：相同部门下发现重复的岗位（岗位名称）【" + deptName + "/" + postName + "】 ");
        }

        return sysPostListByMap.get(0).getPostId();
    }

    /**
     * 查询用户ID：根据部门名称 + 姓名 查
     *
     * @param sysUserList
     * @param nickName
     * @param deptName
     * @return
     */
    private Long getUserIdForNickNameAndDeptName(List<SysUser> sysUserList, String deptName, String nickName) {

        Map<String, List<SysUser>> sysUserListMap = sysUserList.stream().collect(Collectors.groupingBy(p -> p.getDeptName() + p.getNickName()));

        if (!sysUserListMap.containsKey(deptName + nickName)) {
            return null;
        }
        List<SysUser> sysUserListByMap = sysUserListMap.get(deptName + nickName);
        if (sysUserListByMap.size() != 1) {
            throw new BaseException("系统管理->用户管理：相同部门下发现重复的用户姓名（对应EHR中的岗位持有人）【" + deptName + "/" + nickName + "】 ");
        }

        return sysUserListByMap.get(0).getUserId();
    }

    /**
     * 查询用户ID：根据用户名查
     *
     * @param sysUserList
     * @param userName    用户名
     * @return
     */
    private Long getUserIdForUserName(List<SysUser> sysUserList, String userName) {
        Map<String, List<SysUser>> sysUserListMap = sysUserList.stream().collect(Collectors.groupingBy(SysUser::getUserName));
        if (!sysUserListMap.containsKey(userName)) {
            return null;
        }
        List<SysUser> sysUserListByMap = sysUserListMap.get(userName);

        if (sysUserListByMap.size() != 1) {
            throw new BaseException("系统管理->用户管理：发现重复的用户（岗位持有人域账号ID）【" + userName + "】 ");
        }

        return sysUserListByMap.get(0).getUserId();
    }

    /**
     * 岗位下人员计数
     *
     * @param postId
     * @return
     */
    @Override
    public int countUserByPost(Long postId) {
        return postMapper.countUserByPost(postId);
    }

    /**
     * 查询岗位
     *
     * @param deptId
     * @param postName
     * @return
     */
    @Override
    public List<SysPost> selectByNameAndDeptId(Long deptId, String postName) {
        return postMapper.selectByNameAndDeptId( deptId, postName);
    }
}
