package org.dromara.wflow.workflow.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.dromara.biz.domain.BizTask;
import org.dromara.biz.domain.BizTaskFeedback;
import org.dromara.biz.domain.BizTaskWork;
import org.dromara.biz.domain.bo.BizTaskBo;
import org.dromara.biz.domain.bo.BizTaskFeedbackBo;
import org.dromara.biz.domain.vo.ActHiProcinstVo;
import org.dromara.biz.domain.vo.ActRuTaskVo;
import org.dromara.biz.domain.vo.BizTaskFeedbackVo;
import org.dromara.biz.mapper.*;
import org.dromara.biz.service.IBizTaskLogService;
import org.dromara.biz.service.IBizTaskService;
import org.dromara.biz.service.IBizTaskWorkService;
import org.dromara.common.core.constant.WflowContants;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysRole;
import org.dromara.system.mapper.SysRoleMapper;
import org.dromara.system.mapper.SysUserRoleMapper;
import org.dromara.system.service.ISysDeptService;
import org.dromara.system.service.ISysUserService;
import org.dromara.wflow.bean.do_.UserDeptDo;
import org.dromara.wflow.bean.vo.UserVo;
import org.dromara.wflow.service.OrgRepositoryService;
import org.dromara.wflow.workflow.bean.process.OrgUser;
import org.dromara.wflow.workflow.bean.process.enums.BizTaskLogTypeEnum;
import org.dromara.wflow.workflow.bean.process.enums.ProcessResultEnum;
import org.dromara.wflow.workflow.bean.vo.ProcessHandlerParamsVo;
import org.dromara.wflow.workflow.bean.vo.ProcessProgressVo;
import org.dromara.wflow.workflow.bean.vo.ProcessTaskVo;
import org.dromara.wflow.workflow.bean.vo.RuansiMissionTaskVo;
import org.dromara.wflow.workflow.config.WflowGlobalVarDef;
import org.dromara.wflow.workflow.service.BusinessDataStorageService;
import org.dromara.wflow.workflow.service.ProcessInstanceService;
import org.dromara.wflow.workflow.service.RuansiMissionTaskService;
import org.dromara.wflow.workflow.utils.DeptIdUtil;
import org.dromara.wflow.workflow.utils.Executor;
import org.dromara.wflow.workflow.utils.FlowableUtils;
import org.flowable.engine.HistoryService;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class RuansiMissionTaskServiceImpl implements RuansiMissionTaskService {

    @Autowired
    private ProcessTaskServiceImpl processTaskService;

    @Autowired
    private ActRuTaskMapper actRuTaskMapper;

    @Autowired
    private ProcessInstanceService processInstanceService;

    @Autowired
    private ActHiProcinstMapper actHiProcinstMapper;

    @Autowired
    private OrgRepositoryService orgRepositoryService;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private BizTaskMapper bizTaskMapper;

    @Autowired
    private IBizTaskService bizTaskService;

    @Autowired
    private BizTaskWorkMapper bizTaskWorkMapper;

    @Autowired
    private IBizTaskLogService bizTaskLogService;

    @Autowired
    private BizTaskFeedbackMapper bizTaskFeedbackMapper;

    public static final String default_code = WflowContants.NORMAL_MISSION_DEFAULT_CODE;

    @Override
    public Page<ProcessTaskVo> getUserTodoList(Integer pageSize, Integer pageNo, String code, String[] startTimes, String keyword) {
        if (StringUtils.isBlank(code)) {
            code = default_code;
        }
        return processTaskService.getUserTodoList(pageSize, pageNo, code, startTimes, keyword);
    }

    @Override
    public TableDataInfo<RuansiMissionTaskVo> getUserTodoList2(Integer pageSize, Integer pageNo, List<Long> startUserIds, String code,
                                                               String[] startTimes, String taskType,
                                                               String title, String status, String deptId, String level) {
        Long userId = LoginHelper.getUserId();
        if (StringUtils.isNotBlank(deptId)) {
            deptId = DeptIdUtil.subDeptIdLastZero(deptId);
        }

        List<ActRuTaskVo> todoList = actRuTaskMapper.getTodoList(userId.toString(), code, startTimes, deptId);
        if (CollectionUtil.isEmpty(todoList)) {
            return TableDataInfo.build(Collections.emptyList());
        }
        // 获取流程实例id
        Set<String> instanceIds = todoList.stream().map(ActRuTaskVo::getProcInstId).collect(Collectors.toSet());
        Map<String, String> instanceIdAndTaskIdMap = todoList.stream().collect(Collectors.toMap(ActRuTaskVo::getProcInstId, ActRuTaskVo::getId));
        Map<String, Object> startDept = FlowableUtils.getProcessVars(instanceIds, WflowGlobalVarDef.START_DEPT);

        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageNum(pageNo);
        pageQuery.setPageSize(pageSize);
        Page<ActHiProcinstVo> historicProcessInstances = actHiProcinstMapper.selectMySubmmitedList(pageQuery.build(), userId, startUserIds, code, startTimes, title, taskType, WflowContants.NORMAL_MISSION_DEFAULT_TYPE_FIELD, WflowContants.NORMAL_MISSION_DEFAULT_TITLE_FIELD, null, instanceIds, null,WflowContants.NORMAL_MISSION_DEFAULT_LEVEL_FIELD, level);

        Page<RuansiMissionTaskVo> page = new Page<>();
        page.setTotal(historicProcessInstances.getTotal());
        page.setCurrent(pageNo);
        page.setSize(pageSize);

//        Map<String, Object> startDept = FlowableUtils.getProcessVars(instanceIds, WflowGlobalVarDef.START_DEPT);
        page.setRecords(getInstanceList(historicProcessInstances.getRecords(), startDept, instanceIdAndTaskIdMap));

        return TableDataInfo.build(page);
    }

    /**
     * 获取用户已处理列表
     *
     * @param pageSize
     * @param pageNum
     * @param startUserIds
     * @param code
     * @param startTimes
     * @param status
     * @param title
     * @param taskType
     * @param deptId
     * @return
     */
    @Override
    public TableDataInfo<RuansiMissionTaskVo> getUserITodoList(Integer pageSize, Integer pageNum, List<Long> startUserIds, String code, String[] startTimes, String status, String title, String taskType, String deptId, String level) {
        Long userId = LoginHelper.getUserId();
        if (StringUtils.isNotBlank(deptId)) {
            deptId = DeptIdUtil.subDeptIdLastZero(deptId);
        }
        HistoricTaskInstanceQuery query = historyService.createHistoricTaskInstanceQuery();
        Executor.builder().ifNotBlankNext(code, query::processDefinitionKey);
        query.taskAssignee(userId.toString()).finished().taskDefinitionKeyLike("node_%").orderByHistoricTaskInstanceEndTime().desc();
        List<HistoricTaskInstance> taskInstances = query.list();
        Set<String> instanceIds = taskInstances.stream().map(HistoricTaskInstance::getProcessInstanceId).collect(Collectors.toSet());
        // 获取流程实例id
//        Map<String, String> instanceIdAndTaskIdMap = taskInstances.stream().collect(Collectors.toMap(HistoricTaskInstance::getProcessInstanceId, HistoricTaskInstance::getId));
        Map<String, Object> startDept = FlowableUtils.getProcessVars(instanceIds, WflowGlobalVarDef.START_DEPT);
        if (CollectionUtil.isEmpty(instanceIds)) {
            return TableDataInfo.build(Collections.emptyList());
        }
        PageQuery pageQuery = new PageQuery();
        pageQuery.setPageNum(pageNum);
        pageQuery.setPageSize(pageSize);
        Page<ActHiProcinstVo> historicProcessInstances = actHiProcinstMapper.selectMySubmmitedList(
                pageQuery.build(), null, startUserIds, code, startTimes, title, taskType,
                WflowContants.NORMAL_MISSION_DEFAULT_TYPE_FIELD, WflowContants.NORMAL_MISSION_DEFAULT_TITLE_FIELD, null,
                instanceIds, deptId,WflowContants.NORMAL_MISSION_DEFAULT_LEVEL_FIELD, level);
        Page<RuansiMissionTaskVo> page = new Page<>();
        page.setTotal(historicProcessInstances.getTotal());
        page.setCurrent(pageNum);
        page.setSize(pageSize);
//        Map<String, Object> startDept = FlowableUtils.getProcessVars(instanceIds, WflowGlobalVarDef.START_DEPT);
        page.setRecords(getInstanceList(historicProcessInstances.getRecords(), startDept, null));
        return TableDataInfo.build(page);
    }

    /**
     * 设置返回实体
     *
     * @param records
     * @param startDept
     * @return
     */
    private List<RuansiMissionTaskVo> getInstanceList(List<ActHiProcinstVo> records, Map<String, Object> startDept, Map<String, String> instanceIdAndTaskIdMap) {
        Set<String> staterUsers = new HashSet<>();
        List<RuansiMissionTaskVo> objects = new ArrayList<>();

        for (ActHiProcinstVo instance : records) {
            String instanceId = instance.getId();
            //todo 优化方向，由循环获取改为根据instanceId批量获取，然后由本地循环赋值
            ProcessProgressVo instanceProgress = processInstanceService.getInstanceProgress(null, instanceId);
            RuansiMissionTaskVo ruansiMissionTaskVo = getRuansiVo(instanceProgress, instance);

//            Map<String, Object> processInstanceFormData = businessDataService.getProcessInstanceFormData(instanceId);
//            RuansiMissionTaskVo ruansiMissionTaskVo = getRuansiVo(processInstanceFormData,instance);
            if (CollectionUtil.isNotEmpty(instanceIdAndTaskIdMap)) {
                String taskId = instanceIdAndTaskIdMap.getOrDefault(instanceId, "");
                ruansiMissionTaskVo.setTaskId(taskId);
            }
            String deptId = String.valueOf(Optional.ofNullable(startDept.get(instanceId))
                    //如果没有就从流程变量 owner 里取（之前是存owner变量）
                    .orElseGet(() -> FlowableUtils.getOwnerDept(instanceId, true)));
            staterUsers.add(instance.getStartUserId() + "_" + deptId);
            ruansiMissionTaskVo.setOwerDeptId(deptId);

            objects.add(ruansiMissionTaskVo);
        }
        if (CollectionUtil.isNotEmpty(staterUsers)) {
            Map<String, UserDeptDo> infoMap = orgRepositoryService.getUserDeptInfos(staterUsers);
            objects.forEach(v -> {
                UserDeptDo userDeptDo = infoMap.get(v.getStartUser().getId() + "_" + v.getOwerDeptId());
                if (Objects.nonNull(userDeptDo)) {
                    /*v.setOwner(OrgUser.builder()
                            .name(userDeptDo.getUserName())
                            .avatar(userDeptDo.getAvatar())
                            .id(userDeptDo.getUserId())
                            .build());*/
                    v.setOwerDeptId(userDeptDo.getDeptId());
                    v.setOwerDeptName(userDeptDo.getDeptName());
                }
            });

        }
        return objects;
    }

    /**
     * 判断是否可编辑
     * @return
     */
    private boolean instanceCanEditable(ProcessProgressVo instanceProgress) {
        boolean editable = false;
        List<ProcessProgressVo.ProgressNode> progress = instanceProgress.getProgress();
        if (progress.size() <= 1) {
            return true;
        }
        ProcessProgressVo.ProgressNode progressNode = progress.get(progress.size() - 1);
        ProcessHandlerParamsVo.Action result = progressNode.getResult();
        String nodeId = progressNode.getNodeId();
        if(nodeId.equals("root")){
            editable = true;
        }

        if (Objects.isNull(progress.get(1).getResult())) {
            editable = true;
        }
        return editable;
    }

    private RuansiMissionTaskVo getRuansiVo(ProcessProgressVo instanceProgress, ActHiProcinstVo instance) {
        ProcessResultEnum processResult = ProcessResultEnum.resolveResult(instance.getEndActId());
        RuansiMissionTaskVo ruansiMissionTaskVo = new RuansiMissionTaskVo();
        ruansiMissionTaskVo.setInstanceId(instanceProgress.getInstanceId());
        Map<String, Object> formData = instanceProgress.getFormData();
        ruansiMissionTaskVo.setMissionTitle(String.valueOf(formData.get(WflowContants.NORMAL_MISSION_DEFAULT_TITLE_FIELD)));
        Object type = ((JSONArray) formData.get(WflowContants.NORMAL_MISSION_DEFAULT_TYPE_FIELD)).get(0);
        ruansiMissionTaskVo.setMissionTyle(String.valueOf(type));
        ruansiMissionTaskVo.setMissionLevel(String.valueOf(formData.get(WflowContants.NORMAL_MISSION_DEFAULT_LEVEL_FIELD)));
        ruansiMissionTaskVo.setStartTime(instanceProgress.getStartTime());
        ruansiMissionTaskVo.setMissionStatus(processResult.getDesc());
        ruansiMissionTaskVo.setStartUser(instanceProgress.getStaterUser());
        ruansiMissionTaskVo.setProcess(instanceProgress.getProgress());
        ruansiMissionTaskVo.setNodeId(instance.getProcDefKey());
        //判断是否可编辑
        boolean editable = instanceCanEditable(instanceProgress);
        ruansiMissionTaskVo.setEditable(editable);
        return ruansiMissionTaskVo;
    }

    @Override
    public TableDataInfo<BizTask> getToHandleList(Integer pageSize, Integer pageNum, String type, String applyUserName, String deptId, String title, String[] startTimes, String level) {
        Long userId = LoginHelper.getUserId();
        List<Long> roleIds = sysUserRoleMapper.selectRoleIdsByUserId(userId);
        LambdaQueryWrapper<SysRole> queryWrapper0 = new LambdaQueryWrapper<>();
        queryWrapper0.in(SysRole::getRoleId, roleIds);
        List<SysRole> sysRoleList = sysRoleMapper.selectList(queryWrapper0);
        if (ObjectUtil.isNotEmpty(sysRoleList)) {
            LambdaQueryWrapper<BizTask> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.ge(BizTask::getId, 0);
            if (ObjectUtil.isNotEmpty(type)) queryWrapper.eq(BizTask::getType, type);
            if (ObjectUtil.isNotEmpty(applyUserName))
                queryWrapper.and(wq -> wq.like(BizTask::getApplyUserId, applyUserName).or().like(BizTask::getApplyUserName, applyUserName));
            if (ObjectUtil.isNotEmpty(deptId))
                queryWrapper.in(BizTask::getApplyDeptId, sysDeptService.selectNormalChildrenDeptIdById(Long.valueOf(deptId)));
            if (ObjectUtil.isNotEmpty(title)) queryWrapper.like(BizTask::getTitle, title);
            if (ObjectUtil.isNotEmpty(startTimes))
                queryWrapper.ge(BizTask::getUpdateTime, startTimes[0]).le(BizTask::getUpdateTime, startTimes[1]);
            if (ObjectUtil.isNotEmpty(level))
                queryWrapper.eq(BizTask::getLevel, level);
            if (sysRoleList.size() == 1) {
                switch (sysRoleList.get(0).getRoleKey()) {
                    case "julingdao": // 局领导
                        break;
                    case "hezhanleader": // 合战中心领导
                        queryWrapper.last("and ((level = '普通任务' or level = '敏感任务') and (status = '30' or status= '51' or EXISTS (select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status = '3' and (t2.dept_id = " + LoginHelper.getDeptId() + " or t2.dept_id in (SELECT dept_id FROM sys_dept WHERE parent_id = " + LoginHelper.getDeptId() + "))))) order by create_time desc");
                        break;
                    case "hezhanzhongxin": // 合战中心民警
                        queryWrapper.last("and ( EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no  and t2.sponsor_id = " + userId + " and t2.status in ('1','2','3','5'))) order by create_time desc");
                        break;
                    case "qinzhizhongxin": // 情指中心
                        queryWrapper.last("and ((level = '指令任务' or level = '线索核查' or level = '特殊任务' or level = '情指任务') and (status = '30' or status= '51' or EXISTS (select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status = '3' and (t2.dept_id = " + LoginHelper.getDeptId() + " or t2.dept_id in (SELECT dept_id FROM sys_dept WHERE parent_id = " + LoginHelper.getDeptId() + "))))) order by create_time desc");
                        break;
                    case "leader": // 基层单位领导
                        queryWrapper.last("and EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status = '0' and (t2.dept_id = " + LoginHelper.getDeptId() + " or t2.dept_id in (SELECT dept_id FROM sys_dept WHERE parent_id = " + LoginHelper.getDeptId() + "))) order by create_time desc");
                        break;
                    case "normal": // 基层单位民警（普通角色）
                        queryWrapper.last("and ((apply_user_id = " + userId + " and instance_status = 'RUNNING' and status = '11') or ( EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no  and t2.sponsor_id = " + userId + " and t2.status in ('1','2','3','5')))) order by create_time desc");
                        break;
                }
            } else {
                List<String> roleKeyList = sysRoleList.stream().map(SysRole::getRoleKey).toList();
                StringBuilder s = new StringBuilder();
                if (!roleKeyList.contains("julingdao")){
                    for (String roleKey : roleKeyList) {
                        switch (roleKey) {
                            case "hezhanleader" -> // 合战中心领导
                                    s.append(" or ( ((level = '普通任务' or level = '敏感任务') and (status = '30' or status= '51' or EXISTS (select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status = '3' and (t2.dept_id = ").append(LoginHelper.getDeptId()).append(" or t2.dept_id in (SELECT dept_id FROM sys_dept WHERE parent_id = ").append(LoginHelper.getDeptId()).append(")))) ))");
                            case "hezhanzhongxin" -> // 合战中心民警
                                    s.append(" or ( ( EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no  and t2.sponsor_id = ").append(userId).append(" and t2.status in ('1','2','3','5'))) )");
                            case "qinzhizhongxin" -> // 情指中心
                                    s.append(" or ( ((level = '指令任务' or level = '线索核查' or level = '特殊任务' or level = '情指任务') and (status = '30' or status= '51' or EXISTS (select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status = '3' and (t2.dept_id = ").append(LoginHelper.getDeptId()).append(" or t2.dept_id in (SELECT dept_id FROM sys_dept WHERE parent_id = ").append(LoginHelper.getDeptId()).append("))))) )");
                            case "leader" -> // 基层单位领导
                                    s.append(" or ( EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status = '0' and (t2.dept_id = ").append(LoginHelper.getDeptId()).append(" or t2.dept_id in (SELECT dept_id FROM sys_dept WHERE parent_id = ").append(LoginHelper.getDeptId()).append("))) )");
                            case "normal" -> // 基层单位民警（普通角色）
                                    s.append(" or ( ((apply_user_id = ").append(userId).append(" and instance_status = 'RUNNING' and status = '11') or ( EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no  and t2.sponsor_id = ").append(userId).append(" and t2.status in ('1','2','3','5')))) )");
                        }
                    }
                    if (!s.isEmpty()){
//                        System.out.println("s ==========> " + s);
                        s = new StringBuilder(s.substring(4));
//                        System.out.println("s ----------> " + s);
                        queryWrapper.last(" and ( " + s + " ) order by create_time desc");
                    }
                }
            }
            Page<BizTask> bizTaskPage = bizTaskMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper);
            List<BizTask> records = bizTaskPage.getRecords();

            List<ActRuTaskVo> todoList = actRuTaskMapper.getTodoList(userId.toString(), default_code, startTimes, deptId);
            Map<String, String> instanceIdAndTaskIdMap = todoList.stream().collect(Collectors.toMap(ActRuTaskVo::getProcInstId, ActRuTaskVo::getId));

            for (BizTask record : records) {
                LambdaQueryWrapper<BizTaskWork> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(BizTaskWork::getTaskNo, record.getTaskNo());
                queryWrapper1.in(BizTaskWork::getDeptId, sysDeptService.selectNormalChildrenDeptIdById(LoginHelper.getDeptId()));
                List<BizTaskWork> bizTaskWorks = bizTaskWorkMapper.selectList(queryWrapper1);
                record.setBizTaskWorkList(bizTaskWorks);
                //node_id,task_id
                if (CollectionUtil.isNotEmpty(instanceIdAndTaskIdMap)) {
                    String taskId = instanceIdAndTaskIdMap.getOrDefault(record.getTaskNo(), "");
                    record.setTaskId(taskId);
                }
            }
            return TableDataInfo.build(bizTaskPage);
        }
        return TableDataInfo.build(new Page<>());
    }

    @Override
    public TableDataInfo<BizTask> alreadyHandledList(Integer pageSize, Integer pageNum, String type, String applyUserName, String deptId, String title, String[] startTimes, String level) {
        Long userId = LoginHelper.getUserId();
        List<Long> roleIds = sysUserRoleMapper.selectRoleIdsByUserId(userId);
        LambdaQueryWrapper<SysRole> queryWrapper0 = new LambdaQueryWrapper<>();
        queryWrapper0.in(SysRole::getRoleId, roleIds);
        List<SysRole> sysRoleList = sysRoleMapper.selectList(queryWrapper0);
        if (ObjectUtil.isNotEmpty(sysRoleList)) {
            LambdaQueryWrapper<BizTask> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.ge(BizTask::getId, 0);
            if (ObjectUtil.isNotEmpty(type)) queryWrapper.eq(BizTask::getType, type);
            if (ObjectUtil.isNotEmpty(applyUserName))
                queryWrapper.and(wq -> wq.like(BizTask::getApplyUserId, applyUserName).or().like(BizTask::getApplyUserName, applyUserName));
            if (ObjectUtil.isNotEmpty(deptId))
                queryWrapper.in(BizTask::getApplyDeptId, sysDeptService.selectNormalChildrenDeptIdById(Long.valueOf(deptId)));
            if (ObjectUtil.isNotEmpty(title)) queryWrapper.like(BizTask::getTitle, title);
            if (ObjectUtil.isNotEmpty(startTimes))
                queryWrapper.ge(BizTask::getUpdateTime, startTimes[0]).le(BizTask::getUpdateTime, startTimes[1]);
            if (ObjectUtil.isNotEmpty(level))
                queryWrapper.eq(BizTask::getLevel, level);
            if (sysRoleList.size() == 1) {
                switch (sysRoleList.get(0).getRoleKey()) {
                    case "julingdao": // 局领导
                        break;
                    case "hezhanleader": // 合战中心领导
                        queryWrapper.last("and ((level = '普通任务' or level = '敏感任务') and status > '30') order by create_time desc");
                        break;
                    case "hezhanzhongxin": // 合战中心民警
                        queryWrapper.last("and ( EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status > '1' and t2.sponsor_id = " + userId + " )) order by create_time desc");
                        break;
                    case "qinzhizhongxin": // 情指中心
                        queryWrapper.last("and ((level = '指令任务' or level = '线索核查' or level = '特殊任务' or level = '情指任务') and status > '30') order by create_time desc");
                        break;
                    case "leader": // 基层单位领导
                        queryWrapper.last(" and EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status > '0' and  (t2.dept_id = " + LoginHelper.getDeptId() + " or t2.dept_id in (SELECT dept_id FROM sys_dept WHERE parent_id = " + LoginHelper.getDeptId() + "))) order by create_time desc");
                        break;
                    case "normal": // 基层单位民警（普通角色）
                        queryWrapper.last("and ((level = '普通任务' and apply_user_id = " + userId + " and status > '11') or (EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status > '1' and t2.sponsor_id = " + userId + "))) order by create_time desc");
                        break;
                }
            } else {
                List<String> roleKeyList = sysRoleList.stream().map(SysRole::getRoleKey).toList();
                StringBuilder s = new StringBuilder();
                if (!roleKeyList.contains("julingdao")){
                    for (String roleKey : roleKeyList) {
                        switch (roleKey) {
                            case "hezhanleader" -> // 合战中心领导
                                    s.append("or ( ((level = '普通任务' or level = '敏感任务') and status > '30') )");
                            case "hezhanzhongxin" -> // 合战中心民警
                                    s.append(" or ( ( EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status > '1' and t2.sponsor_id = ").append(userId).append(")) )");
                            case "qinzhizhongxin" -> // 情指中心
                                    s.append(" or ( ((level = '指令任务' or level = '线索核查' or level = '特殊任务' or level = '情指任务') and status > '30') )");
                            case "leader" -> // 基层单位领导
                                    s.append(" or (  EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status > '0' and (t2.dept_id = ").append(LoginHelper.getDeptId()).append(" or t2.dept_id in (SELECT dept_id FROM sys_dept WHERE parent_id = ").append(LoginHelper.getDeptId()).append(")) ))");
                            case "normal" -> // 基层单位民警（普通角色）
                                    s.append(" or ( ((level = '普通任务' and apply_user_id = ").append(userId).append(" and status > '11') or ( EXISTS(select * from biz_task_work t2 WHERE biz_task.task_no = t2.task_no and t2.status > '1' and  t2.sponsor_id = ").append(userId).append("))) )");
                        }
                    }
                    if (!s.isEmpty()){
                        s = new StringBuilder(s.substring(4));
                        queryWrapper.last(" and ( " + s + " ) order by create_time desc");
                    }
                }
            }
            Page<BizTask> bizTaskPage = bizTaskMapper.selectPage(new Page<>(pageNum, pageSize), queryWrapper);
            List<BizTask> records = bizTaskPage.getRecords();
            for (BizTask record : records) {
                LambdaQueryWrapper<BizTaskWork> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(BizTaskWork::getTaskNo, record.getTaskNo());
                queryWrapper1.in(BizTaskWork::getDeptId, sysDeptService.selectNormalChildrenDeptIdById(LoginHelper.getDeptId()));
                List<BizTaskWork> bizTaskWorks = bizTaskWorkMapper.selectList(queryWrapper1);
                record.setBizTaskWorkList(bizTaskWorks);
            }
            return TableDataInfo.build(bizTaskPage);
        }
        return TableDataInfo.build(new Page<>());
    }

    @Override
    public boolean redo(BizTaskBo bizTaskBo) {
        LambdaUpdateWrapper<BizTask> updateWrapper = new LambdaUpdateWrapper<BizTask>();
        updateWrapper
                .eq(BizTask::getTaskNo, bizTaskBo.getTaskNo())
                .set(BizTask::getRedo, 1)
                .set(BizTask::getRedoReason, bizTaskBo.getRedoReason())
                .set(BizTask::getRedoTime, DateUtils.getNowDate())
                .set(BizTask::getUpdateTime, new Date())
                .set(BizTask::getStatus, WflowContants.BIZ_TASK_STATUS_TO_POLICE_FEEDBACK);
        int taskUpdateCount = bizTaskMapper.update(null, updateWrapper);
        LambdaUpdateWrapper<BizTaskWork> workUpdateWrapper = new LambdaUpdateWrapper<>();
        workUpdateWrapper
                .eq(BizTaskWork::getTaskNo, bizTaskBo.getTaskNo())
                .set(BizTaskWork::getStatus, WflowContants.BIZ_TASK_WORK_STATUS_TO_POLICE_FEEDBACK);
        int workUpdatedCount = bizTaskWorkMapper.update(null, workUpdateWrapper);
        Boolean save = bizTaskLogService.saveToBizTaskLog(bizTaskBo.getTaskNo(), LoginHelper.getUserId().toString(), BizTaskLogTypeEnum.REDO.getCode(), BizTaskLogTypeEnum.REDO.getDesc(), null, null);
        return taskUpdateCount > 0 && workUpdatedCount > 0 && save;
    }

    @Override
    public Map<String, Object> getBizTaskAndFeedbackByFeedbackId(BizTaskFeedbackBo bizTaskFeedbackBo) {
        Map<String, Object> resultMap = new HashMap<>();
        String taskNo = bizTaskFeedbackBo.getTaskNo();
        BizTask bizTask = bizTaskMapper.selectOne(new LambdaQueryWrapper<BizTask>().eq(BizTask::getTaskNo, taskNo));
        BizTaskFeedback bizTaskFeedback = bizTaskFeedbackMapper.selectById(bizTaskFeedbackBo.getId());
        BizTaskFeedbackVo bizTaskFeedbackVo = MapstructUtils.convert(bizTaskFeedback, BizTaskFeedbackVo.class);

        Long userId = bizTaskFeedback.getUserId();
        UserVo userDetail = orgRepositoryService.getUserDetail(String.valueOf(userId));
        if (userDetail != null){
            bizTaskFeedbackVo.setDeptId(userDetail.getDeptId());
            if(CollectionUtil.isNotEmpty(userDetail.getDepts())) {
                bizTaskFeedbackVo.setDeptName(userDetail.getDepts().get(0));
            }
        }
//        BizTaskWork bizTaskWork = bizTaskWorkMapper.selectById(bizTaskFeedback.getWorkId());
        resultMap.put("bizTask",bizTask);
//        resultMap.put("bizTaskWork",bizTaskWork);
        resultMap.put("bizTaskFeedback",bizTaskFeedbackVo);
        return resultMap;
    }

}
