package com.usky.oa.service.utils;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.oa.domain.*;
import com.usky.oa.mapper.OaFlowMapper;
import com.usky.oa.mapper.OaNodeMapper;
import com.usky.oa.mapper.SysDeptMapper;
import com.usky.oa.mapper.SysUserMapper;
import com.usky.system.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;

/**
 *
 * @author fyc
 * @email yuchuan.fu@chinausky.com
 * @date 2025/2/21
 */
@Slf4j
@Service
public class OaApprovalGeneration {

    @Autowired
    private OaFlowMapper oaFlowMapper;

    @Autowired
    private OaNodeMapper oaNodeMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * @description: 新增流程与节点信息
     * @author: fyc
     * @email yuchuan.fu@chinausky.com
     * @date: 2025/2/21 19:23
     * @param: [oaFormDefinition]
     * @return: void
     **/
    public void addGenerate(OaFormDefinition oaFormDefinition) {
        // 新增流程数据
        OaFlow oaFlow = new OaFlow();
        oaFlow.setFormId(oaFormDefinition.getId());
        oaFlow.setFlowName(oaFormDefinition.getFormName() + "的流程");
        oaFlow.setDocType(oaFormDefinition.getFormSign());
        oaFlow.setDescription(oaFormDefinition.getFormExplain());
        oaFlow.setCreateBy(oaFormDefinition.getCreateBy());
        oaFlow.setCreateTime(oaFormDefinition.getCreateTime());
        oaFlow.setDeptId(oaFormDefinition.getDeptId());
        oaFlow.setTenantId(oaFormDefinition.getTenantId());
        oaFlowMapper.insert(oaFlow);

        String flowInfo = oaFormDefinition.getFlowInfo();
        Integer flowId = oaFlow.getId();

        // 获取JSON字符串内的node节点信息
        if (StringUtils.isBlank(flowInfo)) {
            throw new BusinessException("节点信息为空！请联系管理员");
        }
        JSONObject jsonObject = JSONObject.parseObject(flowInfo);
        if (jsonObject.containsKey("node")) {
            List<JSONObject> nodeList = jsonObject.getJSONArray("node").toJavaList(JSONObject.class);
            // 用于记录上一个节点的 ID
            Integer lastNodeId = null;

            for (JSONObject node : nodeList) {
                String nodeNo = node.getString("nodebh");
                String nodeName = node.getString("nodeName");
                Integer nodeType = node.getInteger("nodeType");
                Integer nodeScope = node.getInteger("nodeScope");
                String proposer = null;
                Integer deptId2 = null;
                Integer jobId = null;

                switch (nodeScope) {
                    case 0:
                        proposer = node.getString("appointApprover");
                        break;
                    case 1:
                    case 2:
                        break;
                    case 3:
                        deptId2 = node.getInteger("deptId");
                        break;
                    case 4:
                        jobId = node.getInteger("jobId");
                        break;
                    default:
                        throw new BusinessException("节点权限范围不正确");
                }

                OaNode oaNode = new OaNode();
                oaNode.setFlowId(flowId);
                oaNode.setNodeNo(nodeNo);
                oaNode.setNodeName(nodeName);
                oaNode.setNodeType(nodeType);
                oaNode.setNodeScope(nodeScope);
                oaNode.setProposer(proposer);
                oaNode.setDeptId(deptId2);
                oaNode.setJobId(jobId);
                // 使用上一个节点的 ID 作为父节点，第一个节点的父节点 ID 设置为 0
                oaNode.setParentId(lastNodeId == null ? 0 : lastNodeId);
                oaNodeMapper.insert(oaNode);

                // 更新 lastNodeId 为当前节点的 ID
                lastNodeId = oaNode.getId();
            }
        }
    }

    public void updateGenerate(OaFormDefinition oaFormDefinition) {
        Integer formId = oaFormDefinition.getId();
        OaFlow flow = oaFlowMapper.selectOne(Wrappers.lambdaQuery(OaFlow.class).eq(OaFlow::getFormId, formId));
        Integer flowId = flow.getId();

        flow.setFlowName(oaFormDefinition.getFormName() + "的流程");
        flow.setDescription(oaFormDefinition.getFormExplain());
        flow.setUpdateBy(oaFormDefinition.getUpdateBy());
        flow.setUpdateTime(oaFormDefinition.getUpdateTime());
        oaFlowMapper.updateById(flow);

        String flowInfo = oaFormDefinition.getFlowInfo();
        JSONObject jsonObject = JSONObject.parseObject(flowInfo);
        if (jsonObject.containsKey("node")) {
            List<JSONObject> nodeList = jsonObject.getJSONArray("node").toJavaList(JSONObject.class);
            // 用于记录上一个节点的 ID
            Integer lastNodeId = null;

            for (JSONObject node : nodeList) {
                String nodeNo = node.getString("nodebh");
                String nodeName = node.getString("nodeName");
                Integer nodeType = node.getInteger("nodeType");
                Integer nodeScope = node.getInteger("nodeScope");
                String proposer = null;
                Integer deptId2 = null;
                Integer jobId = null;

                switch (nodeScope) {
                    case 0:
                        proposer = node.getString("appointApprover");
                        break;
                    case 1:
                    case 2:
                        break;
                    case 3:
                        deptId2 = node.getInteger("deptId");
                        break;
                    case 4:
                        jobId = node.getInteger("jobId");
                        break;
                    default:
                        throw new BusinessException("节点权限范围不正确");
                }

                OaNode oaNode = new OaNode();
                oaNode.setNodeName(nodeName);
                oaNode.setNodeType(nodeType);
                oaNode.setNodeScope(nodeScope);
                oaNode.setProposer(proposer);
                oaNode.setDeptId(deptId2);
                oaNode.setJobId(jobId);
                oaNode.setParentId(lastNodeId);
                oaNodeMapper.update(oaNode, new LambdaQueryWrapper<OaNode>().eq(OaNode::getFlowId, flowId).eq(OaNode::getNodeNo, nodeNo));
                lastNodeId = oaNode.getId();
            }
        }
    }

    public void nodeSave(JSONObject jsonObject, String sign) {
        Integer flowId = selectBySign(sign).getId();
        List<JSONObject> nodeList = jsonObject.getJSONArray("node").toJavaList(JSONObject.class);
        String proposer = null;
        for (JSONObject node : nodeList) {
            String nodeNo = node.getString("nodebh");
            Integer nodeScope = node.getInteger("nodeScope");
            proposer = node.getString("appointApprover");

            OaNode oaNode = new OaNode();
            if (nodeScope == 1) {
                oaNode.setProposer(getDeptLeader().toString());
            } else if (nodeScope == 2) {
                oaNode.setProposer(proposer);
            }
            oaNodeMapper.update(oaNode, new LambdaQueryWrapper<OaNode>().eq(OaNode::getFlowId, flowId).eq(OaNode::getNodeNo, nodeNo));
        }
    }

    public Long getDeptLeader() {
        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        Integer tenantId = SecurityUtils.getTenantId();

        LambdaQueryWrapper<SysDept> deptLeaderQuery = new LambdaQueryWrapper<>();
        deptLeaderQuery.eq(SysDept::getTenantId, tenantId)
                .eq(SysDept::getDeptId, deptId)
                .select(SysDept::getLeader);
        SysDept deptLeader = sysDeptMapper.selectOne(deptLeaderQuery);
        return Long.valueOf(deptLeader.getLeader());
    }

    // 根据单据类型获取流程信息
    public OaFlow selectBySign(String sign) {
        return oaFlowMapper.selectOne(Wrappers.lambdaQuery(OaFlow.class).eq(OaFlow::getDocType, sign));
    }

    // 根据流程ID获取节点信息
    public OaNode selectByFlowId(Integer flowId) {
        LambdaQueryWrapper<OaNode> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(OaNode::getFlowId, flowId)
                .orderByAsc(OaNode::getId);
        return oaNodeMapper.selectList(queryWrapper).get(0);
    }

}
