package cn.stylefeng.workflow.instance.modular.task.taskopt.impl;

import cn.stylefeng.workflow.api.entity.instance.RuntimeNode;
import cn.stylefeng.workflow.api.entity.task.RuTask;
import cn.stylefeng.workflow.api.enums.BackTypeEnum;
import cn.stylefeng.workflow.api.enums.TaskStatusEnum;
import cn.stylefeng.workflow.api.enums.TaskTypeEnum;
import cn.stylefeng.workflow.api.pojo.InstanceContext;
import cn.stylefeng.workflow.instance.api.RuntimeNodeApi;
import cn.stylefeng.workflow.instance.api.WorkflowControlApi;
import cn.stylefeng.workflow.instance.api.WorkflowStatusApi;
import cn.stylefeng.workflow.instance.api.pojo.request.WorkflowTurnRequest;
import cn.stylefeng.workflow.instance.api.pojo.task.RuTaskRequest;
import cn.stylefeng.workflow.instance.modular.task.pojo.operate.BackTaskRequest;
import cn.stylefeng.workflow.instance.modular.task.service.RuTaskService;
import cn.stylefeng.workflow.instance.modular.task.service.TaskDaoWithEvent;
import cn.stylefeng.workflow.instance.modular.task.taskopt.TaskBackService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

@Service
public class TaskBackServiceImpl implements TaskBackService {

    @Resource
    private RuTaskService ruTaskService;

    @Resource
    private WorkflowStatusApi workflowStatusApi;

    @Resource
    private RuntimeNodeApi runtimeNodeApi;

    @Resource
    private WorkflowControlApi workflowControlApi;

    @Resource
    private TaskDaoWithEvent taskDaoWithEvent;

    @Override
    public void backTask(BackTaskRequest backTaskRequest) {

        RuTaskRequest temp = new RuTaskRequest();
        temp.setTaskId(backTaskRequest.getTaskId());
        RuTask ruTask = this.ruTaskService.detail(temp);
        taskDaoWithEvent.updateTaskStatus(ruTask, TaskStatusEnum.BACK.getCode(), backTaskRequest.getSuggestContent());

        this.ruTaskService.deleteAnyOtherTask(ruTask.getRuNodeId(), ruTask.getTaskId());

        InstanceContext instanceContext = workflowStatusApi.buildInstanceContext(ruTask.getInstanceId());

        Integer backType = backTaskRequest.getBackType();

        if (BackTypeEnum.TO_START.getCode().equals(backType)) {

            RuntimeNode startRuntimeNode = runtimeNodeApi.getStartRuntimeNode(ruTask.getInstanceId());

            this.ruTaskService.createUserTask(instanceContext.getRuntimeInstance().getApplicant(), TaskTypeEnum.PROCESSING, startRuntimeNode, instanceContext);

            WorkflowTurnRequest workflowTurnRequest = new WorkflowTurnRequest();
            workflowTurnRequest.setInstanceId(ruTask.getInstanceId());
            workflowTurnRequest.setReNodeId(startRuntimeNode.getNodeId());
            workflowTurnRequest.setInstanceContext(instanceContext);
            workflowTurnRequest.setContinueFlow(false);
            workflowControlApi.turn(workflowTurnRequest);
        }

        else {

            WorkflowTurnRequest workflowTurnRequest = new WorkflowTurnRequest();
            workflowTurnRequest.setInstanceId(ruTask.getInstanceId());
            workflowTurnRequest.setReNodeId(backTaskRequest.getBackNodeId());
            workflowTurnRequest.setInstanceContext(instanceContext);
            workflowTurnRequest.setContinueFlow(true);
            workflowControlApi.turn(workflowTurnRequest);
        }
    }

}
