package com.bonus.material.work.service.impl;

import com.bonus.common.biz.domain.lease.WorkPeopleInfo;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.basic.domain.dto.SysUserRoleVo;
import com.bonus.material.basic.mapper.BmUserRoleMapper;
import com.bonus.material.ma.domain.DirectApplyInfo;
import com.bonus.material.work.domain.SysWorkflowConfig;
import com.bonus.material.work.domain.SysWorkflowNode;
import com.bonus.material.work.domain.SysWorkflowRecordHistory;
import com.bonus.material.work.mapper.DirectAuditMapper;
import com.bonus.material.work.mapper.SysWorkflowConfigMapper;
import com.bonus.material.work.mapper.SysWorkflowNodeMapper;
import com.bonus.material.work.mapper.SysWorkflowRecordHistoryMapper;
import com.bonus.material.work.service.SysWorkflowNodeService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service
public class SysWorkflowNodeServiceImpl implements SysWorkflowNodeService {

    @Resource
    private SysWorkflowNodeMapper sysWorkflowNodeMapper;

    @Resource
    private SysWorkflowConfigMapper sysWorkflowConfigMapper;

    @Resource
    private SysWorkflowRecordHistoryMapper sysWorkflowRecordHistoryMapper;

    @Resource
    private BmUserRoleMapper bmUserRoleMapper;

    @Resource
    private DirectAuditMapper directAuditMapper;

    /**
     * 工作流详情列表
     */
    @Override
    public List<SysWorkflowNode> selectSysWorkflowNodeList(SysWorkflowNode sysWorkflowNode) {
        return sysWorkflowNodeMapper.selectSysWorkflowNodeList(sysWorkflowNode);
    }

    /**
     * 新增工作流详情
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addSysWorkflowNode(SysWorkflowNode sysWorkflowNode) {
        //保存创建人信息
        sysWorkflowNode.setCreateBy(SecurityUtils.getLoginUser().getUserid().toString());
        //保存创建时间
        sysWorkflowNode.setCreateTime(DateUtils.getNowDate());

        if (sysWorkflowNode.getConfigValues().isEmpty()){
            throw new ServiceException("请选择审核人员");
        }
        int count = sysWorkflowNodeMapper.addSysWorkflowNode(sysWorkflowNode);
        SysWorkflowConfig sysWorkflowConfig = new SysWorkflowConfig();
        sysWorkflowConfig.setNodeId(sysWorkflowNode.getId());
        sysWorkflowConfig.setConfigType(sysWorkflowNode.getNodeSignConfig());
        sysWorkflowConfig.setConfigValue(sysWorkflowNode.getConfigValues());
        if (sysWorkflowNode.getNodeSignConfig()==0){
            sysWorkflowConfig.setRoleIds(sysWorkflowNode.getRoleIds());
        }
        //新增审核详情表信息
        sysWorkflowConfigMapper.addSysWorkflowConfig(sysWorkflowConfig);
        return count;
    }


    /**
     * 删除工作流详情
     */
    @Override
    @Transactional
    public int deleteSysWorkflowNode(SysWorkflowNode sysWorkflowNode) {
        SysWorkflowConfig sysWorkflowConfig = new SysWorkflowConfig();
        sysWorkflowConfig.setNodeId(sysWorkflowNode.getId());
        sysWorkflowConfigMapper.deleteSysWorkflowConfig(sysWorkflowConfig);
        int count = sysWorkflowNodeMapper.deleteSysWorkflowNode(sysWorkflowNode);
        return count;
    }

    /**
     * 修改工作流详情
     */
    @Override
    @Transactional
    public int updateSysWorkflowNode(SysWorkflowNode sysWorkflowNode) {
        int count = sysWorkflowNodeMapper.updateSysWorkflowNode(sysWorkflowNode);
        if (sysWorkflowNode.getConfigValues().isEmpty()){
            throw new ServiceException("请选择审核人员");
        }
        SysWorkflowConfig sysWorkflowConfig = new SysWorkflowConfig();
        sysWorkflowConfig.setNodeId(sysWorkflowNode.getId());
        sysWorkflowConfigMapper.deleteSysWorkflowConfig(sysWorkflowConfig);
        sysWorkflowConfig.setNodeId(sysWorkflowNode.getId());
        sysWorkflowConfig.setConfigType(sysWorkflowNode.getNodeSignConfig());
        sysWorkflowConfig.setConfigValue(sysWorkflowNode.getConfigValues());
        if (sysWorkflowNode.getNodeSignConfig()==0){
            sysWorkflowConfig.setRoleIds(sysWorkflowNode.getRoleIds());
        }
        //新增审核详情表信息
        sysWorkflowConfigMapper.addSysWorkflowConfig(sysWorkflowConfig);
        return count;
    }

    @Override
    public List<SysWorkflowNode> listByTaskId(SysWorkflowNode sysWorkflowNode) {
        Long userId = SecurityUtils.getLoginUser().getUserid();
        List<SysWorkflowNode> sysWorkflowNodeList = sysWorkflowNodeMapper.listByTaskId(sysWorkflowNode);
        for (SysWorkflowNode forSysWorkflowNode : sysWorkflowNodeList) {
            // 传入节点信息，自动处理节点配置角色相关的处理
            copeNodeConfigPersonValuesByNode(forSysWorkflowNode);

            SysWorkflowRecordHistory sysWorkflowRecordHistory = new SysWorkflowRecordHistory();
            sysWorkflowRecordHistory.setRecordId(forSysWorkflowNode.getRecordId());
            sysWorkflowRecordHistory.setNodeId(forSysWorkflowNode.getNodeId());
            List<SysWorkflowRecordHistory> sysWorkflowRecordHistoryList = sysWorkflowRecordHistoryMapper.seleteSysWorkflowRecordHistory(sysWorkflowRecordHistory);
            if (!sysWorkflowRecordHistoryList.isEmpty()) {
                //判断是或签还是会签0:或签  1:会签
                if (0 == forSysWorkflowNode.getNodeSignType()) {
                    forSysWorkflowNode.setIsAccept(sysWorkflowRecordHistoryList.get(0).getIsAccept());
                    forSysWorkflowNode.setCreateTime(sysWorkflowRecordHistoryList.get(0).getCreateTime());
                    forSysWorkflowNode.setRemark(sysWorkflowRecordHistoryList.get(0).getRemark());
                    forSysWorkflowNode.setAuditBy(sysWorkflowRecordHistoryList.get(0).getAuditBy());
                } else {
                    String[] configValue =  forSysWorkflowNode.getConfigValues().split(",");
                    List<String> filteredList = Arrays.stream(configValue).collect(Collectors.toList());
                    // 过滤数组元素
                    for (SysWorkflowRecordHistory sysWorkflowRecordHistoryNew : sysWorkflowRecordHistoryList) {
                        // 过滤数组元素
                        filteredList = filteredList.stream()
                                .filter(value ->value != null && !value.equals(sysWorkflowRecordHistoryNew.getCreateBy()))
                                .collect(Collectors.toList());
                        }
                    //获取所有的审核状态
                    List<Integer> isAcceptList =sysWorkflowRecordHistoryList.stream()
                            .map(SysWorkflowRecordHistory::getIsAccept)
                            .collect(Collectors.toList());
                    //判断是否有人是驳回
                    if (isAcceptList.contains(2)) {
                        //获取驳回信息
                        List<SysWorkflowRecordHistory> sysWorkflowRecordHistoryListNew = sysWorkflowRecordHistoryList.stream()
                                .filter(value ->value != null && 2 == (value.getIsAccept()))
                                .collect(Collectors.toList());
                        forSysWorkflowNode.setIsAccept(sysWorkflowRecordHistoryListNew.get(0).getIsAccept());
                        forSysWorkflowNode.setCreateTime(sysWorkflowRecordHistoryListNew.get(0).getCreateTime());
                        forSysWorkflowNode.setRemark(sysWorkflowRecordHistoryListNew.get(0).getRemark());
                        forSysWorkflowNode.setAuditBy(sysWorkflowRecordHistoryListNew.get(0).getAuditBy());
                    } else {
                        // 获取当前人的审核信息
                        List<SysWorkflowRecordHistory>  sysWorkflowRecordHistoryListNew = sysWorkflowRecordHistoryList.stream()
                                .filter(value -> value != null && userId.toString().equals(value.getCreateBy()))
                                .collect(Collectors.toList());
                        // 判断当前人是否是这个节点的审核人
                        if (!sysWorkflowRecordHistoryListNew.isEmpty()) {
                            forSysWorkflowNode.setIsAccept(sysWorkflowRecordHistoryListNew.get(0).getIsAccept());
                            forSysWorkflowNode.setCreateTime(sysWorkflowRecordHistoryListNew.get(0).getCreateTime());
                            forSysWorkflowNode.setRemark(sysWorkflowRecordHistoryListNew.get(0).getRemark());
                            forSysWorkflowNode.setAuditBy(sysWorkflowRecordHistoryListNew.get(0).getAuditBy());
                        } else {
                            forSysWorkflowNode.setIsAccept(sysWorkflowRecordHistoryList.get(0).getIsAccept());
                            forSysWorkflowNode.setCreateTime(sysWorkflowRecordHistoryList.get(0).getCreateTime());
                            forSysWorkflowNode.setRemark(sysWorkflowRecordHistoryList.get(0).getRemark());
                            forSysWorkflowNode.setAuditBy(sysWorkflowRecordHistoryList.get(0).getAuditBy());
                        }
                    }
                }
            }
        }
        return sysWorkflowNodeList;
    }

    /**
     * 根据传入的节点配置，去自动判断是否配置角色，如果是角色 那么自动查询并赋值进入节点的configValues字段
     * @param forSysWorkflowNode 节点信息
     */
    @Override
    public void copeNodeConfigPersonValuesByNode(SysWorkflowNode forSysWorkflowNode) {
        if (forSysWorkflowNode == null) {
            System.err.println("传入的节点信息为空！");
            return;
        }
        try {
            // 判断配置的类型
            if (forSysWorkflowNode.getConfigType() == null || forSysWorkflowNode.getConfigType() == 0) {
                // 如果配置的是角色，那么要根据角色id去查询有哪些用户
                String roleIds = forSysWorkflowNode.getRoleIds();
                // 如果参数没有，那么就从数据库中查询
                if (roleIds == null || roleIds.isEmpty()) {
                    System.out.println("节点配置角色为空！去再执行数据库查询");
                    roleIds = sysWorkflowConfigMapper.selectRolesByNodeId(forSysWorkflowNode.getNodeId());
                }
                if (roleIds != null && !roleIds.isEmpty()) {
                    StringBuilder roleConfigValues = new StringBuilder();
                    String[] roleIdArray = roleIds.split(",");
                    for (String forRoleId : roleIdArray) {
                        List<SysUserRoleVo> userList = bmUserRoleMapper.getUserRoleListByDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId(), Long.valueOf(forRoleId));
                        if (!userList.isEmpty()) {
                            // 如果不是第一次拼接，先添加逗号分隔
                            if (roleConfigValues.length() > 0) {
                                roleConfigValues.append(",");
                            }
                            roleConfigValues.append(userList.stream().map(user -> String.valueOf(user.getUserId())).collect(Collectors.joining(",")));
                        }
                    }
                    forSysWorkflowNode.setConfigValues(roleConfigValues.toString());
                } else {
                    System.err.println("节点配置角色为空！请检查参数");
                }
            } else {
                System.err.println("节点配置类型为:" + forSysWorkflowNode.getConfigType() + ",方法不进行处理！请检查参数");
            }
        } catch (NumberFormatException e) {
            System.err.println("执行审核流配置角色处理方法时发生异常：" + e.getMessage());
        }
    }

    @Override
    public void copeNodeConfigPersonValuesByNodeTwo(SysWorkflowNode forSysWorkflowNode, DirectApplyInfo directApplyInfo,List<WorkPeopleInfo> userList,int num) {
        if (forSysWorkflowNode == null) {
            System.err.println("传入的节点信息为空！");
            return;
        }
        try {
            // 判断配置的类型
            if (forSysWorkflowNode.getConfigType() == null || forSysWorkflowNode.getConfigType() == 0) {
                // 如果配置的是角色，那么要根据角色id去查询有哪些用户
                String roleIds = forSysWorkflowNode.getNextRoleIds();
                // 如果参数没有，那么就从数据库中查询
                if (roleIds == null || roleIds.isEmpty()) {
                    System.out.println("节点配置角色为空！去再执行数据库查询");
                    roleIds = sysWorkflowConfigMapper.selectRolesByNodeId(forSysWorkflowNode.getNodeId());
                }
                if (roleIds != null && !roleIds.isEmpty()) {
                    StringBuilder roleConfigValues = new StringBuilder();
                    String[] roleIdArray = roleIds.split(",");
                    for (String forRoleId : roleIdArray) {
                        if(forSysWorkflowNode.getNodeName().contains("接收方材料员审核")){
                            //根据project_id获取external_id
                            String externalId = directAuditMapper.getExternalId(Integer.parseInt(directApplyInfo.getLeaseProId()));
                            if (externalId != null && !externalId.isEmpty()) {
                                //获取项目总工id
                                String leaderId = directAuditMapper.getLeaderId(externalId);
                                if(leaderId != null && !leaderId.isEmpty()){
                                    //获取项目总工账号
                                    String leaderAccount = directAuditMapper.getUserNameById(leaderId);
                                    if(leaderAccount != null && !leaderAccount.isEmpty()){
                                        userList.addAll(directAuditMapper.getUserIdByUserName(leaderAccount));
                                    }
                                }else{
                                    throw new RuntimeException("项目总工不存在");
                                }
                            }else{
                                throw new RuntimeException("未找到所属工程");
                            }
                        }else if(forSysWorkflowNode.getNodeName().contains("所属施工管理科审核") && num==6){
                            //根据project_id获取external_id
                            String externalId = directAuditMapper.getExternalId(Integer.parseInt(directApplyInfo.getLeaseProId()));
                            if (externalId != null && !externalId.isEmpty()) {
                                userList.addAll(directAuditMapper.getUserIdByExternalId(externalId));
                            }else{
                                throw new RuntimeException("未找到所属工程");
                            }
                        }else{
                            userList.addAll(bmUserRoleMapper.getUserListByDeptId(Long.valueOf(directApplyInfo.getDeptId()), Long.valueOf(forRoleId)));
                        }
                        //去重
                        Set<Long> seenUserIds = new HashSet<>();
                        userList.removeIf(info -> {
                            Long userId = info.getUserId();
                            return userId == null || !seenUserIds.add(userId); // 若userId已存在则移除当前元素
                        });
                        if (!userList.isEmpty()) {
                            for(WorkPeopleInfo info:userList){
                                String userId = String.valueOf(info.getUserId());
                                if(!roleConfigValues.toString().contains(userId)){
                                    // 如果不是第一次拼接，先添加逗号分隔
                                        roleConfigValues.append(info.getUserId());
                                        roleConfigValues.append(",");

                                }
                            }

                        }
                        if(roleConfigValues.length() > 0){
                            // 去除结尾的逗号
                            if (roleConfigValues.charAt(roleConfigValues.length() - 1) == ',') {
                                roleConfigValues.deleteCharAt(roleConfigValues.length() - 1);
                            }
                        }
                    }
                    forSysWorkflowNode.setConfigValues(roleConfigValues.toString());
                } else {
                    System.err.println("节点配置角色为空！请检查参数");
                }
            } else {
                System.err.println("节点配置类型为:" + forSysWorkflowNode.getConfigType() + ",方法不进行处理！请检查参数");
            }
        } catch (NumberFormatException e) {
            System.err.println("执行审核流配置角色处理方法时发生异常：" + e.getMessage());
        }
    }

    @Override
    public Map<Integer, SysWorkflowNode> listByProId(SysWorkflowNode sysWorkflowNode) {
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 获取工程下所有的任务id
        List<SysWorkflowNode> list = sysWorkflowNodeMapper.getTaskIdByProId(sysWorkflowNode);
        List<SysWorkflowNode> sysWorkflowNodeLists = new ArrayList<>();
        for (SysWorkflowNode workflowNode : list) {
            sysWorkflowNode.setTaskId(workflowNode.getTaskId());
            List<SysWorkflowNode> sysWorkflowNodeList = sysWorkflowNodeMapper.listByTaskId(sysWorkflowNode);
            if (sysWorkflowNodeList != null && !sysWorkflowNodeList.isEmpty()){
                sysWorkflowNodeLists.addAll(sysWorkflowNodeList);
            }
        }
        for (SysWorkflowNode forSysWorkflowNode : sysWorkflowNodeLists) {
            // 传入节点信息，自动处理节点配置角色相关的处理
            copeNodeConfigPersonValuesByNode(forSysWorkflowNode);

            SysWorkflowRecordHistory sysWorkflowRecordHistory = new SysWorkflowRecordHistory();
            sysWorkflowRecordHistory.setRecordId(forSysWorkflowNode.getRecordId());
            sysWorkflowRecordHistory.setNodeId(forSysWorkflowNode.getNodeId());
            List<SysWorkflowRecordHistory> sysWorkflowRecordHistoryList = sysWorkflowRecordHistoryMapper.seleteSysWorkflowRecordHistory(sysWorkflowRecordHistory);
            if (!sysWorkflowRecordHistoryList.isEmpty()) {
                //判断是或签还是会签0:或签  1:会签
                if (0 == forSysWorkflowNode.getNodeSignType()) {
                    forSysWorkflowNode.setIsAccept(sysWorkflowRecordHistoryList.get(0).getIsAccept());
                    forSysWorkflowNode.setCreateTime(sysWorkflowRecordHistoryList.get(0).getCreateTime());
                    forSysWorkflowNode.setRemark(sysWorkflowRecordHistoryList.get(0).getRemark());
                    forSysWorkflowNode.setAuditBy(sysWorkflowRecordHistoryList.get(0).getAuditBy());
                } else {
                    String[] configValue =  forSysWorkflowNode.getConfigValues().split(",");
                    List<String> filteredList = Arrays.stream(configValue).collect(Collectors.toList());
                    // 过滤数组元素
                    for (SysWorkflowRecordHistory sysWorkflowRecordHistoryNew : sysWorkflowRecordHistoryList) {
                        // 过滤数组元素
                        filteredList = filteredList.stream()
                                .filter(value ->value != null && !value.equals(sysWorkflowRecordHistoryNew.getCreateBy()))
                                .collect(Collectors.toList());
                    }
                    //获取所有的审核状态
                    List<Integer> isAcceptList =sysWorkflowRecordHistoryList.stream()
                            .map(SysWorkflowRecordHistory::getIsAccept)
                            .collect(Collectors.toList());
                    //判断是否有人是驳回
                    if (isAcceptList.contains(2)) {
                        //获取驳回信息
                        List<SysWorkflowRecordHistory> sysWorkflowRecordHistoryListNew = sysWorkflowRecordHistoryList.stream()
                                .filter(value ->value != null && 2 == (value.getIsAccept()))
                                .collect(Collectors.toList());
                        forSysWorkflowNode.setIsAccept(sysWorkflowRecordHistoryListNew.get(0).getIsAccept());
                        forSysWorkflowNode.setCreateTime(sysWorkflowRecordHistoryListNew.get(0).getCreateTime());
                        forSysWorkflowNode.setRemark(sysWorkflowRecordHistoryListNew.get(0).getRemark());
                        forSysWorkflowNode.setAuditBy(sysWorkflowRecordHistoryListNew.get(0).getAuditBy());
                    } else {
                        // 获取当前人的审核信息
                        List<SysWorkflowRecordHistory>  sysWorkflowRecordHistoryListNew = sysWorkflowRecordHistoryList.stream()
                                .filter(value -> value != null && userId.toString().equals(value.getCreateBy()))
                                .collect(Collectors.toList());
                        // 判断当前人是否是这个节点的审核人
                        if (!sysWorkflowRecordHistoryListNew.isEmpty()) {
                            forSysWorkflowNode.setIsAccept(sysWorkflowRecordHistoryListNew.get(0).getIsAccept());
                            forSysWorkflowNode.setCreateTime(sysWorkflowRecordHistoryListNew.get(0).getCreateTime());
                            forSysWorkflowNode.setRemark(sysWorkflowRecordHistoryListNew.get(0).getRemark());
                            forSysWorkflowNode.setAuditBy(sysWorkflowRecordHistoryListNew.get(0).getAuditBy());
                        } else {
                            forSysWorkflowNode.setIsAccept(sysWorkflowRecordHistoryList.get(0).getIsAccept());
                            forSysWorkflowNode.setCreateTime(sysWorkflowRecordHistoryList.get(0).getCreateTime());
                            forSysWorkflowNode.setRemark(sysWorkflowRecordHistoryList.get(0).getRemark());
                            forSysWorkflowNode.setAuditBy(sysWorkflowRecordHistoryList.get(0).getAuditBy());
                        }
                    }
                }
            }
        }
        Map<Integer, SysWorkflowNode> resultMap = IntStream.range(0, sysWorkflowNodeLists.size())
                .boxed()
                .collect(Collectors.toMap(
                        i -> i + 1,
                        i -> sysWorkflowNodeLists.get(i)
                ));
        return resultMap;
    }
}
