package com.ruoyi.postCheck.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.PostCheckedEnum;
import com.ruoyi.common.constant.PostListEnum;
import com.ruoyi.common.constant.PostPlanEnum;
import com.ruoyi.common.constant.PostProgrammeEnum;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.postCheck.domain.*;
import com.ruoyi.postCheck.mapper.PostCheckedMapper;
import com.ruoyi.postCheck.service.IPostCheckedItemsService;
import com.ruoyi.postCheck.service.IPostCheckedService;
import com.ruoyi.postCheck.service.IPostListService;
import com.ruoyi.postCheck.util.excel.ExcelParsePostCheck;
import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
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.util.*;
import java.util.stream.Collectors;

/**
 * 岗检表管理Service业务层处理
 *
 * @author csg
 * @date 2024-01-05
 */
@Service
@Slf4j
public class PostCheckedServiceImpl extends ServiceImpl<PostCheckedMapper, PostChecked> implements IPostCheckedService {
    @Autowired
    private PostCheckedMapper postCheckedMapper;
    @Autowired
    private IPostCheckedItemsService postCheckedItemsService;
    @Autowired
    private ISysDeptService sysDeptService;
    @Autowired
    private ISysPostService sysPostService;
    @Autowired
    private IPostListService postListService;
//    @Autowired
//    private IPostListInfoService postListInfoService;


    /**
     * 查询岗检表管理
     *
     * @param id 岗检表管理主键
     * @return 岗检表管理
     */
    @Override
    public PostChecked selectPostCheckedById(Long id) {
        PostChecked data = postCheckedMapper.selectPostCheckedById(id);
        if (data != null) {
//            Long id = data.getId();
//            if (id != null) {

            PostCheckedItems param = new PostCheckedItems();
            param.setPostCheckedId(id);
            List<PostCheckedItems> children = postCheckedItemsService.selectPostCheckedItemsList(param);
            data.setChildren(children);
//            }
        }
        return data;
    }

    /**
     * 查询岗检表管理列表
     *
     * @param postChecked 岗检表管理
     * @return 岗检表管理
     */
    @Override
    public List<PostChecked> selectPostCheckedList(PostChecked postChecked) {

        //清单编制菜单查询时提交的是待审核，后台转化状态为：待提交、待审核、审核中、驳回
//        Integer status = postChecked.getStatus();

//        if (status != null && status == PostCheckedEnum.STATUS_WAIT.getValue()) {
//            postChecked.setStatus(null);
//            List<Integer> statusList = new ArrayList<>(4);
//            statusList.add(PostListEnum.STATUS_WAIT_SUBMIT.getValue());
//            statusList.add(PostListEnum.STATUS_WAIT.getValue());
//            statusList.add(PostListEnum.STATUS_ING.getValue());
//            statusList.add(PostListEnum.STATUS_BACK.getValue());
//            postList.setStatusList(statusList);
//        }



        List<PostChecked> dataList = postCheckedMapper.selectPostCheckedList(postChecked);
        if (!CollectionUtils.isEmpty(dataList)) {
            for (PostChecked data : dataList) {
                Long id = data.getId();
                if (id != null) {
                    PostCheckedItems param = new PostCheckedItems();
                    param.setPostCheckedId(id);
                    List<PostCheckedItems> children = postCheckedItemsService.selectPostCheckedItemsList(param);
                    data.setChildren(children);
                }
            }
        }
        return dataList;
    }

    /**
     * 新增岗检表管理
     *
     * @param postChecked 岗检表管理
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertPostChecked(PostChecked postChecked) {

        List<PostCheckedItems> children = postChecked.getChildren();
        if (CollectionUtils.isEmpty(children)) {
            log.error("【岗检表】-add：未设置检查内容，请在页面选择需要检查的项目，再提交！");
            throw new BaseException("未设置检查内容，请在页面选择需要检查的项目，再提交！");
        }

        postChecked.setId(Long.parseLong(IdWorker.getIdStr().substring(4)));
        postChecked.setPostCode("GJ-" + DateUtils.dateTimeNow());

        postChecked.setCreateDefault();
//        postChecked.setStatus(PostCheckedEnum.STATUS_WAIT.getValue()); // 去创建自己的枚举类

        //制单人ID如果已经有值，不能覆盖：全要素检查表自动生成时沿用清单制单人的ID
        Long createUserId = postChecked.getCreateUserId();
        if (createUserId == null) {
            postChecked.setCreateUserId(SecurityUtils.getUserId());
        }

        SysDept sysDept = sysDeptService.selectDeptById(postChecked.getCheckedDeptId());
        SysPost sysPost = sysPostService.selectPostById(postChecked.getCheckedPostId());
        postChecked.setCheckedDeptType(sysDept.getType());//部门类型
        postChecked.setCheckedDeptName(sysDept.getDeptName());//部门名称
        postChecked.setCheckedPostName(sysPost.getPostName());//岗位名称

        postChecked.setStatus(PostCheckedEnum.STATUS_WAIT_SUBMIT.getValue());
        postChecked.setStatusByUserId(null);
        postChecked.setStatusByUserName(null);
        postChecked.setReason(null);
        postChecked.setStatusApproveTime(null);


        int row = postCheckedMapper.insertPostChecked(postChecked);
        if (row > 0) {
            for (PostCheckedItems child : children) {
                child.setId(Long.parseLong(IdWorker.getIdStr().substring(4)));
                child.setPostCheckedId(postChecked.getId());
                child.setCreateDefault();
                Long childrenTypeId = child.getChildrenTypeId();
                if (childrenTypeId == null) {
                    log.error("【岗检表】-新增：新增明细时参数缺少：childrenTypeId : {}", childrenTypeId);
                }
            }

            postCheckedItemsService.saveBatch(children);
        }
        return row;
    }

    /**
     * 修改岗检表管理
     *
     * @param postChecked 岗检表管理
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updatePostChecked(PostChecked postChecked) {
        Long id = postChecked.getId();

        if (id == null) {
            log.error("【岗检表】-edit：未设置id，请联系管理员！");
            throw new BaseException("未设置id，请联系管理员！");
        }

        List<PostCheckedItems> children = postChecked.getChildren();
        if (CollectionUtils.isEmpty(children) || id == null) {
            log.error("【岗检表】-edit：未设置检查内容，请在页面选择需要检查的项目，再提交！");
            throw new BaseException("未设置检查内容，请在页面选择需要检查的项目，再提交！");
        }
        PostChecked postCheckedDB = postCheckedMapper.selectPostCheckedById(id);
        if (postCheckedDB == null) {
            throw new BaseException("id错误，请刷新页面！");
        }

        Integer statusDB = postCheckedDB.getStatus();
        if (statusDB != null && statusDB == PostCheckedEnum.STATUS_PASS.getValue()) {
            throw new BaseException("已审核，不可以修改，请刷新页面！");
        }

        postChecked.setStatus(PostCheckedEnum.STATUS_WAIT_SUBMIT.getValue());
        postChecked.setStatusByUserId(null);
        postChecked.setStatusByUserName(null);
        postChecked.setReason(null);
        postChecked.setStatusApproveTime(null);

        postChecked.setUpdateDefault();


        SysDept sysDept = sysDeptService.selectDeptById(postChecked.getCheckedDeptId());
        SysPost sysPost = sysPostService.selectPostById(postChecked.getCheckedPostId());
        postChecked.setCheckedDeptType(sysDept.getType());//部门类型
        postChecked.setCheckedDeptName(sysDept.getDeptName());//部门名称
        postChecked.setCheckedPostName(sysPost.getPostName());//岗位名称
        int row = postCheckedMapper.updatePostChecked(postChecked);
        if (row > 0) {
            //删除明细
            LambdaUpdateWrapper<PostCheckedItems> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(PostCheckedItems::getPostCheckedId, id);
            postCheckedItemsService.remove(updateWrapper);

            //插入明细
            for (PostCheckedItems child : children) {
                child.setId(Long.parseLong(IdWorker.getIdStr().substring(4)));
                child.setPostCheckedId(postChecked.getId());
                child.setCreateDefault();
                Long childrenTypeId = child.getChildrenTypeId();
                log.error("【岗检表】-新增：新增明细时参数缺少：childrenTypeId : {}", childrenTypeId);
            }
            postCheckedItemsService.saveBatch(children);
        }

        return row;
    }

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


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

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


        int row = postCheckedMapper.deletePostCheckedByIds(ids);

        //删除明细
        LambdaUpdateWrapper<PostCheckedItems> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(PostCheckedItems::getPostCheckedId, ids);
        postCheckedItemsService.remove(updateWrapper);

        return row;
    }

    /**
     * 删除岗检表管理信息
     *
     * @param id 岗检表管理主键
     * @return 结果
    @Override
    public int deletePostCheckedById(Long id) {
        int row = postCheckedMapper.deletePostCheckedById(id);
        //删除明细
        LambdaUpdateWrapper<PostCheckedItems> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(PostCheckedItems::getPostCheckedId, id);
        postCheckedItemsService.remove(updateWrapper);
        return row;
    }
     */


    /**
     * 岗检表提交审核
     *
     * @param id
     * @return
     */
    @Override
    public int submitApprove(Long id) {
        if (id == null) {
            throw new BaseException("参数不全，请检查！");
        }
        PostChecked data = postCheckedMapper.selectById(id);

        if (data == null) {
            throw new BaseException("记录不存在，请刷新页面，再试！");
        }
        Integer status = data.getStatus();
        if (status != PostCheckedEnum.STATUS_WAIT_SUBMIT.getValue()) {
            throw new BaseException("非法操作，请检查当前的状态，仅待提交时才可操作，请检查！");
        }
        data.setStatus(PostCheckedEnum.STATUS_WAIT.getValue());
        int updateByIdCount = 0;
        try {
            updateByIdCount = postCheckedMapper.updateById(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return updateByIdCount;
    }

    /**
     * 岗检表审核
     *
     * @param id     主键
     * @param status 状态：3-通过；4-驳回；
     * @param reason 未通过理由
     * @return
     */
    @Override
    public int statusApprove(Long id, Integer status, String reason) {
        if (id == null || status == null) {
            throw new BaseException("参数不全，请检查！");
        }

        //状态错误
        if (status != PostCheckedEnum.STATUS_PASS.getValue() && status != PostCheckedEnum.STATUS_BACK.getValue()) {
            throw new BaseException("状态错误，请检查！");
        }

        //驳回时必须填写原因
        if (status == PostCheckedEnum.STATUS_BACK.getValue() && StringUtils.isBlank(reason)) {
            throw new BaseException("请填写未通过理由！");
        }


        PostChecked postChecked = postCheckedMapper.selectById(id);
        if (postChecked == null) {
            throw new BaseException("记录不存在，请刷新页面重新查询，请检查！");
        }
        Integer statusDB = postChecked.getStatus();

        //审核
        if (status == PostCheckedEnum.STATUS_PASS.getValue()) {

            if (statusDB == PostCheckedEnum.STATUS_PASS.getValue()) {
                throw new BaseException("已审核通过的记录不允许重复操作，请刷新页面再试！");
            }

        }
        //驳回
        else if (status == PostCheckedEnum.STATUS_BACK.getValue()) {

            if (statusDB == PostCheckedEnum.STATUS_PASS.getValue()) {
                throw new BaseException("已审核通过的记录不允许驳回操作，请刷新页面再试！");
            }

        }


        Long deptId = postChecked.getCheckedDeptId();
        Long postId = postChecked.getCheckedPostId();
        if (deptId == null || postId == null) {
            throw new BaseException("单据的部门ID和岗位ID为空，请检查！");
        }

        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();
        PostChecked data = new PostChecked();
        data.setId(id);
        data.setStatus(status);
        data.setStatusByUserId(sysUser.getUserId());
        data.setStatusByUserName(sysUser.getNickName());
        data.setStatusApproveTime(new Date());
        //审核通过时清空不通过理由
        if (status == PostCheckedEnum.STATUS_PASS.getValue()) {
            reason = "--";
            String versionNoMax = getVersionNoMax(deptId, postId);
            data.setVersionNo(versionNoMax);
        }
        data.setReason(reason);
        return postCheckedMapper.updatePostChecked(data);
    }


    /**
     * 查询当前可用的版本号
     *
     * @param deptId
     * @param postId
     * @return
     */
    private String getVersionNoMax(Long deptId, Long postId) {
        LambdaQueryWrapper<PostChecked> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PostChecked::getCheckedDeptId, deptId);
        queryWrapper.eq(PostChecked::getCheckedPostId, postId);
        queryWrapper.eq(PostChecked::getStatus, PostCheckedEnum.STATUS_PASS.getValue());
        List<PostChecked> postCheckedList = postCheckedMapper.selectList(queryWrapper);
        Set<Integer> versionNoSet = new TreeSet<>();
        versionNoSet.add(0);
        if (!CollectionUtils.isEmpty(postCheckedList)) {
            List<String> versionList = postCheckedList.stream().map(PostChecked::getVersionNo).collect(Collectors.toList());
            for (String versionNoDB : versionList) {
                if (com.ruoyi.common.utils.StringUtils.isNotBlank(versionNoDB)) {
                    String[] versionNoArr = versionNoDB.split("-");
                    versionNoSet.add(versionNoArr.length == 2 ? Integer.parseInt(versionNoArr[1]) : 0);
                }
            }
        }
        Integer versionNoMax = Collections.max(versionNoSet);
        String versionNo = DateUtils.dateTimeNow(DateUtils.YYYY) + ++versionNoMax;
        return versionNo;
    }

    /**
     * 批量导入检查表Excel表格
     *
     * @param fileNameList 数组：前端上传文件接口返回的相对路径（含文件名称）
     */
    /*
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchImport(String[] fileNameList) throws Exception {
        //文件上传接口返回信息
//        {
//            "msg": "操作成功",
//                "fileName": "/upload/2024/01/29/gh_reserve_and_info_template(1)_20240129224542A003.xls",
//                "code": 200,
//                "newFileName": "gh_reserve_and_info_template(1)_20240129224542A003.xls",
//                "url": "http://39.106.66.72:8080/upload/2024/01/29/gh_reserve_and_info_template(1)_20240129224542A003.xls",
//                "originalFilename": "gh_reserve_and_info_template(1).xls"
//        }
        if (ArrayUtils.isEmpty(fileNameList)) {
            throw new BaseException("文件为空，请检查！");
        }

        //遍历解析文件并入库
        String localPath = RuoYiConfig.getProfile();
        for (int i = 0; i < fileNameList.length; i++) {
            //前端上传传的文件相对路径（含文件名称）
            String resource = fileNameList[i];
            // 文件绝对磁盘路径（含文件名称）
            String downloadPath = localPath + resource;
            // 文件名称
            String downloadName = com.ruoyi.common.utils.StringUtils.substringAfterLast(downloadPath, "/");
            ExcelParsePostCheck excelParsePostCheck = new ExcelParsePostCheck();
//            PostChecked postChecked = excelParsePostCheck.parseFile("C:\\test\\postcheck\\2、岗位责任制检查表（模板）1225-方联殷V2.xlsx", downloadName);
            PostChecked postChecked = excelParsePostCheck.parseFile(downloadPath, downloadName);

            //匹配数据：部门 + 岗位
            String checkedDeptName = postChecked.getCheckedDeptName();
            String checkedPostName = postChecked.getCheckedPostName();
            SysDept deptParam = new SysDept();
            deptParam.setDeptName(checkedDeptName);
            List<SysDept> deptList = sysDeptService.selectDeptListByCondition(deptParam);
            if (CollectionUtils.isEmpty(deptList)) {
                throw new BaseException(downloadName + "文件中部门名称【" + checkedDeptName + "】不存在，请检查！");
            } else if (deptList.size() != 1) {
                throw new BaseException(downloadName + "文件中部门名称【" + checkedDeptName + "】不唯一查到" + deptList.size() + "个，请检查！");
            }
            SysPost postParam = new SysPost();
            postParam.setDeptId(deptList.get(0).getDeptId());//部门ID
            postParam.setPostName(checkedPostName);//岗位名称
            List<SysPost> postList = sysPostService.selectPostList(postParam);
            if (CollectionUtils.isEmpty(postList)) {
                throw new BaseException(downloadName + "文件中在对应部门下（" + checkedDeptName + "）岗位名称【" + checkedPostName + "】不存在，请检查！");
            } else if (postList.size() != 1) {
                throw new BaseException(downloadName + "文件中在对应部门下（" + checkedDeptName + "）岗位名称【" + checkedPostName + "】不唯一查到" + postList.size() + "个，请检查！");
            }

            postChecked.setCheckedDeptId(deptList.get(0).getDeptId());
            postChecked.setCheckedPostId(postList.get(0).getPostId());
            postChecked.setCreateUserId(SecurityUtils.getUserId());

            //4、入库
            IPostCheckedService thisBean = SpringUtils.getBean(IPostCheckedService.class);//获取代理对象保证事务传递
            int insertPostCheckedCount = thisBean.insertPostChecked(postChecked);
            if (insertPostCheckedCount <= 0) {
                throw new BaseException(downloadName + "文件入库失败，请稍后重试！插入条数：" + insertPostCheckedCount);
            }
        }

    }
    */

    /**
     * 自动生成全要素岗检检查表：岗检责任制清单人力资源审核通过时自动触发
     *
     * @param postListId 岗检责任制清单ID
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean autoCreateCheckedTypeAll(Long postListId) {
        //岗位责任制清单
        PostList postList = postListService.selectPostListById(postListId);
        //岗位责任制清单明细
        List<PostListInfo> postListInfoList = postList.getChildren();

        Long deptId = postList.getDeptId();
        Long postId = postList.getPostId();
        Long createUserId = postList.getCreateUserId();


        PostChecked postChecked = new PostChecked();
        postChecked.setCheckedType(PostCheckedEnum.CHECKED_TYPE_ALL.getValue());
        postChecked.setCheckedDeptId(deptId);
        postChecked.setCheckedPostId(postId);
        postChecked.setCreateUserId(createUserId);

        List<PostCheckedItems> children = postChecked.getChildren();

        //岗位责任制文件完整性与适宜性（系统默认添加）
        List<PostCheckedItems> postCheckedItemsList = postListService.contentListByType(deptId, postId, PostListEnum.TYPE_SIX.getValue());
        children.addAll(0, postCheckedItemsList);

        for (PostListInfo postListInfo : postListInfoList) {
            Integer listType = postListInfo.getType();
            PostCheckedItems postCheckedItems = new PostCheckedItems();
//            检查内容ID:实际上是岗位责任制清单明细的id，但是type=6和5时是接口（/contentListByType）写死的初始的部分，接口中也是把id写死了。
            postCheckedItems.setChildrenTypeId(postListInfo.getId());
            postCheckedItems.setSerialNumber(postListInfo.getSerialNumber());//序号
//            类型（1-业务职责；2-党建及党风廉政建设职责；3-安全环保职责；4-合规保密职；5-任职资格与能力素质要求）
//            类型（1-业务职责；2-党建及党风廉政建设职责；3-安全环保职责；4-合规保密职；5-任职资格与能力素质要求）
            postCheckedItems.setType(listType);
            postCheckedItems.setPostCheckedContent(postListInfo.getLevelLast());//最后一级事项
            if (listType == PostListEnum.TYPE_FIVE.getValue()) {
                postCheckedItems.setPostCheckedStandard(postListInfo.getRequirement());//检查标准
            } else {
                postCheckedItems.setPostCheckedStandard(postListInfo.getWorkStandard());//检查标准
            }
            postCheckedItems.setPostCheckedMethod(postListInfo.getPostCheckedMethod());//检查方法

            children.add(postCheckedItems);
        }

        int insertCount = 0;
        String errorMsg = "";
        try {
            insertCount = SpringUtils.getBean(IPostCheckedService.class).insertPostChecked(postChecked);
        } catch (BeansException e) {
            errorMsg = e.getMessage();
            e.printStackTrace();
        }

        if (insertCount <= 0) {
            throw new BaseException("自动生成全要素检查表失败，请稍后重试！" + errorMsg);
        }
        return true;
    }
}
