package com.ankaibei.workFlow.webadmin.ankaibei.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ankaibei.workFlow.common.core.object.ResponseResult;
import com.ankaibei.workFlow.common.core.object.TokenData;
import com.ankaibei.workFlow.common.flow.constant.FlowConstant;
import com.ankaibei.workFlow.common.flow.constant.FlowTaskStatus;
import com.ankaibei.workFlow.common.flow.dto.FlowTaskCommentDto;
import com.ankaibei.workFlow.common.flow.model.FlowEntry;
import com.ankaibei.workFlow.common.flow.model.FlowEntryPublish;
import com.ankaibei.workFlow.webadmin.ankaibei.entity.ProjectInfoEntity;
import com.ankaibei.workFlow.webadmin.ankaibei.entity.TaskInfoEntity;
import com.ankaibei.workFlow.webadmin.ankaibei.entity.UserInfoEntity;
import com.ankaibei.workFlow.webadmin.ankaibei.enums.CodeEnum;
import com.ankaibei.workFlow.webadmin.ankaibei.mapper.ProjectInfoMapper;
import com.ankaibei.workFlow.webadmin.ankaibei.mapper.TaskInfoMapper;
import com.ankaibei.workFlow.webadmin.ankaibei.mapper.UserInfoMapper;
import com.ankaibei.workFlow.webadmin.ankaibei.service.TaskInfoService;
import com.ankaibei.workFlow.webadmin.ankaibei.utils.FlowTaskStart;
import com.ankaibei.workFlow.webadmin.ankaibei.vo.ResMsg;
import com.ankaibei.workFlow.webadmin.ankaibei.vo.TaskInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

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

/**
 * @author lwq
 * @version 1.0
 * @description:
 * @date 2022/9/14 17:19
 */
@Service
public class TaskInfoServiceImpl implements TaskInfoService {

    @Resource
    private TaskInfoMapper taskInfoMapper;
    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private ProjectInfoMapper projectInfoMapper;
    @Autowired
    private FlowTaskStart flowTaskStart;

    @Override
    public ResMsg findTaskInfo(Integer pageIndex, Integer pageSize, TaskInfoEntity taskInfoEntity) {
        Pageable page = PageRequest.of(pageIndex - 1, pageSize);
        Page<Map<String, String>> all = taskInfoMapper.findTaskInfo(taskInfoEntity.getTargetTask(), taskInfoEntity.getTaskStatus(), page);
        return new ResMsg(CodeEnum.OK, ResMsg.getMap(all.map(map -> {
            Map<Object, Object> map1 = new HashMap<>();
            map1.putAll(map);
            String projectId = map.get("projectId");
            Optional<ProjectInfoEntity> byId = projectInfoMapper.findById(Integer.valueOf(projectId));
            map1.put("projectId", byId.orElse(null) != null ? byId.orElse(null).getProjectName() : null);
            String taskParticipant = map.get("taskParticipant");
            String[] split = taskParticipant.split(",");
            List<String> list = new ArrayList<>();
            for (String userId : split) {
                list.add(String.valueOf(userId));
            }
            List<UserInfoEntity> allByUserId = userInfoMapper.findAllByUserId(list);
            StringBuffer str = new StringBuffer();
            for (UserInfoEntity name : allByUserId) {
                str.append(name.getShowName()).append(",");
            }
            map1.put("taskParticipant", str.toString());
            return map1;
        }).getContent(), all.getTotalElements()));
    }

    @Override
    public ResMsg addTaskInfo(TaskInfoEntity taskInfoEntity, List<Long> taskParticipant) {
        if (taskInfoMapper.countByTargetTaskEqualsAndIsDeleteEquals(taskInfoEntity.getTargetTask(), "1") > 1) {
            return new ResMsg(CodeEnum.TASK_ALREADY_EXISTS);
        }
        if (taskParticipant.size() < 1) {
            //（1 已分配 2未分配 3已延期）
            taskInfoEntity.setTaskStatus("2");
        } else {
            taskInfoEntity.setTaskStatus("1");
        }
        StringBuffer str = new StringBuffer();
        for (Long id : taskParticipant) {
            str.append(id).append(",");
        }
        taskInfoEntity.setTaskParticipant(str.toString());
        taskInfoEntity.setTaskCreator(taskInfoEntity.getTaskCreator());
        taskInfoEntity.setCreateDate(new Date());
        taskInfoEntity.setIsDelete("1");
        TaskInfoEntity save = taskInfoMapper.save(taskInfoEntity);

        /**
         *调用新增项目任务申请流程的启动
         *获取流程开始节点之后的第一个任务节点的数据
         *param processDefinitionKey 新建项目任务审批流程--流程标识。
         */
        String processDefinitionKey = "projectTaskAddApply";
        ResponseResult<FlowEntry> flowEntryResult = flowTaskStart.verifyAndGetFlowEntry(processDefinitionKey);
        if (!flowEntryResult.isSuccess()) {
            return ResMsg.newInstance(CodeEnum.FAIL, flowEntryResult);
        }
        FlowEntryPublish flowEntryPublish = flowEntryResult.getData().getMainFlowEntryPublish();
        String initTaskInfo = flowEntryPublish.getInitTaskInfo();
        com.ankaibei.workFlow.common.flow.vo.TaskInfoVo taskInfo = StrUtil.isBlank(initTaskInfo)
                ? null : JSON.parseObject(initTaskInfo, com.ankaibei.workFlow.common.flow.vo.TaskInfoVo.class);
        if (taskInfo != null) {
            String loginName = TokenData.takeFromRequest().getLoginName();
            taskInfo.setAssignedMe(StrUtil.equalsAny(
                    taskInfo.getAssignee(), loginName, FlowConstant.START_USER_NAME_VAR));
        }
        //用户在表单页面配置的操作按钮
        FlowTaskCommentDto flowTaskCommentDto = new FlowTaskCommentDto();
        //提交后进行到第二个节点
        flowTaskCommentDto.setApprovalType("agree");
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();
        stringObjectHashMap.put("target_task", taskInfoEntity.getTargetTask());
        stringObjectHashMap.put("task_priority", taskInfoEntity.getTaskPriority());
        stringObjectHashMap.put("task_participant", taskInfoEntity.getTaskParticipant());
        stringObjectHashMap.put("task_plan", taskInfoEntity.getEndTime().toString());
        stringObjectHashMap.put("task_creator", taskInfoEntity.getTaskCreator());
        stringObjectHashMap.put("task_index", taskInfoEntity.getTaskIndex());
        stringObjectHashMap.put("task_standard", taskInfoEntity.getTaskStandard());
        stringObjectHashMap.put("task_statements", taskInfoEntity.getTaskStatements());
        stringObjectHashMap.put("project_id", taskInfoEntity.getProjectId());
        stringObjectHashMap.put("create_date", taskInfoEntity.getCreateDate());
        stringObjectHashMap.put("task_id", save.getTaskId());
        JSONObject masterData = (JSONObject) JSONObject.toJSON(stringObjectHashMap);
        Map<String, String> map = flowTaskStart.startAndTakeUserTaskSS(processDefinitionKey, flowTaskCommentDto, null, masterData, null, null).getData();
        save.setFlowTaskStatus(FlowTaskStatus.SUBMITTED);
        save.setProcessInstanceId(map.get("processInstanceId"));
        save.setProcessDefinitionId(map.get("processDefinitionId"));
        taskInfoMapper.save(save);
        return new ResMsg(CodeEnum.OK);
    }

    @Override
    public ResMsg deleteTask(List<TaskInfoVo> taskInfoVos) {
        //   //审批状态   已提交：0; 审批中：1; 被拒绝：2; 已结束：3; 提前停止：4; 已取消：5;
        StringBuffer optional = new StringBuffer("任务：[");
        int count = 0;
        for (TaskInfoVo info : taskInfoVos) {
            TaskInfoEntity byId = taskInfoMapper.getById(info.getTaskId());
            if (byId.getFlowTaskStatus() > 1) {
                taskInfoMapper.deleteTask(info.getTaskId());
                count++;
            } else {
                optional.append(byId.getTargetTask() + ",");
            }
        }
        optional.replace(optional.length() - 1, optional.length(), "");
        optional.append("] 审批未结束，不可删除！");
        if (count == taskInfoVos.size()) {
            return new ResMsg(CodeEnum.OK, "");
        } else {
            return new ResMsg(CodeEnum.FAIL, optional);
        }
    }

    @Override
    public ResMsg findTaskById(TaskInfoVo taskInfoVo) {
        Optional<TaskInfoEntity> byId = taskInfoMapper.findById(taskInfoVo.getTaskId());
        return new ResMsg(CodeEnum.OK, byId.orElse(null));
    }

    @Override
    public ResMsg performTask(TaskInfoEntity taskInfoEntity) {
        if (taskInfoMapper.performTask(taskInfoEntity.getTaskId()) < 1) {
            return new ResMsg(CodeEnum.FAIL);
        }
        return new ResMsg(CodeEnum.OK);
    }
}
