package com.ruoyi.postCheck.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.constant.DeptConstants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.constant.PostPlanEnum;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.postCheck.domain.PostAssessmentRating;
import com.ruoyi.postCheck.domain.PostPlan;
import com.ruoyi.postCheck.domain.PostPlanCheckUser;
import com.ruoyi.postCheck.domain.PostPlanInfo;
import com.ruoyi.postCheck.mapper.PostAssessmentRatingMapper;
import com.ruoyi.postCheck.mapper.PostPlanInfoMapper;
import com.ruoyi.postCheck.mapper.PostPlanMapper;
import com.ruoyi.postCheck.service.IPostPlanCheckUserService;
import com.ruoyi.postCheck.service.IPostPlanInfoService;
import com.ruoyi.postCheck.service.IPostPlanService;
import com.ruoyi.system.service.ISysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 岗检计划Service业务层处理
 *
 * @author csg
 * @date 2023-12-19
 */
@Service
public class PostPlanServiceImpl extends ServiceImpl<PostPlanMapper, PostPlan> implements IPostPlanService {
    @Autowired
    private PostPlanMapper postPlanMapper;

    @Autowired
    private IPostPlanInfoService postPlanInfoService;

    @Autowired
    private PostAssessmentRatingMapper postAssessmentRatingMapper;


    @Autowired
    private PostPlanInfoMapper postPlanInfoMapper;
    @Autowired
    private IPostPlanCheckUserService postPlanCheckUserService;

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 查询岗检计划
     *
     * @param id 岗检计划主键
     * @return 岗检计划
     */
    @Override
    public PostPlan selectPostPlanById(Long id) {
        PostPlan postPlanParm = new PostPlan();
        postPlanParm.setId(id);
        List<PostPlan> dataList = selectPostPlanListV2(postPlanParm);
        if (CollectionUtils.isEmpty(dataList)) {
            return postPlanParm;
        }
        return dataList.get(0);
        /*
        PostPlan data = postPlanMapper.selectPostPlanById(id);
        if (data != null) {
            Long dataId = data.getId();
            PostPlanInfo info = new PostPlanInfo();
            info.setPostPlanId(dataId);
            List<PostPlanInfo> infoList = postPlanInfoService.selectPostPlanInfoList(info);
            data.setChildren(infoList);

            //设置检查人员集合
            List<Long> planIdList = new ArrayList<>();
            planIdList.add(data.getId());
//        LambdaQueryWrapper<PostPlanCheckUser> wrapper = new LambdaQueryWrapper<>();
//        wrapper.in(PostPlanCheckUser::getPostPlanId, planIdList);
//        List<PostPlanCheckUser> userList = postPlanCheckUserService.list(wrapper);

            PostPlanCheckUser param = new PostPlanCheckUser();
            param.setPostPlanIdList(planIdList);
            List<PostPlanCheckUser> userList = postPlanCheckUserService.selectPostPlanInfoUserList(param);


            Map<Long, List<PostPlanCheckUser>> userListMap = userList.stream().collect(Collectors.groupingBy(PostPlanCheckUser::getPostPlanId));
//            for (PostPlan data : list) {
            Long planId = data.getId();
            if (userListMap.containsKey(planId)) {
                data.setCheckUserChildren(userListMap.get(planId));
            }
//            }

        }
        return data;
        */
    }

    /**
     * 查询岗检计划列表
     *
     * @param postPlan 岗检计划
     * @return 岗检计划
     */
    @Override
    public List<PostPlan> selectPostPlanList(PostPlan postPlan) {
        List<PostPlan> list = postPlanMapper.selectPostPlanList(postPlan);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<Long> planIdList = list.stream().map(PostPlan::getId).collect(Collectors.toList());
//        LambdaQueryWrapper<PostPlanCheckUser> wrapper = new LambdaQueryWrapper<>();
//        wrapper.in(PostPlanCheckUser::getPostPlanId, planIdList);
//        List<PostPlanCheckUser> userList = postPlanCheckUserService.list(wrapper);

        PostPlanCheckUser param = new PostPlanCheckUser();
        param.setPostPlanIdList(planIdList);
        List<PostPlanCheckUser> userList = postPlanCheckUserService.selectPostPlanInfoUserList(param);


        Map<Long, List<PostPlanCheckUser>> userListMap = userList.stream().collect(Collectors.groupingBy(PostPlanCheckUser::getPostPlanId));
        for (PostPlan data : list) {
            Long planId = data.getId();
            if (userListMap.containsKey(planId)) {
                data.setCheckUserChildren(userListMap.get(planId));
            }
        }

        //查询计划明细：部门、岗位、开始时间结束时间
        PostPlanInfo postPlanInfo = new PostPlanInfo();
        postPlanInfo.setPostPlanIdList(planIdList);
        List<PostPlanInfo> postPlanInfoList = postPlanInfoService.selectPostPlanInfoList(postPlanInfo);

        Map<Long, List<PostPlanInfo>> palnInfotMap = postPlanInfoList.stream().collect(Collectors.groupingBy(PostPlanInfo::getPostPlanId));
        for (PostPlan data : list) {
            Long planId = data.getId();
            if (palnInfotMap.containsKey(planId)) {
                data.setChildren(palnInfotMap.get(planId));
            }
        }

        return list;
    }

    @Override
    public List<PostPlan> selectPostPlanListV2(PostPlan postPlan) {
        List<PostPlan> resultList = new ArrayList<>();

        List<PostPlan> dataList = selectPostPlanList(postPlan);

        for (PostPlan data : dataList) {

            List<PostPlanInfo> children = data.getChildren();
            //按部门分组，得到岗位List
            Map<Long, List<PostPlanInfo>> deptMap = children.stream().collect(Collectors.groupingBy(PostPlanInfo::getCheckedDeptId));

            for (Long deptId : deptMap.keySet()) {
                List<PostPlan.PostInfoSendMail> postInfoSendMailList = new ArrayList<>();

                String checkedDeptName = "";
                String checkedPostNames = "";
                String checkedTimeView = "";//计划明细中的检查时间

                List<PostPlanInfo> postPlanInfoList = deptMap.get(deptId);
                // for (PostPlanInfo postPlanInfo : deptMap.get(deptId)) {
                for (int i = 0; i < postPlanInfoList.size(); i++) {

                    PostPlanInfo postPlanInfo = postPlanInfoList.get(i);

                    checkedDeptName = postPlanInfo.getCheckedDeptName();//根据部门ID分组的每个都一样
                    if (i == postPlanInfoList.size() - 1) {
                        if (postPlanInfo.getCheckedPostName() != null)
                            checkedPostNames += postPlanInfo.getCheckedPostName();//拼接被检查岗位
                    } else {
                        if (postPlanInfo.getCheckedPostName() != null)
                            checkedPostNames += postPlanInfo.getCheckedPostName() + "，";//拼接被检查岗位
                    }
                    checkedTimeView = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, postPlanInfo.getStartTime()) + " 至 " + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, postPlanInfo.getEndTime());

                    PostPlan.PostInfoSendMail postInfoSendMail = new PostPlan.PostInfoSendMail();
                    postInfoSendMail.setDeptId(postPlanInfo.getCheckedDeptId());
                    postInfoSendMail.setDeptName(postPlanInfo.getCheckedDeptName());
                    postInfoSendMail.setPostid(postPlanInfo.getCheckedPostId());
                    postInfoSendMail.setPostName(postPlanInfo.getCheckedPostName());
                    postInfoSendMailList.add(postInfoSendMail);
                }


                PostPlan result = new PostPlan();
                BeanUtils.copyBeanProp(result, data);

                result.setCheckedDeptName(null);
                result.setCheckedPostNames(null);
                result.setCheckedTimeView(null);

                result.setCheckedDeptName(checkedDeptName);
//                result.setCheckedPostNames(checkedPostNames.length() > 0 ? checkedPostNames.substring(0, checkedPostNames.length() - 1) : checkedPostNames);
                result.setCheckedPostNames(checkedPostNames);
                result.setCheckedTimeView(checkedTimeView);
                result.getPostInfoSendMailList().addAll(postInfoSendMailList);
                resultList.add(result);
            }
        }
        return resultList;
    }

    /**
     * 新增岗检计划
     *
     * @param postPlan 岗检计划
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertPostPlan(PostPlan postPlan) {
        postPlan.setId(Long.parseLong(IdWorker.getIdStr().substring(4)));
        postPlan.setCreateDefault();
        postPlan.setCreateUserId(SecurityUtils.getUserId());
        postPlan.setStatus(PostPlanEnum.STATUS_WAIT.getValue());//待审核
        postPlan.setPublish(0);
        int rows = postPlanMapper.insertPostPlan(postPlan);
        if (rows > 0) {
            //添加检查人员
            List<PostPlanCheckUser> checkUserChildren = postPlan.getCheckUserChildren();
            if (CollectionUtils.isEmpty(checkUserChildren)) {
                throw new BaseException("检查人员未空，请检查！");
            }
            int index = 0;
            for (PostPlanCheckUser checkUserChild : checkUserChildren) {
                checkUserChild.setId(Long.parseLong(IdWorker.getIdStr().substring(4)));
                checkUserChild.setPostPlanId(postPlan.getId());
                checkUserChild.setCreateDefault();
                //检查人员ID：1-组长；2-组员；
                if (index++ == 0) {
                    checkUserChild.setType(1);
                } else {
                    checkUserChild.setType(2);
                }

                SysUser sysUser = sysUserService.selectUserById(checkUserChild.getCheckedUserId());
                String nickName = sysUser.getNickName();
                checkUserChild.setCheckedUserName(nickName);
            }
            postPlanCheckUserService.saveBatch(checkUserChildren);


            List<PostPlanInfo> children = postPlan.getChildren();


            if (CollectionUtils.isEmpty(children)) {
                throw new BaseException("请选择涉及部门及岗位，请检查！");
            }

            for (PostPlanInfo child : children) {
                child.setPostPlanId(postPlan.getId());
                postPlanInfoService.insertPostPlanInfo(child);
            }
        }

        return rows;
    }

    /**
     * 修改岗检计划
     *
     * @param postPlan 岗检计划
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updatePostPlan(PostPlan postPlan) {
        postPlan.setUpdateDefault();
        postPlan.setPublish(0);
        int rows = postPlanMapper.updatePostPlan(postPlan);

        if (rows > 0) {
            //删除检查人员
            LambdaUpdateWrapper<PostPlanCheckUser> updateWrapperCheckUser = new LambdaUpdateWrapper<>();
            updateWrapperCheckUser.eq(PostPlanCheckUser::getPostPlanId, postPlan.getId());
            postPlanCheckUserService.remove(updateWrapperCheckUser);

            //新增检查人员
            List<PostPlanCheckUser> checkUserChildren = postPlan.getCheckUserChildren();
            if (CollectionUtils.isEmpty(checkUserChildren)) {
                throw new BaseException("检查人员未空，请检查！");
            }

            int index = 0;
            for (PostPlanCheckUser checkUserChild : checkUserChildren) {
                checkUserChild.setId(Long.parseLong(IdWorker.getIdStr().substring(4)));
                checkUserChild.setPostPlanId(postPlan.getId());
                checkUserChild.setCreateDefault();
                //检查人员ID：1-组长；2-组员；
                if (index++ == 0) {
                    checkUserChild.setType(1);
                } else {
                    checkUserChild.setType(2);
                }

                SysUser sysUser = sysUserService.selectUserById(checkUserChild.getCheckedUserId());
                String nickName = sysUser.getNickName();
                checkUserChild.setCheckedUserName(nickName);
            }
            postPlanCheckUserService.saveBatch(checkUserChildren);


            //删除明细
            LambdaUpdateWrapper<PostPlanInfo> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(PostPlanInfo::getPostPlanId, postPlan.getId());
            postPlanInfoMapper.delete(updateWrapper);

            //新增明细
            List<PostPlanInfo> children = postPlan.getChildren();
            if (!CollectionUtils.isEmpty(children)) {
                for (PostPlanInfo child : children) {
                    child.setPostPlanId(postPlan.getId());
                    postPlanInfoService.insertPostPlanInfo(child);
                }
            }
        }

        return rows;
    }

    /**
     * 批量删除岗检计划
     *
     * @param ids 需要删除的岗检计划主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deletePostPlanByIds(Long[] ids) {

        List<PostPlan> planList = postPlanMapper.selectBatchIds(Arrays.asList(ids));
        if (ids.length <= 0 || planList.size() != ids.length) {
            throw new BaseException("前后端记录数量匹配不一致，请刷新页面再试！");
        }

        for (PostPlan postPlan : planList) {
            Integer status = postPlan.getStatus();
            if (status == PostPlanEnum.STATUS_PASS.getValue()) {
                throw new BaseException("已审核通过的记录不允许删除，请刷新页面再试！");
            }
        }

        return postPlanMapper.deletePostPlanByIds(ids);
    }

    /**
     * 删除岗检计划信息
     *
     * @param id 岗检计划主键
     * @return 结果
     @Override public int deletePostPlanById(Long id) {
     return postPlanMapper.deletePostPlanById(id);
     }
     */

    /**
     * 审核1：岗检方案审核-Icfa
     *
     * @param id         主键ID
     * @param statusIcfa 2-内控法务部审批-状态：1-待审核；3-通过；4-驳回；
     * @param reasonIcfa 2-内控法务部审批-未通过理由
     * @return
     */
    @Override
    public int approveIcfa(Long id, Integer statusIcfa, String reasonIcfa) {

        if (id == null || statusIcfa == null) {
            return 0;
        }

        //状态错误
        if (statusIcfa != PostPlanEnum.STATUS_ICFA_PASS.getValue() && statusIcfa != PostPlanEnum.STATUS_ICFA_BACK.getValue()) {
            return 0;
        }

        //未写理由
        if (statusIcfa == PostPlanEnum.STATUS_ICFA_BACK.getValue() && StringUtils.isBlank(reasonIcfa)) {
            return 0;
        }

        // 判断当前状态
        PostPlan postPlan = selectPostPlanById(id);
        //审核
        if (statusIcfa == PostPlanEnum.STATUS_ICFA_PASS.getValue()) {
            // 审核过得不在审核
            if (postPlan.getStatusIcfa() == PostPlanEnum.STATUS_ICFA_PASS.getValue()) {
                throw new BaseException("已审核通过的记录不允许重复操作，请刷新页面再试！");
            }
        }
        //驳回
        else if (statusIcfa == PostPlanEnum.STATUS_ICFA_BACK.getValue()) {
            // 审核过得不在审核
            if (postPlan.getStatusIcfa() == PostPlanEnum.STATUS_ICFA_PASS.getValue()) {
                throw new BaseException("已审核通过的记录不允许驳回操作，请刷新页面再试！");
            }
        }

        PostPlan data = new PostPlan();
        data.setId(id);
        data.setStatusIcfa(statusIcfa);
        data.setReasonIcfa(reasonIcfa);

        if (statusIcfa == PostPlanEnum.STATUS_ICFA_PASS.getValue()) {
            data.setStep(PostPlanEnum.STEP.getValue());
            data.setStatus(PostPlanEnum.STATUS_ING.getValue());//审核中
        } else {
            data.setStatus(PostPlanEnum.STATUS_BACK.getValue());//驳回
        }
        return postPlanMapper.updatePostPlan(data);
    }

    /**
     * 审核2：岗检方案审核-HR
     *
     * @param id       主键ID
     * @param statusHr 1-人力资源审批-状态：1-待审核；3-通过；4-驳回；
     * @param reasonHr 1-人力资源审批-未通过理由
     * @return
     */
    @Override
    public int approveHr(Long id, Integer statusHr, String reasonHr) {
        if (id == null || statusHr == null) {
            return 0;
        }

        //状态错误
        if (statusHr != PostPlanEnum.STATUS_HR_PASS.getValue() && statusHr != PostPlanEnum.STATUS_HR_BACK.getValue()) {
            return 0;
        }

        //未写理由
        if (statusHr == PostPlanEnum.STATUS_HR_BACK.getValue() && StringUtils.isBlank(reasonHr)) {
            return 0;
        }


        // 判断当前状态
        PostPlan postPlan = selectPostPlanById(id);
        // 判断顺序
        if (postPlan.getStatusIcfa() != PostPlanEnum.STATUS_ICFA_PASS.getValue()
                && postPlan.getStatus() != PostPlanEnum.STATUS_ING.getValue()) {
            throw new BaseException("内控法务部还未审核，请刷新页面再试！");
        }

        //审核
        if (statusHr == PostPlanEnum.STATUS_HR_PASS.getValue()) {
            if (postPlan.getStatusHr() == PostPlanEnum.STATUS_HR_PASS.getValue()) {
                throw new BaseException("已审核通过的记录不允许重复操作，请刷新页面再试！");
            }
        }
        //驳回
        else if (statusHr == PostPlanEnum.STATUS_HR_BACK.getValue()) {
            if (postPlan.getStatusHr() == PostPlanEnum.STATUS_HR_PASS.getValue()) {
                throw new BaseException("已审核通过的记录不允许驳回操作，请刷新页面再试！");
            }
        }


        PostPlan data = new PostPlan();
        data.setId(id);
        data.setStatusHr(statusHr);
        data.setReasonHr(reasonHr);

        data.setStatus(statusHr);//最终审核结果

        if (statusHr == PostPlanEnum.STATUS_ICFA_PASS.getValue()) {
            data.setStep(PostPlanEnum.STEP_UP.getValue());
            // 如果审核通过开始初始化评比排名表
            initializationPostAssessmentRating(id);

        }
        return postPlanMapper.updatePostPlan(data);
    }

    /**
     * 岗检计划发布
     *
     * @param id
     * @return
     */
    @Override
    public int publish(Long id) {
        PostPlan postPlan = postPlanMapper.selectPostPlanById(id);
        Integer status = postPlan.getStatus();
        if (status == null || status != PostPlanEnum.STATUS_PASS.getValue()) {
            throw new BaseException("未审核，不可发布，请检查！");
        }
        //TODO 待开发：1、计划表 + 岗检表 发送到检查人邮箱
        // 查询计划表
        // 生成岗检表Excel
        // 查询收件人邮箱列表
        // 发送邮件：带附件


        //2、修改数据库的状态：记录发布次数
        PostPlan data = new PostPlan();
        data.setId(id);
        data.setPublish(postPlan.getPublish() != null ? (postPlan.getPublish() + 1) : 1);
        return postPlanMapper.updatePostPlan(data);
    }

    public void initializationPostAssessmentRating(Long id) {
        // 查询被检查部门
        List<PostPlanInfo> postPlanInfoList = postPlanInfoMapper.selectList(Wrappers.<PostPlanInfo>lambdaQuery().eq(PostPlanInfo::getPostPlanId, id));
        if (!postPlanInfoList.isEmpty()) {
            //受检部门分组
            Map<Long, List<PostPlanInfo>> checkedDeptMap = postPlanInfoList.stream().collect(Collectors.groupingBy(PostPlanInfo::getCheckedDeptId));
            for (Map.Entry<Long, List<PostPlanInfo>> longListEntry : checkedDeptMap.entrySet()) {
                Long key = longListEntry.getKey();//被检查部门ID
                List<PostPlanInfo> value = longListEntry.getValue();
                PostPlanInfo postPlanInfo = value.get(0);
                Date startTime = postPlanInfo.getStartTime();
                Date endTime = postPlanInfo.getEndTime();

                PostAssessmentRating rating = new PostAssessmentRating();
                rating.setId(Long.parseLong(IdWorker.getIdStr().substring(4)));
                String sysDeptName = postAssessmentRatingMapper.getSysDeptName(key);
                if (DeptConstants.FunctionalDepartment.contains(sysDeptName)) {
                    // 在这是职能部门
                    rating.setType(1);
                } else {
                    // 生产部门
                    rating.setType(2);
                }
                rating.setDeptId(key);
                rating.setPlanId(id);
//                rating.setPlanStartTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, startTime));
//                rating.setPlanEndTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, endTime));

                rating.setPeerEvaluationScore(new BigDecimal("100"));
                rating.setPositionScore(new BigDecimal("100"));
                rating.setDepartmentScore(new BigDecimal("100"));
                rating.setCreateDefault();
                postAssessmentRatingMapper.insert(rating);
            }
        }
    }


}
