package cn.iocoder.yudao.module.pms.service.qhse.accident;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.accident.vo.IotAccidentReportPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.qhse.accident.vo.IotAccidentReportSaveReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.stat.DeptUtil;
import cn.iocoder.yudao.module.pms.dal.dataobject.qhse.accident.IotAccidentReportDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.qhse.accident.IotAccidentReportProcessDO;
import cn.iocoder.yudao.module.pms.dal.mysql.qhse.accident.IotAccidentReportMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.qhse.accident.IotAccidentReportProcessMapper;
import cn.iocoder.yudao.module.pms.message.PmsMessage;
import cn.iocoder.yudao.module.pms.service.IotDeviceService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.PostApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * QHSE事故上报 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class IotAccidentReportServiceImpl implements IotAccidentReportService {

    @Resource
    private IotAccidentReportMapper iotAccidentReportMapper;
    @Autowired
    private DeptApi deptApi;
    @Autowired
    private AdminUserApi adminUserApi;
    @Autowired
    private RoleApi roleApi;
    @Autowired
    private DeptService deptService;
    @Autowired
    private PostApi postApi;
    @Autowired
    private IotAccidentReportProcessMapper iotAccidentReportProcessMapper;
    @Resource
    private BpmProcessInstanceApi processInstanceApi;
    @Autowired
    private PmsMessage pmsMessage;
    @Autowired
    private IotDeviceService iotDeviceService;
    @Autowired
    private DeptUtil deptUtil;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approvalAccident(Long id, String suggestion) {
        IotAccidentReportDO iotAccidentReportDO = iotAccidentReportMapper.selectById(id);
        assert Objects.nonNull(iotAccidentReportDO);
        IotAccidentReportProcessDO processDO = new IotAccidentReportProcessDO();
        processDO.setAccidentId(id);
        processDO.setOperator(SecurityFrameworkUtils.getLoginUserNickname());
        processDO.setDescription(suggestion);
        processDO.setStatus("上报");
        processDO.setDeleted(false);
        Set<Long> deptIds = getDeptIdCompany(iotAccidentReportDO.getDeptId());
        List<AdminUserRespDTO> users = adminUserApi.getUserListByDeptIdsNew(deptIds);
        if ("2".equals(iotAccidentReportDO.getFlowStatus())) {//项目经理操作的
            processDO.setNodeName("项目经理");
            iotAccidentReportDO.setFlowStatus("3");
            PostRespDTO bz = postApi.getPostByName("QHSE部长");
            Long postId = bz.getId();
            users.stream().filter(e -> e.getPostIds().contains(postId)).findFirst().ifPresent(f ->{
                //设置当前操作人为QHSE部长
                iotAccidentReportDO.setCurrentPerson(Collections.singleton(f.getId()));
            });
        } else if ("3".equals(iotAccidentReportDO.getFlowStatus())){//QHSE部长操作的
            processDO.setNodeName("公司QHSE部长");
            iotAccidentReportDO.setFlowStatus("4");
            PostRespDTO bz = postApi.getPostByName("总经理");
            Long postId = bz.getId();
            boolean b = users.stream().anyMatch(e -> e.getPostIds().contains(postId));
            if (!b) {
                throw new ServiceException(new ErrorCode(1,"未找到总经理岗位"));
            }
            users.stream().filter(e -> e.getPostIds().contains(postId)).findFirst().ifPresent(f->{
                iotAccidentReportDO.setCurrentPerson(ImmutableSet.of(f.getId(), 873L));
            });
        } else if ("4".equals(iotAccidentReportDO.getFlowStatus())) {//总经理或者集团QHSE副总监操作的
            Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
            if (Objects.nonNull(loginUserId) && loginUserId==873L) {//如果集团QHSE副总监
                processDO.setNodeName("集团QHSE副总监");
            } else {
                processDO.setNodeName("总经理");
            }
            iotAccidentReportDO.setFlowStatus("5");
            iotAccidentReportDO.setStatus("finished");
            PostRespDTO zz = postApi.getPostByName("总裁");
            Long postId = zz.getId();
            List<AdminUserRespDTO> allUser = adminUserApi.getUserListByPostIdsNoPermission(Collections.singleton(postId));
            if (CollUtil.isEmpty(allUser)){
                throw new ServiceException(new ErrorCode(2,"未找到审批岗位"));
            }
            allUser.stream().filter(e -> e.getPostIds().contains(postId)).findFirst().ifPresent(f ->{
                iotAccidentReportDO.setCurrentPerson(ImmutableSet.of(f.getId()));
            });
        }
        iotAccidentReportProcessMapper.insert(processDO);

        iotAccidentReportMapper.updateById(iotAccidentReportDO);

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approvalAccidentFlow(Long id, Integer bpmResult) {
//        IotAccidentReportDO iotAccidentReportDO = iotAccidentReportMapper.selectById(id);
//        if (iotAccidentReportDO == null) {throw new ServiceException(new ErrorCode(111,"不存在事故上报信息"));}
//        if(bpmResult ==2 ){
//            iotAccidentReportDO.setStatus("finished");
//            iotAccidentReportMapper.updateById(iotAccidentReportDO);
//        }
    }

    public Set<Long> getDeptIdCompany(Long deviceDept) {
        List<DeptRespDTO> rhdept = deptApi.getDeptByNamePermission("瑞恒兴域");
        Set<Long> rhDeptIds = Collections.emptySet();
        if (CollUtil.isNotEmpty(rhdept)) {
            Long deptId = rhdept.get(0).getId();
            rhDeptIds = deptService.getChildDeptIdListFromCache(deptId);
            rhDeptIds.add(deptId);
        }

        List<DeptRespDTO> rddept = deptApi.getDeptByNamePermission("四川瑞都");
        Set<Long> rdDeptIds = Collections.emptySet();
        if (CollUtil.isNotEmpty(rddept)) {
            Long deptId = rddept.get(0).getId();
            rdDeptIds = deptService.getChildDeptIdListFromCache(deptId);
            rdDeptIds.add(deptId);
        }

        List<DeptRespDTO> rydept = deptApi.getDeptByNamePermission("瑞鹰国际");
        Set<Long> ryDeptIds = Collections.emptySet();
        if (CollUtil.isNotEmpty(rydept)) {
            Long deptId = rydept.get(0).getId();
            ryDeptIds = deptService.getChildDeptIdListFromCache(deptId);
            ryDeptIds.add(deptId);
        }

        if (rhDeptIds.contains(deviceDept)) {
            return rhDeptIds;
        } else if (rdDeptIds.contains(deviceDept)) {
            return rdDeptIds;
        } else {
            return ryDeptIds;
        }
    }

    @Override
    public Long createIotAccidentReport(IotAccidentReportSaveReqVO createReqVO) {
        // 插入
        IotAccidentReportDO iotAccidentReport = BeanUtils.toBean(createReqVO, IotAccidentReportDO.class);
        Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
        iotAccidentReport.setDeptId(loginUserDeptId);
        DeptRespDTO dept = deptApi.getDept(loginUserDeptId);
        if (Objects.nonNull(dept)){
            iotAccidentReport.setDeptName(dept.getName());
        }
        //设置状态为上报中
//        iotAccidentReport.setStatus("reporting");
        //查找上一级的项目主管
        iotAccidentReport.setDeleted(false);
//        iotAccidentReport.setFlowStatus("2");
        //获取当前部门的上一级部门也就是项目部的项目经理
//        Long parentId = dept.getParentId();
//        List<AdminUserRespDTO> parentDeptUsers = adminUserApi.getUserListByDeptIdsNew(Collections.singleton(parentId));
//        List<Long> projectUserIds = roleApi.getRoleUserIds("项目经理");
//        Set<Long> currentUserIds = parentDeptUsers.stream().map(AdminUserRespDTO::getId)
//                .filter(projectUserIds::contains)
//                .collect(Collectors.toSet());
//        if (CollUtil.isEmpty(currentUserIds)){
//            throw new ServiceException(new ErrorCode(22,"未找到项目经理，无法完成事故上报"));
//        }
//        iotAccidentReport.setCurrentPerson(Collections.singleton(currentUserIds.stream().findFirst().get()));
        iotAccidentReportMapper.insert(iotAccidentReport);
//        //插入流程明细表
//        IotAccidentReportProcessDO processDO = new IotAccidentReportProcessDO();
//        processDO.setAccidentId(iotAccidentReport.getId());
//        String loginUserNickname = SecurityFrameworkUtils.getLoginUserNickname();
//        processDO.setOperator(loginUserNickname);
//        processDO.setDescription("发起事故事件上报");
//        processDO.setNodeName("发起人");
//        processDO.setDeleted(false);
//        processDO.setCreateTime(LocalDateTime.now());
//        processDO.setStatus("提交上报");
//        iotAccidentReportProcessMapper.insert(processDO);
//        String processInstanceId;
//        processInstanceId = processInstanceApi.createProcessInstance(SecurityFrameworkUtils.getLoginUserId(),
//                new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey("qhse-accident").setBusinessKey(String.valueOf(iotAccidentReport.getId())));
//
//        iotAccidentReportMapper.updateById(new IotAccidentReportDO().setId(iotAccidentReport.getId()).setProcessInstanceId(processInstanceId));
        //发送钉钉消息
        //pmsMessage.sendMessage(item.getId(), item.getCertName(), PmsConstants.GENERATE_QHSE_CERT, adminUserRespDTO.getId(), adminUserRespDTO.getMobile());
        String deptName;
        if (iotAccidentReport.getDeptName().contains("~~")) {
            String[] split = iotAccidentReport.getDeptName().split("~~");
            deptName = split[0];
        } else {
            deptName = iotAccidentReport.getDeptName();
        }
        //todo 发送公司总经理及QHSE总监、数智化首席运营及集团总裁
        PostRespDTO zjl = postApi.getPostByName("总经理");
        List<AdminUserRespDTO> userListByPostIds = adminUserApi.getUserListByPostIdsNoPermission(ImmutableList.of(zjl.getId()));
        userListByPostIds.stream().filter(e -> e.getDeptId().equals(iotAccidentReport.getDeptId())).findFirst().ifPresent(f ->{
            //总经理发送消息
            System.out.println("---------");
//            pmsMessage.sendMessage(iotAccidentReport.getId(), deptName+iotAccidentReport.getAccidentAddress()+"事故事件上报",PmsConstants.QHSE_ACCIDENT,f.getId(), f.getMobile());
        });
        ImmutableList<String> strings = ImmutableList.of("安全副总监", "数智化首席运营", "集团总裁");
        for (String string : strings) {
            PostRespDTO fzj = postApi.getPostByName(string);
            List<AdminUserRespDTO> fzjUsers = adminUserApi.getUserListByPostIdsNoPermission(ImmutableList.of(fzj.getId()));
            if (CollUtil.isNotEmpty(fzjUsers)) {
//                pmsMessage.sendMessage(iotAccidentReport.getId(), deptName+iotAccidentReport.getAccidentAddress()+"事故事件上报",PmsConstants.QHSE_ACCIDENT,fzjUsers.get(0).getId(), fzjUsers.get(0).getMobile());
            }
        }
        // 返回
        return iotAccidentReport.getId();
    }

    @Override
    public void updateIotAccidentReport(IotAccidentReportSaveReqVO updateReqVO) {
        // 校验存在
        validateIotAccidentReportExists(updateReqVO.getId());
        // 更新
        IotAccidentReportDO updateObj = BeanUtils.toBean(updateReqVO, IotAccidentReportDO.class);
        iotAccidentReportMapper.updateById(updateObj);
    }

    @Override
    public void deleteIotAccidentReport(Long id) {
        // 校验存在
        validateIotAccidentReportExists(id);
        // 删除
        iotAccidentReportMapper.deleteById(id);
    }

    private void validateIotAccidentReportExists(Long id) {
        if (iotAccidentReportMapper.selectById(id) == null) {
            throw exception(new ErrorCode(11,"不存在"));
        }
    }

    @Override
    public IotAccidentReportDO getIotAccidentReport(Long id) {
        return iotAccidentReportMapper.selectById(id);
    }

    @Override
    public PageResult<IotAccidentReportDO> getIotAccidentReportPage(IotAccidentReportPageReqVO pageReqVO) {
        Set<Long> ids = new HashSet<>();
        if (Objects.nonNull(pageReqVO.getDeptId())) {
            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
            ids.add(pageReqVO.getDeptId());
        }
        return iotAccidentReportMapper.selectPage(pageReqVO, ids);
    }

    @Override
    public PageResult<IotAccidentReportDO> getIotAccidentReportApprovalPage(IotAccidentReportPageReqVO pageReqVO) {
        return iotAccidentReportMapper.selectApprovalPage(pageReqVO);
    }
}