package com.mortals.xhx.busiz.web;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
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.framework.util.DateUtils;
import com.mortals.xhx.busiz.req.BaseFlowReq;
import com.mortals.xhx.busiz.req.BaseQuery;
import com.mortals.xhx.busiz.rsp.ApiResp;
import com.mortals.xhx.busiz.rsp.TaskRsp;
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.FlowNextPdu;
import com.mortals.xhx.common.pdu.flow.FlowTaskPdu;
import com.mortals.xhx.common.pdu.flow.FlowUserTaskPdu;
import com.mortals.xhx.feign.flowable.IApiFlowTaskFeign;
import com.mortals.xhx.flowable.task.*;
import lombok.extern.apachecommons.CommonsLog;
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.Date;
import java.util.List;
import java.util.Map;

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

    /**
     * 我发起的流程
     *
     * @param req
     * @return
     */
    @PostMapping("task/myProcess")
    public ApiResp<TaskRsp> myProcess(@RequestBody BaseFlowReq<BaseQuery> req) {
        ApiResp<TaskRsp> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        PageInfo page = new PageInfo();
        page.setPrePageResult(-1);
        TaskRsp taskRsp = new TaskRsp();
        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());
            }

            CommonTaskReq commonTaskReq = new CommonTaskReq();
            commonTaskReq.setPlatformSn(req.getQuery().getPlatformSn());
            commonTaskReq.setUserCode(req.getQuery().getUserCode());
            commonTaskReq.setPageInfo(page);
            ApiRespPdu<Result<FlowTaskPdu>> resp = apiFlowTaskFeign.myProcess(commonTaskReq);
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("获取指定用户流程任务列表异常：" + resp.getMsg());
                throw new AppException("获取指定用户流程任务列表异常：" + resp.getMsg());
            }


            taskRsp.setList(resp.getData().getList());
            req.getPage().setTotal(resp.getData().getPageInfo().getTotalResult());
            taskRsp.setPage(req.getPage());
        } catch (Exception e) {
            log.error("获取指定用户流程任务列表异常", e);
            rsp.setCode(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }
        rsp.setData(taskRsp);
        log.info("响应【我的流程】【流程查询】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 获取待办列表
     * 获取的列表需要和业务系统数据合并
     *
     * @param req
     * @return
     */
    @PostMapping("task/todoList")
    public ApiResp<TaskRsp> todoList(@RequestBody BaseFlowReq<BaseQuery> req) {
        ApiResp<TaskRsp> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        PageInfo page = new PageInfo();
        page.setPrePageResult(-1);
        TaskRsp taskRsp = new TaskRsp();
        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());
            }
            CommonTaskReq commonTaskReq = new CommonTaskReq();
            commonTaskReq.setPlatformSn(req.getQuery().getPlatformSn());
            commonTaskReq.setUserCode(req.getQuery().getUserCode());
            commonTaskReq.setCandidateUsers(req.getQuery().getCandidateUsers());
            commonTaskReq.setCandidateGroups(req.getQuery().getCandidateGroups());
            commonTaskReq.setPageInfo(page);
            ApiRespPdu<Result<FlowTaskPdu>> resp = apiFlowTaskFeign.todoList(commonTaskReq);
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("获取指定用户代办任务列表异常：" + resp.getMsg());
                throw new AppException("获取指定用户代办流程任务列表异常：" + resp.getMsg());
            }


            taskRsp.setList(resp.getData().getList());
            req.getPage().setTotal(resp.getData().getPageInfo().getTotalResult());
            taskRsp.setPage(req.getPage());
        } catch (Exception e) {
            log.error("获取指定用户待办流程任务列表异常", e);
            rsp.setCode(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }
        rsp.setData(taskRsp);
        log.info("响应【待办任务】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 获取已办任务
     * 获取的列表需要和业务系统数据合并
     *
     * @param req
     * @return
     */
    @PostMapping("task/finishedList")
    public ApiResp<TaskRsp> finishedList(@RequestBody BaseFlowReq<BaseQuery> req) {
        ApiResp<TaskRsp> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        PageInfo page = new PageInfo();
        page.setPrePageResult(-1);
        TaskRsp taskRsp = new TaskRsp();
        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());
            }
            CommonTaskReq commonTaskReq = new CommonTaskReq();
            commonTaskReq.setPlatformSn(req.getQuery().getPlatformSn());
            commonTaskReq.setUserCode(req.getQuery().getUserCode());
            commonTaskReq.setPageInfo(page);

            ApiRespPdu<Result<FlowTaskPdu>> resp = apiFlowTaskFeign.finishedList(commonTaskReq);
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("获取指定用户已办任务列表异常：" + resp.getMsg());
                throw new AppException("获取指定用户已办流程任务列表异常：" + resp.getMsg());
            }

            taskRsp.setList(resp.getData().getList());
            req.getPage().setTotal(resp.getData().getPageInfo().getTotalResult());
            taskRsp.setPage(req.getPage());
        } catch (Exception e) {
            log.error("获取指定用户已办任务列表异常", e);
            rsp.setCode(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }
        rsp.setData(taskRsp);
        log.info("响应【已办流程】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 流程历史流转记录
     *
     * @param req
     * @return
     */
    @PostMapping("task/flowRecord")
    public ApiResp<TaskRsp> flowRecord(@RequestBody BaseFlowReq<BaseQuery> req) {
        ApiResp<TaskRsp> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        PageInfo page = new PageInfo();
        page.setPrePageResult(-1);
        TaskRsp taskRsp = new TaskRsp();
        try {
            CommonTaskReq commonTaskReq = new CommonTaskReq();
            commonTaskReq.setPlatformSn(req.getQuery().getPlatformSn());
            commonTaskReq.setUserCode(req.getQuery().getUserCode());
            commonTaskReq.setProcessInstanceId(req.getQuery().getProcessInstanceId());

            ApiRespPdu<List<FlowTaskPdu>> resp = apiFlowTaskFeign.flowRecord(commonTaskReq);
            if (YesNoEnum.NO.getValue() == resp.getCode()) {
                log.error("获取流程历史流转记录列表异常：" + resp.getMsg());
                throw new AppException("获取流程历史流转记录列表异常：" + resp.getMsg());
            }

            taskRsp.setList(resp.getData());
        } catch (Exception e) {
            log.error("获取指定用户代办流程任务列表异常", e);
            rsp.setCode(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }
        rsp.setData(taskRsp);
        log.info("响应【流程历史流转记录】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }
    /**
     * 获取流程变量
     *
     * @param req
     * @return
     */
    @PostMapping("task/processVariables")
    public ApiResp<Map<String, Object>> processVariables(@RequestBody CommonTaskReq req) {
        ApiResp<Map<String, Object>> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());

        try {
            ApiRespPdu<Map<String, Object>> resp = apiFlowTaskFeign.processVariables(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

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


    /**
     * 设置流程变量
     *
     * @param req
     * @return
     */
    @PostMapping("task/setProcessVariables")
    public ApiResp<Map<String, Object>> setProcessVariables(@RequestBody CommonTaskReq req) {
        ApiResp<Map<String, Object>> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());

        try {
            ApiRespPdu<Map<String, Object>> resp = apiFlowTaskFeign.processVariables(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

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

    /**
     * 撤回流程
     *
     * @param req
     * @return
     */
    @PostMapping("task/revokeProcess")
    public ApiResp revokeProcess(@RequestBody RevokeTaskReq req) {
        ApiResp rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            ApiRespPdu<String> resp = apiFlowTaskFeign.revokeProcess(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

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


    /**
     * 取消申请
     *
     * @param commonTaskReq
     * @return
     */
    @PostMapping("task/stopProcess")
    public ApiResp stopProcess(@RequestBody CommonTaskReq commonTaskReq) {
        ApiResp rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            ApiRespPdu<String> resp = apiFlowTaskFeign.stopProcess(commonTaskReq);
            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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }


        log.info("响应【取消申请】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 审批任务
     *
     * @param req
     * @return
     */
    @PostMapping("task/complete")
    public ApiResp<String> complete(@RequestBody CompleteTaskReq req) {
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            ApiRespPdu<String> resp = apiFlowTaskFeign.complete(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【审批任务】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 驳回任务
     *
     * @param req
     * @return
     */
    @PostMapping("task/reject")
    public ApiResp reject(@RequestBody RejectTaskReq req) {
        ApiResp rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {

            ApiRespPdu<String> resp = apiFlowTaskFeign.reject(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【驳回任务】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    /**
     * 退回任务
     *
     * @param req
     * @return
     */
    @PostMapping("task/return")
    public ApiResp taskReturn(@RequestBody ReturnTaskReq req) {
        ApiResp rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {

            ApiRespPdu<String> resp = apiFlowTaskFeign.taskReturn(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【驳回任务】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 删除任务
     *
     * @param req
     * @return
     */
    @PostMapping("task/delete")
    public ApiResp<String> delete(@RequestBody DeleteTaskReq req) {
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {

            ApiRespPdu<String> resp = apiFlowTaskFeign.delete(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

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

    /**
     * 委派任务
     *
     * @param req
     * @return
     */
    @PostMapping("task/delegate")
    public ApiResp<String> delegateTask(@RequestBody DelegateTaskReq req) {
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {

            ApiRespPdu<String> resp = apiFlowTaskFeign.delegateTask(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【委派任务】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 转办任务
     *
     * @param req
     * @return
     */
    @PostMapping("task/assign")
    public ApiResp assignTask(@RequestBody TurnTaskReq req) {
        ApiResp rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {

            ApiRespPdu<String> resp = apiFlowTaskFeign.assignTask(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【转办任务】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    /**
     * 加签任务
     *
     * @param req
     * @return
     */
    @PostMapping("task/addSign")
    public ApiResp<String> addSignTask(@RequestBody AddSignTaskReq req) {
        ApiResp<String> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {

            ApiRespPdu<String> resp = apiFlowTaskFeign.addSignTask(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【加签任务】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }

    /**
     * 获取所有可回退的节点
     *
     * @param req
     * @return
     */
    @PostMapping("task/findReturnTaskList")
    public ApiResp<List<FlowUserTaskPdu>> findReturnTaskList(@RequestBody CommonTaskReq req) {
        ApiResp<List<FlowUserTaskPdu>> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {

            ApiRespPdu<List<FlowUserTaskPdu>> resp = apiFlowTaskFeign.findReturnTaskList(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【获取所有可回退的节点】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    /**
     * 获取下一节点
     *
     * @param req
     * @return
     */
    @PostMapping("task/nextFlowNode")
    public ApiResp<FlowNextPdu> nextFlowNode(@RequestBody CommonTaskReq req) {
        ApiResp<FlowNextPdu> rsp = new ApiResp<>();
        rsp.setMsg(ApiRespCodeEnum.SUCCESS.getLabel());
        rsp.setCode(ApiRespCodeEnum.SUCCESS.getValue());
        try {
            ApiRespPdu<FlowNextPdu> resp = apiFlowTaskFeign.getNextFlowNode(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(YesNoEnum.NO.getValue());
            rsp.setMsg(e.getMessage());
            return rsp;
        }

        log.info("响应【获取下一节点】【响应体】-->  " + JSONObject.toJSONString(rsp));
        return rsp;
    }


    public static void main(String[] args) {

        DateTime dateTime = DateUtil.offsetMonth(new Date(), 2);

        System.out.println(DateUtils.getStrDate(dateTime));
    }
}
