package com.boco.nbd.wios.flow.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.bestvike.linq.Linq;
import com.boco.nbd.framework.common.ResponseMessage2;
import com.boco.nbd.framework.common.ResponseStatus;
import com.boco.nbd.framework.common.util.IdUtil;
import com.boco.nbd.wios.flow.entity.bo.*;
import com.boco.nbd.wios.flow.entity.po.FlowNodeUserPO;
import com.boco.nbd.wios.flow.entity.po.FlowPO;
import com.boco.nbd.wios.flow.entity.po.GroupPO;
import com.boco.nbd.wios.flow.entity.po.NodePO;
import com.boco.nbd.wios.flow.entity.qo.NodeQo;
import com.boco.nbd.wios.flow.enums.FlowNodeEnum;
import com.boco.nbd.wios.flow.service.IFlowService;
import com.boco.nbd.wios.flow.service.IGroupService;
import com.boco.nbd.wios.flow.service.INodeService;
import com.boco.nbd.wios.flow.service.IOrderService;
import com.boco.nbd.wios.flow.util.ProcessUtil;
import com.ihidea.core.support.session.SessionInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author:cao hai
 * @date:2022/6/22 14:34
 * @version:V1.0
 * @description:FlowManagerController
 * @modify:
 */
@RestController
@RequestMapping("/flowManager")
@Api(tags = "流程用户管理接口")
@Slf4j
public class FlowManagerController {

    @Autowired
    private IFlowService flowService;

    @Autowired
    private INodeService nodeService;

    @Autowired
    private IGroupService groupService;

    @Autowired
    private IOrderService orderService;


    /**
     * @return
     */
    @RequestMapping(value = "/getInvoiceRight", method = RequestMethod.GET)
    @ApiOperation(notes = "获取当前用户的票据权限;113-开票权限,114-收票权限", value = "获取当前用户的票据权限;113-开票权限,114-收票权限")
    public ResponseMessage2 getInvoiceRight() {
        List<Integer> result = new ArrayList<>(2);
        try {
            SessionInfo currentUser = ProcessUtil.getUserInfo();
            if (currentUser == null) {
                return ResponseMessage2.Failed(ResponseStatus.ForbiddenAccess.getIndex(), ProcessUtil.RE_LOGIN);
            }
            List<String> superUsers = Linq.of(orderService.getSuperUserByGroup()).select(s -> s.getId()).toList();
            if (CollUtil.isNotEmpty(superUsers)) {
                if (Linq.of(superUsers).where(s -> currentUser.getUserId().equals(s)).firstOrDefault() != null) {
                    result.add(FlowNodeEnum.NODE_113.getKey());
                    result.add(FlowNodeEnum.NODE_114.getKey());
                    return ResponseMessage2.Success2(result);
                }
            }
            List<FlowNodeUserPO> right113 = nodeService.getFlowNodeUserInfo(FlowNodeEnum.NODE_113.getKey(), null, null);
            if (Linq.of(right113).where(s -> currentUser.getUserName().equals(s.getUserName())).firstOrDefault() != null) {
                result.add(FlowNodeEnum.NODE_113.getKey());
            }
            List<FlowNodeUserPO> right114 = nodeService.getFlowNodeUserInfo(FlowNodeEnum.NODE_114.getKey(), null, null);
            if (Linq.of(right114).where(s -> currentUser.getUserName().equals(s.getUserName())).firstOrDefault() != null) {
                result.add(FlowNodeEnum.NODE_114.getKey());
            }


        } catch (Exception ex) {
            log.error("getBillRight " + ex.getMessage());
        }
        return ResponseMessage2.Success2(result);
    }

    /**
     * updateNode
     *
     * @param po
     * @return
     */
    @RequestMapping(value = "/save/node", method = RequestMethod.POST)
    @ApiOperation(notes = "保存节点(nodeId为空新增)", value = "保存节点")
    public ResponseMessage2 saveNode(@RequestBody NodePO po) {
        try {
            if (null == po.getFlowId()) {
                return ResponseMessage2.Failed("flowId为空");
            }
            if (StrUtil.isEmpty(po.getNodeCode())) {
                return ResponseMessage2.Failed("节点编号为空");
            }
            if (StrUtil.isEmpty(po.getNodeName())) {
                return ResponseMessage2.Failed("节点名称");
            }
            if (po.getNodeId() == null) {
                if (!nodeService.checkNode(po)) {
                    return ResponseMessage2.Failed("该流程下nodeId或者节点名称已重复");
                }
                int status = nodeService.insert(po);
                if (status > 0) {
                    return ResponseMessage2.Success();
                }
                return ResponseMessage2.Failed("添加节点失败!");
            }

            int status = nodeService.updateByPrimaryKey(po);
            if (status > 0) {
                return ResponseMessage2.Success();
            }
            return ResponseMessage2.Failed("修改节点失败!");
        } catch (Exception e) {
            log.error("saveNode error:", e);
            return ResponseMessage2.Failed(e.getMessage());
        }
    }

    /**
     * deleteNode
     *
     * @param nodeId
     * @return
     */
    @RequestMapping(value = "/delete/node", method = RequestMethod.GET)
    @ApiOperation(notes = "根据ID删除", value = "删除节点")
    public ResponseMessage2 deleteNode(Long nodeId) {
        try {
            int status = nodeService.deleteByPrimaryKey(nodeId);
            if (status > 0) {
                return ResponseMessage2.Success();
            }
            return ResponseMessage2.Failed("删除流程失败!");
        } catch (Exception e) {
            log.error("deleteNode error:", e);
            return ResponseMessage2.Failed(e.getMessage());
        }
    }


    /**
     * searchNode
     *
     * @param qo
     * @return
     */
    @RequestMapping(value = "/search/node", method = RequestMethod.POST)
    @ApiOperation(notes = "查询节点数据", value = "查询节点数据")
    public ResponseMessage2 searchNode(NodeQo qo) {
        return ResponseMessage2.Success2(nodeService.searchNode(qo));
    }

    /**
     * @param nodeId
     * @return
     */
    @RequestMapping(value = "/getGroupByNode", method = RequestMethod.GET)
    @ApiOperation(notes = "根据节点获取绑定的用户组", value = "根据节点获取绑定的用户组")
    public ResponseMessage2 getGroupByNode(Long nodeId) {
        List<NodeGroupBO> result = nodeService.getNodeGroupsInfo(nodeId);
        return ResponseMessage2.Success2(result);
    }

    /**
     * 保存节点配置的用户组
     *
     * @param vo
     * @return
     */
    @RequestMapping(value = "/saveNodeGroup", method = RequestMethod.POST)
    @ApiOperation(notes = "保存节点配置的用户组", value = "保存节点配置的用户组")
    public ResponseMessage2 saveNodeGroup(@RequestBody NodeGroupVO vo) {
        Long nodeId = vo.getNodeId();
        if (nodeId == null) {
            return ResponseMessage2.Failed("节点ID不能为空");
        }
        nodeService.updateGroupNode(vo);
        return ResponseMessage2.Success();
    }

    /**
     * @param flowCode
     * @param nodeCode
     * @return
     */
    @RequestMapping(value = "/getDataByFlowAndNode", method = RequestMethod.GET)
    @ApiOperation(notes = "根据流程标识与节点名称", value = "根据流程标识与节点名称")
    public ResponseMessage2 getDataByFlowAndNode(@RequestParam("flowCode") String flowCode,
                                                 @RequestParam("nodeCode") String nodeCode) {
        return ResponseMessage2.Success2(nodeService.selectDataByFlowAndNode(flowCode, nodeCode));
    }

    /**
     * @return
     */
    @RequestMapping(value = "/loadUsers", method = RequestMethod.GET)
    @ApiOperation(notes = "加载用户数据", value = "加载用户数据")
    public ResponseMessage2 loadUsers(@RequestParam(value = "groupId", required = false) Long groupId,
                                      @RequestParam(value = "vendorId", required = false) Integer vendorId) {
        return ResponseMessage2.Success2(nodeService.loadUsers(groupId, vendorId));
    }

    @RequestMapping(value = "/deleteGroup", method = RequestMethod.GET)
    @ApiOperation(notes = "根据id删除用户组", value = "根据id删除用户组")
    public ResponseMessage2 deleteGroup(Long groupId) {
        try {
            if (null == groupId) {
                return ResponseMessage2.Failed("groupId参数缺失!");
            }
            groupService.deleteGroup(groupId);
            return ResponseMessage2.Success();
        } catch (Exception e) {
            log.error("deleteGroup error:", e);
            return ResponseMessage2.Failed(e.getMessage());
        }
    }

    @RequestMapping(value = "/getVendorInfo", method = RequestMethod.GET)
    @ApiOperation(notes = "获取厂家", value = "获取厂家")
    public ResponseMessage2 getVendorInfo() {
        return ResponseMessage2.Success2(nodeService.getSelectVendorInfo());
    }


    @RequestMapping(value = "/getUserByNodeCode", method = RequestMethod.GET)
    @ApiOperation(notes = "通过节点加载配置用户信息", value = "通过节点加载配置用户信息")
    public ResponseMessage2 getUserByNodeCode(@RequestParam(value = "nodeCode") Integer nodeCode,
                                              @RequestParam(value = "vendorId", required = false) Integer vendorId,
                                              @RequestParam(value = "userName", required = false) String userName) {
        return ResponseMessage2.Success2(nodeService.getFlowNodeUserInfo(nodeCode, vendorId, userName));
    }

    @RequestMapping(value = "/getConnectUser", method = RequestMethod.GET)
    @ApiOperation(notes = "获取订单首联人信息", value = "获取订单首联人信息")
    public ResponseMessage2 getConnectUser(@RequestParam(value = "id") String id, @RequestParam(value = "omeId") Integer omeId) {
        return ResponseMessage2.Success2(nodeService.getConnectUser(id, omeId));
    }

    @RequestMapping(value = "/getConnectConfig", method = RequestMethod.GET)
    @ApiOperation(notes = "获取首联订单尾号配置信息", value = "获取首联订单尾号配置信息")
    public ResponseMessage2 getConnectConfig() {
        return ResponseMessage2.Success2(nodeService.getConnectConfig());
    }

    @RequestMapping(value = "/saveConnectConfig", method = RequestMethod.POST)
    @ApiOperation(notes = "保存首联订单尾号配置信息", value = "保存首联订单尾号配置信息")
    public ResponseMessage2 saveConnectConfig(@RequestBody ConnectConfigBO item) {
        try {
            nodeService.saveConnectConfig(item);
        } catch (Exception ex) {
            return ResponseMessage2.Failed("保存失败:" + ex.getMessage());
        }
        return ResponseMessage2.Success();
    }


    /**
     * 获取所有用户组
     *
     * @param groupName
     * @return
     */
    @RequestMapping(value = "/getAllGroup", method = RequestMethod.GET)
    @ApiOperation(notes = "获取所有用户组", value = "获取所有用户组")
    public ResponseMessage2 getAllGroup(String groupName) {
        List<GroupPO> list = groupService.selectAll();
        if (!list.isEmpty() && StrUtil.isNotEmpty(groupName)) {
            list = list.stream().filter(s -> s.getGroupName().contains(groupName)).collect(Collectors.toList());
        }
        return ResponseMessage2.Success2(list);
    }


    @RequestMapping(value = "/save/group", method = RequestMethod.POST)
    @ApiOperation("保存用户组")
    public ResponseMessage2 saveGroup(@RequestBody GroupBO vo) {
        SessionInfo currentUser = ProcessUtil.getUserInfo();
        if (null == currentUser) {
            return ResponseMessage2.Failed(ResponseStatus.ForbiddenAccess.getIndex(), ProcessUtil.RE_LOGIN);
        }
        GroupPO po = vo.toPo();
        if (po.getGroupId() == null) {
            po.setGroupId(IdUtil.getLongUUID());
            po.setCreateUserId(Convert.toLong(currentUser.getUserId()));
            po.setCreateUserName(currentUser.getUserName());
            groupService.insertSelective(po);
        } else {
            po.setUpdateTime(new Date());
            groupService.updateByPrimaryKeySelective(po);
        }
        Boolean status = nodeService.updateGroupUsers(po.getGroupId(), po.getUserIds());
        if (!status) {
            return ResponseMessage2.Failed("添加失败");
        }
        return ResponseMessage2.Success();
    }

    /**
     * @param entity
     * @return
     */
    @RequestMapping(value = "/save/flow", method = RequestMethod.POST)
    @ApiOperation(notes = "添加", value = "添加流程")
    public ResponseMessage2 insertFlow(@RequestBody FlowPO entity) {
        try {
            if (StrUtil.isEmpty(entity.getFlowCode())) {
                return ResponseMessage2.Failed("流程标识为空");
            }
            if (StrUtil.isEmpty(entity.getFlowName())) {
                return ResponseMessage2.Failed("流程名称为空");
            }
            if (StrUtil.isEmpty(entity.getCategoryName())) {
                return ResponseMessage2.Failed("功能为空");
            }
            if (entity.getFlowId() == null) {
                if (!flowService.checkFlow(entity)) {
                    return ResponseMessage2.Failed("该流程标识或名已存在");
                }
                int status = flowService.insert(entity);
                if (status > 0) {
                    return ResponseMessage2.Success();
                }
                return ResponseMessage2.Failed("添加流程失败!");
            }
            int status = flowService.updateByPrimaryKey(entity);
            if (status > 0) {
                return ResponseMessage2.Success();
            }
            return ResponseMessage2.Failed("修改流程失败!");
        } catch (Exception e) {
            return ResponseMessage2.Failed(e.getMessage());
        }
    }

    @RequestMapping(value = "/delete/flow", method = RequestMethod.GET)
    @ApiOperation(notes = "根据ID删除", value = "删除流程")
    public ResponseMessage2 deleteFlow(Long flowId) {
        try {
            int status = flowService.deleteByPrimaryKey(flowId);
            if (status > 0) {
                return ResponseMessage2.Success();
            }
            return ResponseMessage2.Failed("删除流程失败!");
        } catch (Exception e) {
            log.error("deleteFlow error:", e);
            return ResponseMessage2.Failed(e.getMessage());
        }
    }

    @RequestMapping(value = "/getAllCategory", method = RequestMethod.GET)
    @ApiOperation(notes = "查询所有功能", value = "查询所有功能")
    public ResponseMessage2 selectAllCategory() {
        List<String> result = flowService.selectAllCategory();
        return ResponseMessage2.Success2(result);
    }

    @RequestMapping(value = "/getAllFlow", method = RequestMethod.GET)
    @ApiOperation(notes = "查询所有流程", value = "查询所有流程")
    public ResponseMessage2 selectAllFlow() {
        List<FlowVO> result = flowService.selectAllFlow();
        return ResponseMessage2.Success2(result);
    }

    /**
     * @param categoryName
     * @param flowName
     * @return
     */
    @GetMapping(value = "/getFlowByName")
    @ApiOperation(notes = "根据名称查询流程", value = "根据名称查询")
    public ResponseMessage2 getFlowByName(String categoryName, String flowName) {
        return ResponseMessage2.Success2(flowService.getFlowByName(categoryName, flowName));
    }

    /**
     * @param flowId
     * @return
     */
    @GetMapping(value = "/getFlowById")
    @ApiOperation(notes = "根据FlowId查询流程", value = "根据FlowId查询")
    public ResponseMessage2 selectByName(Long flowId) {
        return ResponseMessage2.Success2(flowService.selectByPrimaryKey(flowId));
    }
}