package com.ruoyi.postCheck.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.constant.PostCheckedProblemEnum;
import com.ruoyi.common.constant.PostCheckedReportEnum;
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.postCheck.domain.PostCheckedProblem;
import com.ruoyi.postCheck.domain.history.CheckStatisticsView;
import com.ruoyi.postCheck.domain.problemStatistics.CheckedProblemDeptDetaailView;
import com.ruoyi.postCheck.mapper.PostAssessmentRatingMapper;
import com.ruoyi.postCheck.mapper.PostAssessmentRatingOtherMapper;
import com.ruoyi.postCheck.mapper.PostCheckedProblemMapper;
import com.ruoyi.postCheck.model.DeptDetaailViewModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.postCheck.mapper.PostCheckedReportMapper;
import com.ruoyi.postCheck.domain.PostCheckedReport;
import com.ruoyi.postCheck.service.IPostCheckedReportService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.springframework.transaction.annotation.Transactional;

import javax.security.auth.callback.LanguageCallback;

/**
 * 岗检报告管理Service业务层处理
 *
 * @author csg
 * @date 2023-12-28
 */
@Service
public class PostCheckedReportServiceImpl extends ServiceImpl<PostCheckedReportMapper, PostCheckedReport> implements IPostCheckedReportService {
    @Autowired
    private PostAssessmentRatingMapper postAssessmentRatingMapper;
    @Autowired
    private PostCheckedReportMapper postCheckedReportMapper;
    @Autowired
    private PostCheckedProblemMapper postCheckedProblemMapper;
    @Autowired
    private PostAssessmentRatingOtherMapper postAssessmentRatingOtherMapper;

    /**
     * 查询岗检报告管理
     *
     * @param id 岗检报告管理主键
     * @return 岗检报告管理
     */
    @Override
    public PostCheckedReport selectPostCheckedReportById(Long id) {
        return postCheckedReportMapper.selectPostCheckedReportById(id);
    }

    /**
     * 查询岗检报告管理列表
     *
     * @param postCheckedReport 岗检报告管理
     * @return 岗检报告管理
     */
    @Override
    public List<PostCheckedReport> selectPostCheckedReportList(PostCheckedReport postCheckedReport) {
        return postCheckedReportMapper.selectPostCheckedReportList(postCheckedReport);
    }

    /**
     * 新增岗检报告管理
     *
     * @param postCheckedReport 岗检报告管理
     * @return 结果
     */
    @Override
    public int insertPostCheckedReport(PostCheckedReport postCheckedReport) {
        String reportName = postCheckedReport.getReportName();
//        Date startTime = postCheckedReport.getStartTime();
//        Date endTime = postCheckedReport.getEndTime();
        Integer type = postCheckedReport.getType();
        String diskPath = postCheckedReport.getDiskPath();


//        if (startTime == null || endTime == null || type == null || StringUtils.isBlank(diskPath)) {
        if (reportName == null || type == null || StringUtils.isBlank(diskPath)) {
//            throw new BaseException("参数不全(开始时间、结束时间、类型、报告文件)，请检查！");
            throw new BaseException("参数不全(名称、类型、报告文件)，请检查！");
        }
        //TODO 自增主键修改为-MyBatis-Plus雪花算法(截取5位解决VUE精度丢失BUG)-系统登录日志
//        if (postCheckedReport.getId() == null)
        postCheckedReport.setId(Long.parseLong(IdWorker.getIdStr().substring(4)));
        // postCheckedReport.setCreateTime(DateUtils.getNowDate());
        postCheckedReport.setCreateDefault();
        postCheckedReport.setStatus(PostCheckedReportEnum.STATUS_WAIT.getValue()); // 去创建自己的枚举类
        postCheckedReport.setCreateUserId(SecurityUtils.getUserId());

        postCheckedReport.setReportNo("BG-" + DateUtils.dateTimeNow());
        return postCheckedReportMapper.insertPostCheckedReport(postCheckedReport);
    }

    /**
     * 修改岗检报告管理
     *
     * @param postCheckedReport 岗检报告管理
     * @return 结果
     */
    @Override
    public int updatePostCheckedReport(PostCheckedReport postCheckedReport) {
        String reportName = postCheckedReport.getReportName();
//        Date startTime = postCheckedReport.getStartTime();
//        Date endTime = postCheckedReport.getEndTime();
        Integer type = postCheckedReport.getType();
        String diskPath = postCheckedReport.getDiskPath();


//        if (startTime == null || endTime == null || type == null || StringUtils.isBlank(diskPath)) {
        if (reportName == null || type == null || StringUtils.isBlank(diskPath)) {
//            throw new BaseException("参数不全(开始时间、结束时间、类型、报告文件)，请检查！");
            throw new BaseException("参数不全(名称、类型、报告文件)，请检查！");
        }

        // postCheckedReport.setUpdateTime(DateUtils.getNowDate());
        postCheckedReport.setUpdateDefault();
        return postCheckedReportMapper.updatePostCheckedReport(postCheckedReport);
    }

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

        LambdaQueryWrapper<PostCheckedReport> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(PostCheckedReport::getId, ids);
        List<PostCheckedReport> postCheckedReportList = postCheckedReportMapper.selectList(lambdaQueryWrapper);
        Map<Date, List<PostCheckedReport>> createTileLst = postCheckedReportList.stream().collect(Collectors.groupingBy(PostCheckedReport::getCreateTime));
        createTileLst.forEach((keyDate, postCheckedReports) -> {
            if (keyDate != null) {
                Date thisYear = DateUtils.parseDate(DateUtils.parseDateToStr(DateUtils.YYYY, new Date()) + "-01-01");
                if (keyDate.before(thisYear)) {
                    throw new BaseException("往期报告不可删除，请检查！");
                }
            }
        });

        return postCheckedReportMapper.deletePostCheckedReportByIds(ids);
    }

    /**
     * 删除岗检报告管理信息
     *
     * @param id 岗检报告管理主键
     * @return 结果
     */
    @Override
    public int deletePostCheckedReportById(Long id) {
        return postCheckedReportMapper.deletePostCheckedReportById(id);
    }

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

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

        //驳回时必须填写原因
        if (status == PostCheckedReportEnum.STATUS_BACK.getValue() && StringUtils.isBlank(reason)) {
            throw new BaseException("请填写未通过理由！");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser sysUser = loginUser.getUser();
        PostCheckedReport data = new PostCheckedReport();
        data.setId(id);
        data.setStatus(status);
        data.setStatusByUserId(sysUser.getUserId());
        data.setStatusByUserName(sysUser.getNickName());
        data.setStatusApproveTime(new Date());
        data.setStatusReason(reason);
        return postCheckedReportMapper.updatePostCheckedReport(data);
    }

    @Override
    public List<CheckStatisticsView> checkStatistics() {
        List<PostCheckedProblem> postCheckedProblems = postCheckedProblemMapper.selectList(Wrappers.lambdaQuery());
        List<CheckStatisticsView> validity = new ArrayList<>();
        {
            // 检查部门
            List<Long> collect1 = postCheckedProblems.stream().map(PostCheckedProblem::getCheckedDeptId).distinct().collect(Collectors.toList());
            CheckStatisticsView view1 = new CheckStatisticsView();
            view1.setValue(1);
            view1.setPostNum(collect1.size());
            validity.add(view1);
        }
        {
            // 检查岗位
            List<Long> collect1 = postCheckedProblems.stream().map(PostCheckedProblem::getCheckedPostId).distinct().collect(Collectors.toList());
            CheckStatisticsView view1 = new CheckStatisticsView();
            view1.setValue(2);
            view1.setPostNum(collect1.size());
            validity.add(view1);
        }
        {
            // 完整问题 1
            List<PostCheckedProblem> collect1 = postCheckedProblems.stream().filter(d -> d.getProblemAttribute() != null && d.getProblemAttribute() == 1).distinct().collect(Collectors.toList());
            CheckStatisticsView view1 = new CheckStatisticsView();
            view1.setValue(3);
            view1.setPostNum(collect1.size());
            validity.add(view1);
        }
        {
            // 2有效性问题
            List<PostCheckedProblem> collect1 = postCheckedProblems.stream().filter(d -> d.getProblemAttribute() != null && d.getProblemAttribute() == 2).distinct().collect(Collectors.toList());
            CheckStatisticsView view1 = new CheckStatisticsView();
            view1.setValue(4);
            view1.setPostNum(collect1.size());
            validity.add(view1);
        }
        {
            // 3 、适宜性问题
            List<PostCheckedProblem> collect1 = postCheckedProblems.stream().filter(d -> d.getProblemAttribute() != null && d.getProblemAttribute() == 3).distinct().collect(Collectors.toList());
            CheckStatisticsView view1 = new CheckStatisticsView();
            view1.setValue(5);
            view1.setPostNum(collect1.size());
            validity.add(view1);
        }
        {
            // 问题总数
            CheckStatisticsView view1 = new CheckStatisticsView();
            view1.setValue(6);
            view1.setPostNum(postCheckedProblems.size());
            validity.add(view1);
        }
        {
            // 已整改问题
            List<PostCheckedProblem> collect1 = postCheckedProblems.stream().filter(d -> d.getIsRectificationCompleted() != null && d.getIsRectificationCompleted() == 1).distinct().collect(Collectors.toList());
            CheckStatisticsView view1 = new CheckStatisticsView();
            view1.setValue(7);
            view1.setPostNum(collect1.size());
            validity.add(view1);
        }
        return validity;
    }

    @Override
    public List<CheckedProblemDeptDetaailView> deptDetaailView(DeptDetaailViewModel type) {

        List<Map<String, Object>> deptIdListByType = postAssessmentRatingOtherMapper.getDeptIdListByType(type.getType());
        if (deptIdListByType == null || deptIdListByType.size() == 0) {
            return new ArrayList<>();
        }
        List<String> deptIds = deptIdListByType.stream().map(d -> d.get("deptId").toString()).distinct().collect(Collectors.toList());
        // 查询职能问题数量
        LambdaQueryWrapper<PostCheckedProblem> postCheckedProblemLambdaQueryWrapper = Wrappers.<PostCheckedProblem>lambdaQuery();
        postCheckedProblemLambdaQueryWrapper.in(PostCheckedProblem::getCheckedDeptId, deptIds);
        if (type.getParams() != null && type.getParams().get("beginTime") != null && type.getParams().get("beginTime") != null)
            postCheckedProblemLambdaQueryWrapper.between(PostCheckedProblem::getCreateTime, type.getParams().get("beginTime"), type.getParams().get("endTime"));
        List<PostCheckedProblem> postCheckedProblems = postCheckedProblemMapper.selectList(postCheckedProblemLambdaQueryWrapper);

        List<CheckedProblemDeptDetaailView> list = new ArrayList<>();

        //TODO 第一步：得到各个部门ID、部门名称、问题总数量、重要问题数量、一般问题数量、统计时间
        //TODO 第二步：得到4个职责类别的问题数量及整改完成数量(1-业务职责；2-党建及党风廉政；3-安全环保职责；4-合规保密职；)
        //TODO 第三步：设置部门的整改率：遍历职责类别计算整改率
        if (postCheckedProblems != null && postCheckedProblems.size() > 0) {
            Map<Long, List<PostCheckedProblem>> deptMap = postCheckedProblems.stream().collect(Collectors.groupingBy(PostCheckedProblem::getCheckedDeptId));
            for (Map.Entry<Long, List<PostCheckedProblem>> longListEntry : deptMap.entrySet()) {
                Long key = longListEntry.getKey();
                List<PostCheckedProblem> value = longListEntry.getValue();
                CheckedProblemDeptDetaailView data1 = new CheckedProblemDeptDetaailView();
                data1.setDeptId(key); //部门ID
                data1.setDeptName(postAssessmentRatingMapper.getSysDeptName(key));// 部门名称
                if (type.getDeptName() != null && !data1.getDeptName().contains(type.getDeptName())) {
                    continue;
                }
                int problemTotal = 0;
//    @ApiModelProperty("一般")
                Integer problemLeveOne = 0;
//    @ApiModelProperty("重要")
                Integer problemLeveTwo = 0;

                Integer rate = 0;
                for (PostCheckedProblem postCheckedProblem : value) {
                    problemTotal++;
                    if (postCheckedProblem.getProblemLevel().equals("1")) {
                        problemLeveOne++;
                    }
                    if (postCheckedProblem.getProblemLevel().equals("2")) {
                        problemLeveTwo++;
                    }
                    if (postCheckedProblem.getIsRectificationCompleted() != null && postCheckedProblem.getIsRectificationCompleted() == 1) {
                        rate++;
                    }
                }
                if (rate == 0 || problemTotal == 0) {
                    data1.setRate(new BigDecimal("0"));
                } else {
                    data1.setRate(new BigDecimal(rate).divide(new BigDecimal(problemTotal), 4, RoundingMode.HALF_UP));
                }
                data1.setStatisticsTime(new Date());
                data1.setProblemTotal(problemTotal); //问题数量
                data1.setProblemLeveTwo(problemLeveTwo); //重要问题
                data1.setProblemLeveOne(problemLeveOne); //一般问题
                Map<Integer, List<PostCheckedProblem>> dutyMap = value.stream().collect(Collectors.groupingBy(PostCheckedProblem::getDutyType));

                List<CheckedProblemDeptDetaailView.ProblemAttributeInner> innerList = new ArrayList<>();
                for (Map.Entry<Integer, List<PostCheckedProblem>> integerListEntry : dutyMap.entrySet()) {
                    //        @ApiModelProperty("完整性数量")
                    int problemComplete = 0;
//        @ApiModelProperty("适宜性数量")
                    int problemSuitable = 0;
//        @ApiModelProperty("有效性数量")
                    int problemEffective = 0;
                    Integer duty = integerListEntry.getKey();
                    CheckedProblemDeptDetaailView.ProblemAttributeInner child1 = new CheckedProblemDeptDetaailView.ProblemAttributeInner();
                    child1.setDutyType(duty);
                    List<PostCheckedProblem> postCheckedProblemList = integerListEntry.getValue();
//                    @ApiModelProperty("已完成完整性数量")
                    int problemCompleteChecked = 0;
//                    @ApiModelProperty("已完成适宜性数量")
                    int problemSuitableChecked = 0;
//                    @ApiModelProperty("已完成有效性数量")
                    int problemEffectiveChecked = 0;
                    for (PostCheckedProblem postCheckedProblem : postCheckedProblemList) {
                        if (postCheckedProblem.getProblemAttribute() == 1) {
                            problemComplete++;
                        }
                        if (postCheckedProblem.getProblemAttribute() == 2) {
                            problemEffective++;
                        }
                        if (postCheckedProblem.getProblemAttribute() == 3) {
                            problemSuitable++;
                        }
                        if (postCheckedProblem.getIsRectificationCompleted() != null && postCheckedProblem.getIsRectificationCompleted() == 1) {
                            if (postCheckedProblem.getProblemAttribute() == 1) {
                                problemCompleteChecked++;
                            }
                            if (postCheckedProblem.getProblemAttribute() == 2) {
                                problemEffectiveChecked++;
                            }
                            if (postCheckedProblem.getProblemAttribute() == 3) {
                                problemSuitableChecked++;
                            }
                        }
                    }
                    child1.setProblemComplete(problemComplete);
                    child1.setProblemEffective(problemEffective);
                    child1.setProblemSuitable(problemSuitable);
                    child1.setProblemCompleteChecked(problemCompleteChecked);
                    child1.setProblemEffectiveChecked(problemEffectiveChecked);
                    child1.setProblemSuitableChecked(problemSuitableChecked);
                    innerList.add(child1);
                }
                data1.setChildren(innerList);
                list.add(data1);

            }
        }
        return list;
    }
}
