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.framework.model.PageInfo;
import com.mortals.framework.model.Result;
import com.mortals.xhx.busiz.req.*;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.DefinitionDeployRsp;
import com.mortals.xhx.busiz.rsp.FlowProcDef;
import com.mortals.xhx.busiz.rsp.FlowProcStartInfo;
import com.mortals.xhx.common.code.ApiRespCodeEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.model.RequestTaskReq;
import com.mortals.xhx.common.pdu.api.ApiReqPdu;
import com.mortals.xhx.common.pdu.api.ApiRespPdu;
import com.mortals.xhx.common.pdu.flow.FlowProcDefPdu;
import com.mortals.xhx.common.pdu.flow.FlowViewerPdu;
import com.mortals.xhx.feign.flowable.IApiFlowDefinitionFeign;
import com.mortals.xhx.feign.flowable.IApiFlowInstanceFeign;
import com.mortals.xhx.flowable.runtime.StartProcessInstanceReq;
import lombok.extern.apachecommons.CommonsLog;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 流程定义部署接口类
 *
 * @author: zxfei
 * @date: 2021/8/24 20:28
 */
@RestController
@Slf4j
@RequestMapping("/api/definition")
public class FlowDefinitionApiController {

    @Autowired
    private IApiFlowDefinitionFeign apiFlowDefinitionFeign;


    /**
     * 流程部署列表查询
     *
     * @param req
     * @return
     */
    @PostMapping("deploy/list")
    public ApiResp<DefinitionDeployRsp> deploymentsList(@RequestBody BaseFlowReq<BaseQuery> req) {
        ApiResp<DefinitionDeployRsp> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        PageInfo page = new PageInfo();
        page.setPrePageResult(-1);
        DefinitionDeployRsp deployRsp = new DefinitionDeployRsp();
        log.info("deploy req:{}", JSON.toJSONString(req));
        try {
            if (!ObjectUtils.isEmpty(req.getPage())) {
                page.setPrePageResult(req.getPage().getPer() == 0 ? -1 : req.getPage().getPer());
                page.setCurrPage(req.getPage().getSize() == 0 ? 1 : req.getPage().getSize());
            }
            ApiRespPdu<Result<FlowProcDefPdu>> resp = apiFlowDefinitionFeign.list(req.getQuery().getPlatformSn(), page);
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("获取流程定义列表异常：" + resp.getMsg());
                rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
                rsp.setMsg(resp.getMsg());
                return rsp;
                //  throw new AppException("获取流程定义列表异常：" + resp.getMsg());
            }

            List<FlowProcDef> collect = resp.getData().getList().stream().map(item -> {
                FlowProcDef flowProcDef = new FlowProcDef();
                BeanUtils.copyProperties(item, flowProcDef);
                return flowProcDef;
            }).collect(Collectors.toList());

            deployRsp.setList(collect);
            req.getPage().setTotal(resp.getData().getPageInfo().getTotalResult());

            deployRsp.setPage(req.getPage());

        } catch (Exception e) {
            log.error("流程部署列表查询失败", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }
        rsp.setData(deployRsp);
        log.info("响应【流程定义】【流程部署列表查询】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 激活或挂起流程定义(已经部署)
     *
     * @param req
     * @return
     */
    @PostMapping("deploy/updateState")
    public ApiResp updateState(@RequestBody DefinitionReq req) {
        ApiResp rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());

        try {
            ApiRespPdu<String> resp = apiFlowDefinitionFeign.updateState(req.getState(), req.getDeployId(), req.getPlatformSn());
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("激活或挂起流程异常：" + resp.getMsg());
                throw new AppException("激活或挂起流程异常：" + resp.getMsg());
            }
        } 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("deploy/readImage")
    public ApiResp<String> readImage(@RequestBody DefinitionReq req) {
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            if(ObjectUtils.isEmpty(req.getDeployId())) throw new AppException("deployId不能为空");
            ApiRespPdu<String> resp = apiFlowDefinitionFeign.readImage(req.getDeployId());
            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.getMessage());
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

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


    /**
     * 根据流程定义 ID 获取xml
     *
     * @param req
     * @return
     */
    @PostMapping("deploy/readXml")
    public ApiResp<String> readXml(@RequestBody DefinitionReq req) {
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            ApiRespPdu<String> resp = apiFlowDefinitionFeign.readXml(req.getDeployId());
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                throw new AppException(resp.getMsg());
            }
            rsp.setData(resp.getData());
        } catch (Exception e) {
            log.error("获取流xml异常", e);
            rsp.setCode(ApiRespCodeEnum.FAILED.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

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


}
