package com.mortals.xhx.busiz.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.exception.AppException;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.common.code.ApiRespCodeEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.pdu.api.ApiRespPdu;
import com.mortals.xhx.common.pdu.flow.FlowTaskVoPdu;
import com.mortals.xhx.common.pdu.flow.FlowViewerPdu;
import com.mortals.xhx.feign.flowable.IApiFlowInstanceFeign;
import com.mortals.xhx.flowable.processinstance.ProcessCommonReq;
import com.mortals.xhx.flowable.processinstance.ProcessDeleteReq;
import com.mortals.xhx.flowable.processinstance.ProcessStopReq;
import com.mortals.xhx.flowable.processinstance.ProcessUpdateStateReq;
import com.mortals.xhx.flowable.runtime.StartProcessInstanceReq;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 工作流流程对外服务接口
 *
 * @author: zxfei
 * @date: 2021/8/24 20:28
 */
@RestController
@CommonsLog
@RequestMapping("/api/flow")
public class FlowProcessApiController {
    @Autowired
    private IApiFlowInstanceFeign apiFlowInstanceFeign;


    /**
     * 启动流程
     *
     * @param req
     * @return
     */
    @PostMapping("process/start")
    public ApiResp<String> processStart(@RequestBody StartProcessInstanceReq req) {
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());

        try {
            ApiRespPdu<String> resp = apiFlowInstanceFeign.startProcessInstanceByKey(req);
            if(resp.getCode()==YesNoEnum.NO.getValue()){
               throw new AppException(resp.getMsg());
            }
            rsp.setData(resp.getData());
        } catch (Exception e) {
            log.error("流程实例化失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【启动】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    /**
     * 获取el表达式
     *
     * @param req
     * @return
     */
    @PostMapping("process/getAllProcessInstanceEl")
    public ApiResp<List<FlowTaskVoPdu>> getAllProcessInstanceEl(@RequestBody StartProcessInstanceReq req) {
        ApiResp<List<FlowTaskVoPdu>> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {

            ApiRespPdu<List<FlowTaskVoPdu>> resp = apiFlowInstanceFeign.getAllProcessInstanceEl(req);
            rsp.setData(resp.getData());
        } catch (Exception e) {
            log.error("流程查询失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【获取所有el表达式】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 激活或挂起流程实例
     *
     * @param req
     * @return
     */
    @PostMapping("process/updateState")
    public ApiResp updateState(@RequestBody ProcessUpdateStateReq req) {
        ApiResp rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());

        try {
            ApiRespPdu<String> resp = apiFlowInstanceFeign.updateState(req);
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("激活或挂起流程异常：" + resp.getMsg());
                throw new AppException(resp.getMsg());
            }
            rsp.setData(resp.getData());
        } catch (Exception e) {
            log.error("激活或挂起流程失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【启动】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 终止流程
     *
     * @param req
     * @return
     */
    @PostMapping("process/stop")
    public ApiResp<String> stopProcess(@RequestBody ProcessStopReq req) {
        ApiResp rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            ApiRespPdu<String> resp = apiFlowInstanceFeign.stopProcess(req);
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("流程实例化终止异常：" + resp.getMsg());
                throw new AppException(resp.getMsg());
            }
            rsp.setData(resp.getData());

        } catch (Exception e) {
            log.error("流程实例化终止失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【终止流程】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    /**
     * 删除流程
     *
     * @param req
     * @return
     */
    @PostMapping("process/delete")
    public ApiResp deleteProcess(@RequestBody ProcessDeleteReq req) {
        ApiResp rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            ApiRespPdu<String> resp = apiFlowInstanceFeign.deleteProcess(req);
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("删除流程异常：" + resp.getMsg());
                throw new AppException(resp.getMsg());
            }
            resp.setData(resp.getData());
        } catch (Exception e) {
            log.error("删除流程失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【删除流程】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 获取流程执行过程
     *
     * @param req
     * @return
     */
    @PostMapping("process/getFlowViewer")
    public ApiResp<List<FlowViewerPdu>> getFlowViewer(@RequestBody ProcessCommonReq req) {
        ApiResp<List<FlowViewerPdu>> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            ApiRespPdu<List<FlowViewerPdu>> resp = apiFlowInstanceFeign.getFlowViewer(req);
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("获取流程执行过程异常：" + resp.getMsg());
                throw new AppException(resp.getMsg());
            }

            rsp.setData(resp.getData());

        } catch (Exception e) {
            log.error("获取流程执行异常", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【获取流程执行过程】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    /**
     * 根据流程实例ID 获取当前流程运行情况 返回BASE64图片
     *
     * @param req
     * @return base64图片数据
     */
    @PostMapping("process/getImage")
    public ApiResp<String> processReadImage(@RequestBody ProcessCommonReq req) {
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            ApiRespPdu<String> resp = apiFlowInstanceFeign.getFlowImage(req);
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("获取流程图异常：" + resp.getMsg());
                throw new AppException(resp.getMsg());
            }
            rsp.setData(resp.getData());
        } catch (Exception e) {
            log.error("获取流程图异常", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【获取流程图异常】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    public static void main(String[] args) {
        ProcessUpdateStateReq processUpdateStateReq = new ProcessUpdateStateReq();
        processUpdateStateReq.setProcessInstanceId("123123");
        processUpdateStateReq.setSuspensionState(1);
        System.out.println(JSON.toJSONString(processUpdateStateReq));
    }

}
