package cn.axzo.workflow.server.controller.web;

import cn.axzo.workflow.client.feign.bpmn.ProcessInstanceApi;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
import cn.axzo.workflow.core.service.support.FlowNodeForecastService;
import cn.axzo.workflow.server.common.annotation.RepeatSubmit;
import cn.azxo.framework.common.model.CommonResponse;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.common.engine.impl.util.IoUtil;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.Deployment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;

/**
 * 测试接口
 * @author wangli
 * @since 2023/10/10 13:59
 */
@Slf4j
@RequestMapping("/web/v1/api")
@RestController
@Validated
public class TestController {

    @Autowired
    private FlowNodeForecastService forecastService;
    @Autowired
    private BpmnProcessInstanceService instanceService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessInstanceApi processInstanceApi;
    @Autowired
    private BpmnProcessInstanceService bpmnProcessInstanceService;

    @RepeatSubmit
    @GetMapping("/test")
    public void test(@RequestParam String processInstanceId) {
        List<FlowElement> flowElements = forecastService.performProcessForecasting(processInstanceId, null);
        System.out.println("flowElements = " + flowElements);
    }

    @RepeatSubmit
    @GetMapping("/test2")
    public void test2(@RequestParam String processInstanceId) {
        List<ProcessNodeDetailVO> detailVOS = instanceService.getProcessInstanceNodeForecast(processInstanceId, "296");
        System.out.println("detailVOS = " + detailVOS);
    }

    /**
     * 操作 act_ge_bytearray
     *
     * @param processInstanceId
     * @return
     */
    @GetMapping("/test3")
    public String test3(@RequestParam String processInstanceId) {
        Deployment deploy =
                repositoryService.createDeployment().addBytes("自定义资源", processInstanceId.getBytes()).deploy();
        InputStream is = repositoryService.getResourceAsStream(deploy.getId(), "自定义资源");
        byte[] bytes = IoUtil.readInputStream(is, "自定义资源");
        return new String(bytes);
    }

    @GetMapping("/test4")
    public String test4() {
        BpmnProcessInstanceQueryDTO query = new BpmnProcessInstanceQueryDTO();
        query.setProcessInstanceId("202311131646000000000");
        CommonResponse<BpmnProcessInstanceVO> processInstanceVO = processInstanceApi.getProcessInstanceVO(query);
        return processInstanceVO.getData().getName();
    }

    @GetMapping("/system/operation/batch/abort")
    public CommonResponse<Boolean> systemOperation(Long timestamp) {
        if (Objects.isNull(timestamp)) {
            timestamp = 1706198400000L;
        }
        List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
                .processInstanceBusinessStatus(PROCESSING.getStatus())
                .startedBefore(new Date(timestamp))
                .unfinished()
                .list();
        log.info("待系统中止的流程实例数: {}", list.size());
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        list.forEach(i -> {
            executorService.submit(() -> {
                try {
                    log.info("当前中止的流程: {}", i.getId());
                    BpmnProcessInstanceAbortDTO abort = new BpmnProcessInstanceAbortDTO();
                    abort.setProcessInstanceId(i.getId());
                    abort.setReason("系统超时中止");
                    bpmnProcessInstanceService.abortProcessInstance(abort);
                } catch (Exception e) {
                    log.warn("系统批量中止流程: {}, 发生异常: {}", i.getId(), e.getMessage());
                }
            });
        });
        return CommonResponse.success(true);
    }

}
