package com.njcn.process.controller.flowable;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.process.pojo.dto.flowable.FlowProcDefDto;
import com.njcn.process.pojo.dto.flowable.FlowSaveXmlVo;
import com.njcn.process.service.flowable.IFlowDefinitionService;
import com.njcn.web.controller.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * pqs
 * 工作流
 *
 * @author cdf
 * @date 2023/4/10
 */
@Slf4j
@Api(tags = "工作流")
@RestController
@RequestMapping("/flowable/definition")
@RequiredArgsConstructor
public class FlowDefinitionController extends BaseController {


    private final IFlowDefinitionService flowDefinitionService;

    private final RepositoryService repositoryService;


    @GetMapping("deployment")
    @ApiOperation(value = "工作流_部署流程")
    public void createDeployment() {
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("puce.bpmn20.xml")
                .name("谐波普测管理").category("xbpc")
                .deploy();

        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
        repositoryService.setProcessDefinitionCategory(definition.getId(), "xbpc");
        System.out.println(deployment.getId());
    }


    @ApiOperation(value = "工作流_发起流程")
    @PostMapping("/start")
    public HttpResult<String> start(@ApiParam(value = "流程定义id") @RequestParam(value = "procDefId") String procDefId,
                                    @ApiParam(value = "监督单id") @RequestParam(value = "thsIndex") String thsIndex,
                                    @ApiParam(value = "表单功能类型") @RequestParam(value = "type") Integer type,
                                    @ApiParam(value = "变量集合,json对象") @RequestBody Map<String, Object> variables) {
        String methodDescribe = getMethodDescribe("start");
        String res = flowDefinitionService.startProcessInstanceById(procDefId, thsIndex,type, variables);
        if (Objects.nonNull(res)) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, res, methodDescribe);
        }
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe);
    }


    @ApiOperation(value = "工作流_定义删除")
    @PostMapping(value = "delete")
    public HttpResult<Object> delete(@RequestBody List<String> deployIds) {
        String methodDescribe = getMethodDescribe("delete");
        for (String deployId : deployIds) {
            flowDefinitionService.delete(deployId);
        }
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
    }

    @GetMapping(value = "/list")
    @ApiOperation(value = "流程定义列表")
    public HttpResult<Page<FlowProcDefDto>> list(@ApiParam(value = "当前页码", required = true) @RequestParam("pageNum") Integer pageNum,
                                                 @ApiParam(value = "每页条数", required = true) @RequestParam("pageSize") Integer pageSize,
                                                 @ApiParam(value = "流程名称") @RequestParam(value = "name", required = false) String name) {
        String methodDescribe = getMethodDescribe("list");
        Page<FlowProcDefDto> pageResult = flowDefinitionService.list(name, pageNum, pageSize);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, pageResult, methodDescribe);

    }


    @ApiOperation(value = "保存流程设计器内的xml文件")
    @PostMapping("/save")
    public HttpResult save(@RequestBody FlowSaveXmlVo vo) {
        String methodDescribe = getMethodDescribe("save");

        InputStream in = null;
        try {
            in = new ByteArrayInputStream(vo.getFlowableXml().getBytes(StandardCharsets.UTF_8));
            flowDefinitionService.importFile(vo.getName(), vo.getCategory(), in);
        } catch (Exception e) {
            log.error("导入失败:", e);
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, e.getMessage(), methodDescribe);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                log.error("关闭输入流出错", e);
            }
        }

        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, "导入成功", methodDescribe);
    }


    @ApiOperation(value = "读取xml文件")
    @GetMapping("/readXml")
    public HttpResult<String> readXml(@ApiParam(value = "流程定义id") @RequestParam(value = "deployId") String deployId) {
        String methodDescribe = getMethodDescribe("readXml");
        try {
            String result = flowDefinitionService.readXml(deployId);
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
        } catch (Exception e) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, "加载xml文件异常", methodDescribe);
        }
    }


    /**
     * 挂载表单
     *
     * @author cdf
     * @date 2024/4/2
     */
    @ApiOperation(value = "挂载表单")
    @GetMapping("/assFormWithDeploy")
    public HttpResult<Boolean> assFormWithDeploy(@ApiParam(value = "流程定义id") @RequestParam(value = "deployId") String deployId, @ApiParam(value = "表单功能id") @RequestParam(value = "formId") String formId) {
        String methodDescribe = getMethodDescribe("assFormWithDeploy");
        flowDefinitionService.assFormWithDeploy(deployId, formId);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
    }


}
