package com.mortals.xhx.module.flowable.web;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.HashUtil;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.common.IBaseEnum;
import com.mortals.framework.common.code.YesNo;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.Result;
import com.mortals.framework.web.BaseCRUDJsonController;
import com.mortals.framework.web.BaseCRUDMappingController;
import com.mortals.xhx.base.system.upload.service.UploadService;
import com.mortals.xhx.common.code.FlowStateType;
import com.mortals.xhx.common.pdu.flow.DefinitionVoPdu;
import com.mortals.xhx.common.pdu.flow.FlowSaveXmlPdu;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.mortals.framework.web.BaseCRUDJsonMappingController;
import com.mortals.xhx.module.flowable.model.FlowableDefinitionEntity;
import com.mortals.xhx.module.flowable.service.FlowableDefinitionService;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>Title: 流程定义表</p>
 * <p>Description: FlowableDefinitionController  </p>
 * <p>Copyright: Copyright &reg;  </p>
 * <p>Company: </p>
 *
 * @author zxfei
 * @version 1.0.0
 */
@RestController
@RequestMapping("flowable/definition")
public class FlowableDefinitionController extends BaseCRUDJsonMappingController<FlowableDefinitionService, FlowableDefinitionForm, FlowableDefinitionEntity, Long> {

    public FlowableDefinitionController() {
        super.setFormClass(FlowableDefinitionForm.class);
        super.setModuleDesc("流程定义表");
    }

    @Override
    protected void init(HttpServletRequest request, HttpServletResponse response, FlowableDefinitionForm form, Map<String, Object> model, Context context) {
        this.addDict(model, "suspensionState", IBaseEnum.getEnumMap(FlowStateType.class));
    }

    /**
     * 查询流程定义表
     */
    @PostMapping(value = "list")
    @Override
    public String list(FlowableDefinitionForm form) {
        Map<String, Object> model = new HashMap();
        JSONObject ret = new JSONObject();
        int code = VALUE_RESULT_SUCCESS;
        String busiDesc = "查询" + this.getModuleDesc();
        try {
            Result<FlowableDefinitionEntity> result = this.service.getDefinList(form.getQuery(), form.getPageInfo(), getContext());
            this.init(request, response, form, model, getContext());
            model.put("result", result.getList());
            model.put("pageInfo", result.getPageInfo());
            model.putAll(form.getModel());
            this.recordSysLog(request, busiDesc + " 【成功】");
        } catch (Exception e) {
            log.error("查询流程列表异常", e);
            this.doException(request, busiDesc, model, e);
            code = VALUE_RESULT_FAILURE;
        }

        ret.put("code", code);
        ret.put("query", form.getQuery());
        ret.put("data", model);
        return ret.toJSONString();
    }


    /**
     * 读取流程图片
     */
    @PostMapping(value = "readImage")
    public String readImage(@ApiParam(value = "流程定义id") @RequestParam(value = "deployId") String deployId) {
        JSONObject jsonObject = new JSONObject();
        OutputStream os = null;
        BufferedImage image = null;
        try {
            String base64 = this.getService().readImage(deployId);

            byte[] bytes = Base64.decode(base64);

            //  uploadService.saveFileUpload()
            jsonObject.put("src", VALUE_RESULT_SUCCESS);
            jsonObject.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
        } catch (Exception e) {
            log.error("读取流程图片异常", e);
            jsonObject.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            jsonObject.put(KEY_RESULT_MSG, super.convertException(e));
        }
        return jsonObject.toJSONString();
    }

    /**
     * 读取流程XML
     */
    @PostMapping(value = "readXml")
    public String readXml(@ApiParam(value = "流程定义id") @RequestParam(value = "deployId") String deployId) {

        log.info("readXml,deployId:" + deployId);
        JSONObject ret = new JSONObject();
        try {
            String Xml = this.getService().readXml(deployId);
            ret.put(KEY_RESULT_DATA, Xml);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
        } catch (Exception e) {
            log.error("读取流程XML异常", e);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            ret.put(KEY_RESULT_MSG, super.convertException(e));
        }
        return ret.toJSONString();
    }

    /**
     * 保存流程XML
     */
    @PostMapping(value = "saveXml")
    public String saveXml(@ApiParam(value = "流程定义类") @RequestParam Map map) {
        FlowSaveXmlPdu flowSaveXmlPdu = BeanUtil.fillBeanWithMap(map, new FlowSaveXmlPdu(), false);
        JSONObject ret = new JSONObject();
        try {
            String definId = this.getService().saveXml(flowSaveXmlPdu, getContext());
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
            ret.put(KEY_RESULT_MSG, "保存模型XML成功，definitionId:" + definId);
        } catch (Exception e) {
            log.error("保存XML异常", e);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            ret.put(KEY_RESULT_MSG, super.convertException(e));
        }
        return ret.toJSONString();
    }


    /**
     * 启动流程定义的实例
     */
    @PostMapping(value = "start")
    public String start(@ApiParam(value = "流程定义id") @RequestParam(value = "procDefId") String procDefId,
                        @ApiParam(value = "流程定义类") @RequestParam(value = "data") String data) {

        JSONObject ret = new JSONObject();
        try {
            String proInstanceId = this.getService().start(procDefId, data, getContext());
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
            ret.put(KEY_RESULT_MSG, "部署流程实例成功，proInstanceId:" + proInstanceId);
        } catch (Exception e) {
            log.error("部署流程实例异常", e);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            ret.put(KEY_RESULT_MSG, super.convertException(e));
        }
        return ret.toJSONString();
    }


    /**
     * 激活/挂起流程
     */
    @PostMapping(value = "updateState")
    public String updateState(@ApiParam(value = "流程定义实体类") DefinitionVoPdu definitionVoPdu) {

        JSONObject ret = new JSONObject();
        try {
            String proInstanceId = this.getService().updateState(definitionVoPdu, getContext());
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
            ret.put(KEY_RESULT_MSG, "挂起/激活流程成功，proInstanceId:" + proInstanceId);
        } catch (Exception e) {
            log.error("挂起/激活流程异常", e);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            ret.put(KEY_RESULT_MSG, super.convertException(e));
        }
        return ret.toJSONString();
    }


    /**
     * 删除流程定义
     */
    @PostMapping(value = "deleteDefinition")
    public String deleteDefinition(@ApiParam(value = "流程定义实体类") DefinitionVoPdu definitionVoPdu) {

        JSONObject ret = new JSONObject();
        try {
            String deplyId = this.getService().deleteDefinition(definitionVoPdu, getContext());
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
            ret.put(KEY_RESULT_MSG, "删除流程成功，deplyId:" + deplyId);
        } catch (Exception e) {
            log.error("删除流程异常", e);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            ret.put(KEY_RESULT_MSG, super.convertException(e));
        }
        return ret.toJSONString();
    }


    /**
     * 导入附件
     */
    @PostMapping(value = "upload")
    public String upload(@RequestParam(required = false) String name,
                         @RequestParam(required = false) String category,
                         MultipartFile multipartFile) {

        JSONObject ret = new JSONObject();
        try {

            String xml = IoUtil.readUtf8(multipartFile.getInputStream());

            FlowSaveXmlPdu flowSaveXmlPdu = new FlowSaveXmlPdu();
            flowSaveXmlPdu.setCategory(category);
            flowSaveXmlPdu.setName(name);
            flowSaveXmlPdu.setXml(xml);

            String definId = this.getService().saveXml(flowSaveXmlPdu, getContext());
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
            ret.put(KEY_RESULT_MSG, "导入模型XML成功，definitionId:" + definId);
        } catch (Exception e) {
            log.error("挂起/激活流程异常", e);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            ret.put(KEY_RESULT_MSG, super.convertException(e));
        }
        return ret.toJSONString();
    }

}