package com.ruoyi.doubledefense.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.constant.AppUserTypeEnum;
import com.ruoyi.common.constant.DangerStatusEnum;
import com.ruoyi.common.constant.DeletedEnum;
import com.ruoyi.common.constant.SysNoticeTitleRouteEnum;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.TbSysAreaUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.*;
import com.ruoyi.doubledefense.domain.Danger;
import com.ruoyi.doubledefense.domain.DangerManage;
import com.ruoyi.doubledefense.domain.DangerOperateRecord;
import com.ruoyi.doubledefense.dto.DangerDTO;
import com.ruoyi.doubledefense.dto.DangerStatisticsDTO;
import com.ruoyi.doubledefense.dto.DangerStatisticsPCDTO;
import com.ruoyi.doubledefense.dto.res.DangerResultDTO;
import com.ruoyi.doubledefense.dtoGov.DangerDTOGov;
import com.ruoyi.doubledefense.mapper.DangerManageMapper;
import com.ruoyi.doubledefense.mapper.DangerMapper;
import com.ruoyi.doubledefense.mapper.DangerOperateRecordMapper;
import com.ruoyi.doubledefense.service.IDangerService;
import com.ruoyi.system.domain.AppLogin;
import com.ruoyi.system.dto.ContractorUserDTO;
import com.ruoyi.system.mapper.TbSysAreaMapper;
import com.ruoyi.system.service.IAppLoginService;
import com.ruoyi.system.service.IContractorUserService;
import com.ruoyi.system.service.ISysNoticeService;
import com.ruoyi.system.service.ISysUserService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 隐患信息Service业务层处理
 *
 * @author ruoyi
 * @date 2023-08-03
 */
@Service
public class DangerServiceImpl implements IDangerService {
    @Autowired
    private DangerMapper dangerMapper;
    @Autowired
    private IAppLoginService appLoginService;
    @Autowired
    private IContractorUserService contractorUserService;

    @Autowired
    private DangerManageMapper dangerManageMapper;

    @Autowired
    private DangerOperateRecordMapper dangerOperateRecordMapper;
    @Autowired
    private ISysNoticeService sysNoticeService;

//    @Autowired
//    private TbSysAreaUserRelationMapper tbSysAreaUserRelationMapper;

    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private TbSysAreaMapper tbSysAreaMapper;

    /**
     * 重预防汇聚计算节点
     * 查询隐患列表
     *
     * @param dangerDTOGov
     * @return
     */
    @Override
    public PageInfo<DangerDTOGov> govSelectDangerList(DangerDTOGov dangerDTOGov) {
        PageHelper.startPage(dangerDTOGov.getPageNo(),dangerDTOGov.getPageSize());
        List<DangerDTOGov> dangerDTOGovList = dangerMapper.govSelectDangerList(dangerDTOGov);
        PageInfo<DangerDTOGov> pageInfo = new PageInfo<>(dangerDTOGovList);
        return pageInfo;
    }

    /**
     * 查询隐患信息
     *
     * @param id 隐患信息主键
     * @return 隐患信息
     */
    @Override
    public DangerResultDTO selectDangerById(String id) {
        DangerDTO dangerDTO = new DangerDTO();
        dangerDTO.setId(id);
        List<DangerResultDTO> dangerResultDTOS = selectDangerList(dangerDTO);
        if (CollectionUtils.isEmpty(dangerResultDTOS)) {
            return null;
        }
        //填充流程信息
        DangerResultDTO dangerResultDTO = dangerResultDTOS.get(0);
        LambdaQueryWrapper<DangerOperateRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DangerOperateRecord::getDangerId, id);
        queryWrapper.orderByDesc(DangerOperateRecord::getCreateDate);//流程记录按创建时间排序
        List<DangerOperateRecord> dangerOperateRecords = dangerOperateRecordMapper.selectList(queryWrapper);
        if (!CollectionUtils.isEmpty(dangerOperateRecords)) {
            for (int i = 0; i < dangerOperateRecords.size(); i++) {
                DangerOperateRecord dangerOperateRecord = dangerOperateRecords.get(i);
                // CREATE ("创建",0),
                if (DangerStatusEnum.CREATE.getValue().equals(dangerOperateRecord.getDangerStatus())) {
                    dangerOperateRecord.setStatusDesc("上报隐患");
                }
                //CHECK_PENDING("待审核",10),
                else if (DangerStatusEnum.CHECK_PENDING.getValue().equals(dangerOperateRecord.getDangerStatus())) {
                    dangerOperateRecord.setStatusDesc(dangerOperateRecord.getOperateUserId() != null ? "审核完成" : "等待审核");
                    if (dangerOperateRecord.getOperateUserId() == null)
                        dangerOperateRecord.setOperateTime(null);
                }
                //UNCLAIMED ("认领中",20),
                else if (DangerStatusEnum.UNCLAIMED.getValue().equals(dangerOperateRecord.getDangerStatus())) {
                    dangerOperateRecord.setStatusDesc(dangerOperateRecord.getOperateUserId() != null ? "已认领隐患" : "等待认领");
                    if (dangerOperateRecord.getOperateUserId() == null)
                        dangerOperateRecord.setOperateTime(null);
                }
                //RECTIFICATION("整改中",30),
                else if (DangerStatusEnum.RECTIFICATION.getValue().equals(dangerOperateRecord.getDangerStatus())) {
                    dangerOperateRecord.setStatusDesc(dangerOperateRecord.getOperateUserId() != null ? "整改完成" : "整改中");
                    if (dangerOperateRecord.getOperateUserId() == null)
                        dangerOperateRecord.setOperateTime(null);
                }
                //WAIT_FOR_ACCEPTANCE("待验收",40),
                else if (DangerStatusEnum.WAIT_FOR_ACCEPTANCE.getValue().equals(dangerOperateRecord.getDangerStatus())) {
                    //40待验收驳回时，显示验收驳回：需要查询当前集合中的上一个记录的状态是否为30-整改中（因为是倒叙所以查看上一个）
                    if (i >= 1) {
                        DangerOperateRecord nextStatusNode = dangerOperateRecords.get(i - 1);
                        Integer dangerStatus = nextStatusNode.getDangerStatus();
                        //下一状态不等于“已验收”显示信息“验收驳回”
                        if (!dangerStatus.equals(DangerStatusEnum.COMPLETED.getValue())) {
                            dangerOperateRecord.setStatusDesc(dangerOperateRecord.getOperateUserId() != null ? "验收驳回" : "等待验收");
                        } else {
                            dangerOperateRecord.setStatusDesc(dangerOperateRecord.getOperateUserId() != null ? "验收完成" : "等待验收");
                        }
                    } else {
                        dangerOperateRecord.setStatusDesc(dangerOperateRecord.getOperateUserId() != null ? "验收完成" : "等待验收");
                    }
                }
                // COMPLETED("已完成",50),
                else if (DangerStatusEnum.COMPLETED.getValue().equals(dangerOperateRecord.getDangerStatus())) {
                    dangerOperateRecord.setStatusDesc("已完成");
                }
                //CANCELED("已取消",60);
                else if (DangerStatusEnum.CANCELED.getValue().equals(dangerOperateRecord.getDangerStatus())) {
                    dangerOperateRecord.setStatusDesc("已取消");
                }
            }
        }
        dangerResultDTO.setDangerOperateRecordList(dangerOperateRecords);
        //填充区域负责人ID集合
        Long areaId = dangerResultDTO.getAreaId();
        if (areaId != null) {
            List<TbSysAreaUser> sysUsers = tbSysAreaMapper.selectUserNickNameByAreaIdList(Arrays.asList(areaId));
            dangerResultDTO.setAreaManageUserList(sysUsers);
        }


        return dangerResultDTO;
    }

    /**
     * 查询隐患信息列表
     *
     * @param danger 隐患信息
     * @return 隐患信息
     */
    @Override
    public List<DangerResultDTO> selectDangerList(DangerDTO danger) {
        //TODO 待发布：开发环境时才生效，线上环境依旧显示全部数据
        HttpServletRequest request = ServletUtils.getRequest();
        String localAddr = request.getLocalAddr();
        if (localAddr.startsWith("192.168.3.")) {
            //需要查看的人：
            //如果领导角色就查看全部
            //上报人：创建人
            //区域负责人
            //整改负责人：审核完成以后才可以查看
       /* LoginUser loginUser = null;
        try {
            loginUser = SecurityUtils.getLoginUser();
        } catch (Exception e) {
        }*/

//        隐患列表：哪些人可以查看：
//        1、如果领导角色就查看全部
//        非领导角色：
//        1、上报人：创建人
//        2、区域负责人
//        3、整改负责人：审核完成以后才可以查看（待审核和取消的状态不让查看）
            String requestToken = JWTUtil.getRequestToken();

            String appUserType = null;
            try {
                appUserType = JWTUtil.getAppUserType();
            } catch (Exception e) {

            }
            //承包商不让查看，直接返回空集合
            if (appUserType != null && AppUserTypeEnum.CONTRACTOR.getValue() == Integer.parseInt(appUserType)) {
                return new ArrayList<>();
            }
            // APP请求时
            else if (StringUtils.isNotBlank(requestToken)) {
                boolean leader = JWTUtil.isLeader();
                String pcUserId = JWTUtil.getPCUserId();
                //APP登录人员的岗位集合
                List<Long> postIdList = JWTUtil.getPostIdList();
                // 非领导角色不能查看全部，需要筛选
                if (!leader) {
                    danger.setDataUserId(Long.parseLong(pcUserId));
                    danger.setPostIdList(postIdList);
                }
            }
            //WEB请求
//        else if (loginUser != null) {
//            Long userId = SecurityUtils.getUserId();
//            String username = SecurityUtils.getUsername();
//        }
        }

        return dangerMapper.selectDangerList(danger);
    }

    /**
     * PC首页统计-双重防御机制：查询隐患列表
     *
     * @param danger 隐患信息
     * @return 隐患信息
     */
    @Override
    public List<DangerResultDTO> pcHomePageDangerList(DangerDTO danger) {

        return dangerMapper.pcHomePageDangerList(danger);
    }

    /**
     * 新增隐患信息
     *
     * @param dangerDTO 隐患信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertDanger(DangerDTO dangerDTO) {
        System.out.println("PC新增隐患开始");
        Danger danger = new Danger();
        BeanUtils.copyProperties(dangerDTO, danger);
        danger.setId(UUID.randomUUID().toString());
        danger.setDangerStatus(DangerStatusEnum.CHECK_PENDING.getValue());
        danger.setCreateDefault();
        // 隐患编号
        danger.setDangerNo(CodeUtils.getDangerCode());
        int count = dangerMapper.insert(danger);
        DangerManage dangerManage = new DangerManage();
        BeanUtils.copyProperties(dangerDTO, dangerManage);
        dangerManage.setDangerId(danger.getId());
        dangerManage.setCreateDefault();
        dangerManageMapper.insert(dangerManage);
        //创建流程数据
        DangerOperateRecord dangerOperateRecord = new DangerOperateRecord();
        dangerOperateRecord.setOperateTime(new Date());
        dangerOperateRecord.setDangerStatus(DangerStatusEnum.CREATE.getValue());
        dangerOperateRecord.setOperateUserName(SecurityUtils.getUsername());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        dangerOperateRecord.setOperateNickName(loginUser.getNickName());
        dangerOperateRecord.setOperateUserId(SecurityUtils.getUserId());
        dangerOperateRecord.setDangerId(danger.getId());
//        System.out.println("PC新增隐患开始：申请时间-未偏移");
        dangerOperateRecord.setCreateDefault();
//        System.out.println(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_SSS, dangerOperateRecord.getCreateDate()));
        dangerOperateRecord.setCreateDate(DateUtils.addSeconds(new Date(), -3));
//        System.out.println(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_SSS, dangerOperateRecord.getCreateDate()));
//        System.out.println("PC新增隐患开始：申请时间-前偏移3秒");

        dangerOperateRecordMapper.insert(dangerOperateRecord);

        //待审核流程
        DangerOperateRecord dangerOperateRecord2 = new DangerOperateRecord();
        dangerOperateRecord2.setDangerStatus(DangerStatusEnum.CHECK_PENDING.getValue());
        dangerOperateRecord2.setDangerId(danger.getId());
        dangerOperateRecord2.setCreateDefault();
//        System.out.println("PC新增隐患开始：审核时间-未偏移");
//        System.out.println(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_SSS, dangerOperateRecord2.getCreateDate()));
        dangerOperateRecord2.setCreateDate(DateUtils.addSeconds(new Date(), 3));
//        System.out.println(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_SSS, dangerOperateRecord2.getCreateDate()));
//        System.out.println("PC新增隐患开始：审核时间-后偏移3秒");

        dangerOperateRecordMapper.insert(dangerOperateRecord2);


        //1、上报完成后：给区域负责人发消息 -> xxx上报了隐患信息，请及时确认，单据号：xxxx
//        LoginUser loginUser = SecurityUtils.getLoginUser();
        String noticeContent = loginUser.getNickName() + "上报了隐患信息，请及时确认，单据号：" + danger.getDangerNo();
        //收消息的人：区域负责人

        //根据区域ID查询岗位下的用户集合
        List<TbSysAreaUser> sysUsers = tbSysAreaMapper.selectUserNickNameByAreaIdList(Arrays.asList(danger.getAreaId()));
        Set<Long> appUserIdSet = sysUsers.parallelStream().map(TbSysAreaUser::getAppUserId).distinct().collect(Collectors.toSet());
        appUserIdSet.forEach(appUserId -> {
            if (appUserId != null)
                sysNoticeService.insertNoticeToUser(appUserId, noticeContent, SysNoticeTitleRouteEnum.DANGER);
        });

        return count;
    }

    /**
     * 修改隐患信息
     *
     * @param dangerDTO 隐患信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateDanger(DangerDTO dangerDTO) {
        if (StringUtils.isBlank(dangerDTO.getId())) {
            throw new RuntimeException("缺少参数id");
        }
        Danger danger = new Danger();
        BeanUtils.copyProperties(dangerDTO, danger);
        danger.setUpdateDefault();
        int count = dangerMapper.updateById(danger);
        DangerManage dangerManage = new DangerManage();
        BeanUtils.copyProperties(dangerDTO, dangerManage);
        dangerManage.setDangerId(danger.getId());
        dangerManage.setUpdateDefault();
        QueryWrapper<DangerManage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("danger_id", dangerDTO.getId());
        dangerManageMapper.update(dangerManage, queryWrapper);
        return count;
    }

    /**
     * 批量删除隐患信息
     *
     * @param ids 需要删除的隐患信息主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteDangerByIds(String[] ids) {
        Danger danger = new Danger();
        danger.setIsDel(DeletedEnum.INVALID.getValue());
        danger.setUpdateDefault();
        QueryWrapper<Danger> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        int count = dangerMapper.update(danger, queryWrapper);

        DangerManage dangerManage = new DangerManage();
        dangerManage.setIsDel(DeletedEnum.INVALID.getValue());
        dangerManage.setUpdateDefault();
        QueryWrapper<DangerManage> dangerManageQueryWrapper = new QueryWrapper<>();
        dangerManageQueryWrapper.in("danger_id", ids);
        dangerManageMapper.update(dangerManage, dangerManageQueryWrapper);
        return count;
    }

    /**
     * 新增隐患信息
     *
     * @param dangerDTO 隐患信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertDangerForApp(DangerDTO dangerDTO) {
       /* //用户昵称
        String nickName = null;
        //用户类型：1内部，2承包商
        if ("1".equals(JWTUtil.getAppUserType())) {
            //设置人员姓名
            SysUser sysUser = sysUserService.selectUserById(Long.parseLong(JWTUtil.getPCUserId()));
            if (Objects.nonNull(sysUser)) {
                nickName = sysUser.getNickName();
            }
        } else {
            AppLogin appLogin = appLoginService.selectAppLoginById(JWTUtil.getUserId());
            if (Objects.nonNull(appLogin)) {
                ContractorUserDTO contractorUserDTO = contractorUserService.selectContractorUserById(appLogin.getContractorUserId());
                if (Objects.nonNull(contractorUserDTO)) {
                    nickName = contractorUserDTO.getCompellation();
                }
            }
        }*/

        //1、添加隐患信息表
        Danger danger = new Danger();
        BeanUtils.copyProperties(dangerDTO, danger);
        danger.setId(UUID.randomUUID().toString());
        danger.setDangerStatus(DangerStatusEnum.CHECK_PENDING.getValue());
        danger.setCreateDate(new Date());
        danger.setUpdateDate(new Date());
        danger.setDangerNo(CodeUtils.getDangerCode());// 隐患编号
        int count = dangerMapper.insert(danger);

        //2、添加隐患治理表
        DangerManage dangerManage = new DangerManage();
        BeanUtils.copyProperties(dangerDTO, dangerManage);
        dangerManage.setDangerId(danger.getId());
        dangerManage.setCreateDate(new Date());
        dangerManage.setUpdateDate(new Date());
        dangerManageMapper.insert(dangerManage);


        //流程记录创建时间：多条插入时，时间需要 +1秒
//        Date recordCreateDate = new Date();

        //3、添加隐患操作记录表：申请人
        DangerOperateRecord dangerOperateRecord = new DangerOperateRecord();
        dangerOperateRecord.setDangerId(danger.getId());
        dangerOperateRecord.setDangerStatus(DangerStatusEnum.CREATE.getValue());//0
        dangerOperateRecord.setOperateTime(new Date());
        dangerOperateRecord.setOperateUserId(Long.parseLong(JWTUtil.getPCUserId()));
        dangerOperateRecord.setOperateUserName(JWTUtil.getUserName());
        dangerOperateRecord.setOperateNickName(JWTUtil.getNickName());
        dangerOperateRecord.setCreateDefaultForApp();
        System.out.println("新增隐患开始：申请时间-未偏移");
        System.out.println(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_SSS, dangerOperateRecord.getCreateDate()));
        dangerOperateRecord.setCreateDate(DateUtils.addSeconds(new Date(), -30));
        System.out.println(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_SSS, dangerOperateRecord.getCreateDate()));
        System.out.println("新增隐患开始：申请时间-前偏移30秒");
        dangerOperateRecordMapper.insert(dangerOperateRecord);


        //3、添加隐患操作记录表：待审核
        DangerOperateRecord dangerOperateRecord2 = new DangerOperateRecord();
        dangerOperateRecord2.setDangerId(danger.getId());
        dangerOperateRecord2.setDangerStatus(DangerStatusEnum.CHECK_PENDING.getValue());//10
        dangerOperateRecord2.setOperateTime(new Date());
//        dangerOperateRecord2.setOperateUserId(Long.parseLong(JWTUtil.getPCUserId()));
//        dangerOperateRecord2.setOperateUserName(JWTUtil.getUserName());
//        dangerOperateRecord2.setOperateNickName(nickName);
        dangerOperateRecord2.setCreateDefaultForApp();
        System.out.println("新增隐患开始：审核时间-未偏移");
        System.out.println(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_SSS, dangerOperateRecord2.getCreateDate()));
        dangerOperateRecord2.setCreateDate(DateUtils.addSeconds(new Date(), 3));
        System.out.println(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS_SSS, dangerOperateRecord2.getCreateDate()));
        System.out.println("新增隐患开始：审核时间-后偏移3秒");
        dangerOperateRecordMapper.insert(dangerOperateRecord2);

        //1、上报完成后：给区域负责人发消息 -> xxx上报了隐患信息，请及时确认，单据号：xxxx
        String noticeContent = JWTUtil.getNickName() + "上报了隐患信息，请及时确认，单据号：" + danger.getDangerNo();
        //收消息的人：区域负责人

        //根据区域ID查询岗位下的用户集合
        List<TbSysAreaUser> sysUsers = tbSysAreaMapper.selectUserNickNameByAreaIdList(Arrays.asList(danger.getAreaId()));
        Set<Long> appUserIdSet = sysUsers.parallelStream().map(TbSysAreaUser::getAppUserId).distinct().collect(Collectors.toSet());
        appUserIdSet.forEach(appUserId -> {
            if (appUserId != null)
                sysNoticeService.insertNoticeToUser(appUserId, noticeContent, SysNoticeTitleRouteEnum.DANGER);
        });
        return count;
    }

    /**
     * 修改隐患信息
     *
     * @param dangerDTO      隐患信息
     * @param isStatusUpdate 是否状态变更
     * @return 结果
     */
    @Override
    @Transactional
    public int updateDangerForApp(DangerDTO dangerDTO, boolean isStatusUpdate) {
        Danger danger = new Danger();
        BeanUtils.copyProperties(dangerDTO, danger);
        danger.setUpdateDefaultForApp();
        //1、更新隐患的状态
        int count = dangerMapper.updateById(danger);

        DangerManage dangerManage = new DangerManage();
        BeanUtils.copyProperties(dangerDTO, dangerManage);
        dangerManage.setDangerId(danger.getId());
        dangerManage.setUpdateDefaultForApp();
        QueryWrapper<DangerManage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("danger_id", dangerDTO.getId());
        dangerManageMapper.update(dangerManage, queryWrapper);

        //处理隐患流程记录信息
        handleDangerOperateRecord(danger, isStatusUpdate);
        return count;
    }

    private void handleDangerOperateRecord(Danger danger, boolean isStatusUpdate) {
        //流程记录创建时间：多条插入时，时间需要 +1秒
//        Date recordCreateDate = new Date();
//        recordCreateDate = DateUtils.addSeconds(recordCreateDate, 1);

        try {
            //判断是否状态变更
            if (isStatusUpdate) {
                //更新未完成操作记录
                DangerOperateRecord dangerOperateRecord = getDangerOperateRecordByDangerId(danger.getId());
                if (Objects.nonNull(dangerOperateRecord)) {
                    setOptionInfo(dangerOperateRecord);//设置操作人信息：id、userName、nickName
                    //驳回时需要修改上1条的状态为取消
                    if (danger.getDangerStatus() == DangerStatusEnum.CANCELED.getValue()) {
                        dangerOperateRecord.setDangerStatus(DangerStatusEnum.CANCELED.getValue());
                    }
                    dangerOperateRecordMapper.updateById(dangerOperateRecord);
                }
                //判断是否需要下一个流程，已完成和取消状态为最后一个流程
                if (!danger.getDangerStatus().equals(DangerStatusEnum.COMPLETED.getValue()) &&
                        !danger.getDangerStatus().equals(DangerStatusEnum.CANCELED.getValue())) {
                    //下一个状态流程
                    DangerOperateRecord dangerOperateRecord2 = new DangerOperateRecord();
                    dangerOperateRecord2.setDangerStatus(danger.getDangerStatus());
                    dangerOperateRecord2.setDangerId(danger.getId());
                    dangerOperateRecord2.setCreateDefaultForApp();
//                    dangerOperateRecord2.setCreateDate(recordCreateDate);//创建时间，流程记录列表时排序字段
                    dangerOperateRecordMapper.insert(dangerOperateRecord2);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 查询隐患节点未完成的流程记录
     *
     * @param dangerId
     * @return
     */
    private DangerOperateRecord getDangerOperateRecordByDangerId(String dangerId) {
        QueryWrapper<DangerOperateRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("danger_id", dangerId);
        queryWrapper.isNull("operate_user_id");
        List<DangerOperateRecord> dangerOperateRecords = dangerOperateRecordMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(dangerOperateRecords)) {
            return null;
        }
        return dangerOperateRecords.get(0);
    }


    /**
     * 填充操作信息
     *
     * @param dangerOperateRecord
     */
    public void setOptionInfo(DangerOperateRecord dangerOperateRecord) {

        //用户昵称
//        String nickName = null;
//        //用户类型：1内部，2承包商
//        if ("1".equals(JWTUtil.getAppUserType())) {
//            //设置人员姓名
//            SysUser sysUser = sysUserService.selectUserById(Long.parseLong(JWTUtil.getPCUserId()));
//            if (Objects.nonNull(sysUser)) {
//                nickName = sysUser.getNickName();
//            }
//        } else {
//            AppLogin appLogin = appLoginService.selectAppLoginById(JWTUtil.getUserId());
//            if (Objects.nonNull(appLogin)) {
//                ContractorUserDTO contractorUserDTO = contractorUserService.selectContractorUserById(appLogin.getContractorUserId());
//                if (Objects.nonNull(contractorUserDTO)) {
//                    nickName = contractorUserDTO.getCompellation();
//                }
//            }
//        }

        dangerOperateRecord.setOperateTime(new Date());
        dangerOperateRecord.setOperateUserId(Long.parseLong(JWTUtil.getUserId()));
        dangerOperateRecord.setOperateUserName(JWTUtil.getUserName());
//        dangerOperateRecord.setOperateNickName(nickName);//设置用户昵称
        dangerOperateRecord.setOperateNickName(JWTUtil.getNickName());//设置用户昵称
        dangerOperateRecord.setUpdateDefaultForApp();
    }

    /**
     * 审核隐患
     *
     * @param dangerDTO
     * @return
     */
    @Override
    public AjaxResult dangerReview(DangerDTO dangerDTO) {
        //判断权限，审核人是否是区域负责人
        DangerResultDTO dangerResultDTO = selectDangerById(dangerDTO.getId());
        if (Objects.isNull(dangerResultDTO)) {
            return AjaxResult.error("隐患信息不存在！");
        }
        if (!dangerResultDTO.getDangerStatus().equals(DangerStatusEnum.CHECK_PENDING.getValue())) {
            return AjaxResult.error("隐患非待审核状态！");
        }
        //根据区域ID查询岗位下的用户集合
        List<TbSysAreaUser> sysUsers = tbSysAreaMapper.selectUserNickNameByAreaIdList(Arrays.asList(dangerResultDTO.getAreaId()));
        Set<Long> areaUserIdSet = sysUsers.parallelStream().map(TbSysAreaUser::getUserId).distinct().collect(Collectors.toSet());
        //判断是否是区域负责人
        if (!areaUserIdSet.contains(Long.parseLong(JWTUtil.getPCUserId()))) {
            return AjaxResult.error("该用户无审核权限");
        }

//        QueryWrapper<TbSysAreaUserRelation> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("area_id", dangerResultDTO.getAreaId());
//        queryWrapper.eq("user_id", userId);
//        List<TbSysAreaUserRelation> sysAreaUserRelations = tbSysAreaUserRelationMapper.selectList(queryWrapper);
        //判断是否是区域负责人
//        if (CollectionUtils.isEmpty(sysAreaUserRelations)) {
//            return AjaxResult.error("该用户无审核权限");
//        }

        //审核
        if (dangerDTO.getDangerStatus() == DangerStatusEnum.UNCLAIMED.getValue()) {
            //2、审核完成后：给整改负责人（认领人）发消息 -> 单据号：xxxx已审批，请及时认领！
            String noticeContent = "单据号：" + dangerResultDTO.getDangerNo() + "已审批，请及时认领！";
            Long manageUserId = dangerResultDTO.getManageUserId();
            AppLogin appLogin = appLoginService.selectAppLoginByUserId(manageUserId);
            if (!Objects.isNull(appLogin)) {
                //发消息
                sysNoticeService.insertNoticeToUser(appLogin.getId(), noticeContent, SysNoticeTitleRouteEnum.DANGER);
            }
        }
        //驳回
        else if (dangerDTO.getDangerStatus() == DangerStatusEnum.CANCELED.getValue()) {


        }


        return AjaxResult.success(updateDangerForApp(dangerDTO, true));
    }

    @Override
    public AjaxResult receiveDanger(String dangerId) {
        //判断认领权限，认领人是否是整改负责人
//        String userId = JWTUtil.getUserId();
        String userId = JWTUtil.getPCUserId();
        DangerResultDTO dangerResultDTO = selectDangerById(dangerId);
        if (Objects.isNull(dangerResultDTO)) {
            return AjaxResult.error("隐患信息不存在！");
        }
        //判断是否是整改负责人
//        if (!dangerResultDTO.getManageUserId().equals(userId)) {
        if (!dangerResultDTO.getManageUserId().toString().equals(userId)) {
            return AjaxResult.error("该用户无权限认领！");
        }
        if (!dangerResultDTO.getDangerStatus().equals(DangerStatusEnum.UNCLAIMED.getValue())) {
            return AjaxResult.error("隐患非待领取状态！");
        }
        DangerDTO updateDangerDTO = new DangerDTO();
        updateDangerDTO.setId(dangerId);
        updateDangerDTO.setDangerStatus(DangerStatusEnum.RECTIFICATION.getValue());
        return AjaxResult.success(updateDangerForApp(updateDangerDTO, true));
    }


    @Override
    public AjaxResult submitDangerManage(DangerDTO dangerDTO) {
        //判断整改提交权限，整改人是否是整改负责人
//        String userId = JWTUtil.getUserId();
        String userId = JWTUtil.getPCUserId();
        DangerResultDTO dangerResultDTO = selectDangerById(dangerDTO.getId());
        if (Objects.isNull(dangerResultDTO)) {
            return AjaxResult.error("隐患信息不存在！");
        }
        //判断是否是整改负责人
        if (!dangerResultDTO.getManageUserId().toString().equals(userId)) {
            return AjaxResult.error("该用户无权限提交整改信息！");
        }
        if (!dangerResultDTO.getDangerStatus().equals(DangerStatusEnum.RECTIFICATION.getValue())) {
            return AjaxResult.error("隐患非整改中状态！");
        }

        //3、待验收时：给区域负责人发消息 -> 单据号：xxxx的隐患已整改，请及时确认！
        String noticeContent = "单据号：" + dangerResultDTO.getDangerNo() + "的隐患已整改，请及时确认！";
        //收消息的人：负责人
        //根据区域ID查询岗位下的用户集合
        List<TbSysAreaUser> sysUsers = tbSysAreaMapper.selectUserNickNameByAreaIdList(Arrays.asList(dangerResultDTO.getAreaId()));
        Set<Long> appUserIdSet = sysUsers.parallelStream().map(TbSysAreaUser::getAppUserId).distinct().collect(Collectors.toSet());
        appUserIdSet.forEach(appUserId -> {
            if (appUserId != null)
                sysNoticeService.insertNoticeToUser(appUserId, noticeContent, SysNoticeTitleRouteEnum.DANGER);
        });

        return AjaxResult.success(updateDangerForApp(dangerDTO, true));
    }

    @Override
    public AjaxResult checkDangerManage(DangerDTO dangerDTO) {
        //判断权限，验收人是否是区域负责人
//        String userId = JWTUtil.getUserId();
        String userId = JWTUtil.getPCUserId();
        DangerResultDTO dangerResultDTO = selectDangerById(dangerDTO.getId());
        if (Objects.isNull(dangerResultDTO)) {
            return AjaxResult.error("隐患信息不存在！");
        }
        if (!dangerResultDTO.getDangerStatus().equals(DangerStatusEnum.WAIT_FOR_ACCEPTANCE.getValue())) {
            return AjaxResult.error("隐患非待验收状态！");
        }
        //根据区域ID查询岗位下的用户集合
        List<TbSysAreaUser> sysUsers = tbSysAreaMapper.selectUserNickNameByAreaIdList(Arrays.asList(dangerResultDTO.getAreaId()));
        Set<Long> areaUserIdSet = sysUsers.parallelStream().map(TbSysAreaUser::getUserId).distinct().collect(Collectors.toSet());
        //判断是否是区域负责人
        if (!areaUserIdSet.contains(Long.parseLong(userId))) {
            return AjaxResult.error("该用户无验收权限");
        }

//        QueryWrapper<TbSysAreaUserRelation> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("area_id", dangerResultDTO.getAreaId());
//        queryWrapper.eq("user_id", userId);
//        List<TbSysAreaUserRelation> sysAreaUserRelations = tbSysAreaUserRelationMapper.selectList(queryWrapper);
        //判断是否是区域负责人
//        if (CollectionUtils.isEmpty(sysAreaUserRelations)) {
//            return AjaxResult.error("该用户无验收权限");
//        }
        //驳回信息
        if (!DangerStatusEnum.COMPLETED.getValue().equals(dangerDTO.getDangerStatus())) {
//            dangerDTO.setRejectReason(dangerDTO.getRemarkInfo());   验收情况描述存在这里：checkAcceptComment
//            dangerDTO.setRejectUserId(Long.parseLong(JWTUtil.getPCUserId()));
            SysUser sysUser = sysUserService.selectUserById(Long.parseLong(JWTUtil.getPCUserId()));
            dangerDTO.setRejectUserName(sysUser != null ? sysUser.getNickName() : null);

            //4、验收不通过时返回到整改中：给整改负责人（认领人）发消息 -> 单据号：xxxx的隐患验收不合格，请及时确认！
            String noticeContent = "单据号：" + dangerResultDTO.getDangerNo() + "的隐患验收不合格，请及时确认！";
            //查整改负责人
            Long manageUserId = dangerResultDTO.getManageUserId();
            AppLogin appLogin = appLoginService.selectAppLoginByUserId(manageUserId);
            if (!Objects.isNull(appLogin)) {
                //发消息
                sysNoticeService.insertNoticeToUser(appLogin.getId(), noticeContent, SysNoticeTitleRouteEnum.DANGER);
            }
        }
        return AjaxResult.success(updateDangerForApp(dangerDTO, true));
    }

    /**
     * APP首页统计-隐患排查
     *
     * @return
     */
    @Override
    public DangerStatisticsDTO dangerStatistics() {
        DangerStatisticsDTO dto = dangerMapper.dangerStatistics();
        if (dto == null) {
            dto = new DangerStatisticsDTO();
        } else {
            //计算完成比例整数     completeRatio
            //整改率（保留整数向上取整）：(已完成 + 已关闭)/ 总数
            Integer completedCount = dto.getCompletedCount();
            Integer canceledCount = dto.getCanceledCount();
            Integer dangerTotal = dto.getDangerTotal();

            BigDecimal completedCountBig = new BigDecimal(completedCount + canceledCount);
            BigDecimal dangerTotalBig = new BigDecimal(dangerTotal);
            //保留两位小数向上取整
            BigDecimal completeRatioBig = completedCountBig.divide(dangerTotalBig, 2, BigDecimal.ROUND_UP);

            // 按照整数位向上取整
            int completeRatio = completeRatioBig.multiply(new BigDecimal(100)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
            dto.setCompleteRatio(completeRatio);
        }


        return dto;
    }

    /**
     * PC首页统计-双重预防机制
     *
     * @param endDate 今天的0点0分的时间
     * @return
     */
    @Override
    public DangerStatisticsPCDTO dangerStatisticsPC(Date endDate) {
        return dangerMapper.dangerStatisticsPC(endDate);
    }

}
