package com.junmp.junmpProcess.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.junmp.junmpProcess.dto.StartProcessInstanceDTO;
import com.junmp.junmpProcess.factory.FlowServiceFactory;
import com.junmp.junmpProcess.service.IFlowInstanceService;
import com.junmp.jyzb.api.bean.req.UpdateOrderDetailReq;
import com.junmp.jyzb.api.bean.req.UpdateOrderReq;
import com.junmp.jyzb.api.exception.enums.CabinetBoxExceptionEnum;
import com.junmp.jyzb.api.exception.enums.OrderExceptionEnum;
import com.junmp.v2.auth.api.bean.login.LoginUser;
import com.junmp.v2.auth.api.context.LoginContext;
import com.junmp.v2.common.bean.response.ApiRes;
import com.junmp.v2.common.exception.IExceptionEnum;
import com.junmp.v2.common.exception.base.ServiceException;
import com.junmp.v2.common.util.BeanPlusUtil;
import com.junmp.v2.sys.user.entity.SysUser;
import com.junmp.v2.sys.user.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricActivityInstanceQuery;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceBuilder;
import org.flowable.task.api.Task;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.junmp.junmpProcess.common.CommonConstants.*;
import static com.junmp.junmpProcess.common.CommonConstants.BUSINESS_STATUS_1;
import static com.junmp.junmpProcess.common.WorkFlowConstants.PROCESS_PREFIX;

@Service
@Slf4j
public class FlowInstanceServiceImpl extends FlowServiceFactory implements IFlowInstanceService {
    @Resource
    private SysUserService sysUserService;


    @Override
    public void updateState(Integer state, String instanceId) {
        // 激活
        if (state == 1) {
            runtimeService.activateProcessInstanceById(instanceId);
        }
        // 挂起
        if (state == 2) {
            runtimeService.suspendProcessInstanceById(instanceId);
        }
    }

    /**
     * 删除流程实例ID
     *
     * @param instanceId   流程实例ID
     * @param deleteReason 删除原因
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String instanceId, String deleteReason) {

        // 查询历史数据
        HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(instanceId);
        if (historicProcessInstance.getEndTime() != null) {
            historyService.deleteHistoricProcessInstance(historicProcessInstance.getId());
            return;
        }
        // 删除流程实例
        runtimeService.deleteProcessInstance(instanceId, deleteReason);
        // 删除历史流程实例
        historyService.deleteHistoricProcessInstance(instanceId);
    }

    /**
     * 根据实例ID查询历史实例数据
     *
     * @param processInstanceId
     * @return
     */
    @Override
    public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) {
        HistoricProcessInstance historicProcessInstance =
                historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if (Objects.isNull(historicProcessInstance)) {
            throw new FlowableObjectNotFoundException("流程实例不存在: " + processInstanceId);
        }
        return historicProcessInstance;
    }

    ///获取下一个审核人信息
    @Override
   public String GetNextAssign(String processInstanceId)
    {
                String assigneeString="";

                    Object assigneeObject = runtimeService.getVariable(processInstanceId, "currentAssignee");

                    if (assigneeObject instanceof List) {
                        List<String> assigneeList = (List<String>) assigneeObject;

                         assigneeString = String.join(",", assigneeList);

                        // 现在 assigneeString 中包含了集合元素用逗号拼接的字符串
                    }

                return  assigneeString;
    }
    @Override
    public String startProcessInstanceById(StartProcessInstanceDTO processInstanceDto) {
        SysUser StartUser=new SysUser();
        if (processInstanceDto.getUserId()!=null)//优先拿接口中的信息，方便调试
        {
            StartUser = sysUserService.getById(processInstanceDto.getUserId());
        }
        else
        {
            StartUser= sysUserService.getById(LoginContext.getContext().getLoginUser());
        }
        JSONObject formData = processInstanceDto.getFormData();
        Authentication.setAuthenticatedUserId(StartUser.getUserId().toString());
        Map<String,Object> processVariables= new HashMap<>();
        processVariables.put(FORM_VAR,formData);
        processVariables.put(FORM_Trigger,processInstanceDto.getTriggerId());//获取触发器信息
        processVariables.put(ORDER_ID,processInstanceDto.getOrderId());
        processVariables.put(TYPE_ORDER,processInstanceDto.getTypeOrder());
        processVariables.put(BUSSINESS_TYPE,processInstanceDto.getBussinessType());
        //单据类型
        processVariables.put(TYPE,processInstanceDto.getType());
        //发物单位
        if (ObjectUtil.isNotNull(processInstanceDto.getStartOrgName())){
            processVariables.put(START_ORG_NAME,processInstanceDto.getStartOrgName());
        }
        //收物单位
        if (ObjectUtil.isNotNull(processInstanceDto.getEndOrgName())){
            processVariables.put(END_ORG_NAME,processInstanceDto.getEndOrgName());
        }
        //装备名称拼接
        if (ObjectUtil.isNotNull(processInstanceDto.getInvList())){
            processVariables.put(INVLIST,processInstanceDto.getInvList());
        }
        //出入库状态
        if (ObjectUtil.isNotNull(processInstanceDto.getOutInState())){
            processVariables.put(OUT_IN_STATE,processInstanceDto.getOutInState());
        }
        processVariables.put(START_USER_INFO,JSONObject.toJSONString(StartUser));
        processVariables.put(AGENT_NAME,StartUser.getRealName());
        processVariables.put(PROCESS_STATUS,BUSINESS_STATUS_1);

        if (ObjectUtil.isNotNull(processInstanceDto.getEndUserName())){
            processVariables.put(END_USER_NAME,processInstanceDto.getEndUserName());
        }
        if (ObjectUtil.isNotNull(processInstanceDto.getStartUserName())){
            processVariables.put(START_USER_NAME,processInstanceDto.getStartUserName());
        }
        if (formData!=null)
        {
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            processVariables.putAll(formValue);
        }

        ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();
//        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(processInstanceDto.getProcessDefinitionId())
//                .latestVersion().singleResult();

        ProcessInstance processInstance = processInstanceBuilder
                .processDefinitionId(processInstanceDto.getProcessDefinitionId())
                .variable("initiator", StartUser != null ? StartUser.getUserId() : null)
                .variables(processVariables != null ? processVariables : Collections.emptyMap())
                .businessStatus(BUSINESS_STATUS_1)
                .start();

        // 从流程执行上下文中获取流程变量
        Object skip = runtimeService.getVariable(processInstance.getId(), "skip");

        if (ObjectUtils.isNotEmpty(skip) && BooleanUtils.toBoolean(skip.toString())){
            return "skip"+processInstance.getProcessInstanceId();
        }
        else{

            Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list().get(0);
            task.setAssignee(StartUser.getUserId().toString());
            return  processInstance.getProcessInstanceId();

        }


//        } catch (Exception e) {
//            String fullErrorMessage = getFullErrorMessage(e);
//            // 处理在启动流程实例时发生的异常
//            throw new ServiceException(OrderExceptionEnum.ROLE_ERROR);
////            throw new ServiceException(fullErrorMessage);
//
//        }
        //手动完成第一个任务

    }




    // 递归获取异常信息的方法
    private String getFullErrorMessage(Throwable throwable) {
        StringBuilder errorMessage = new StringBuilder();

        while (throwable != null) {
            errorMessage.append(throwable.getMessage()).append("\n");
            throwable = throwable.getCause();
        }

        return errorMessage.toString();
    }
    @Override
    public String getFormIdByInstanceId(String instanceId) {
        HistoricActivityInstance query = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(instanceId)
                .orderByHistoricActivityInstanceStartTime().asc()
                .listPage(0, 1).get(0);
        if (query != null) {
//            String[] parts = query.getProcessDefinitionId().split(":");
//            String pro=parts[0].replace(PROCESS_PREFIX, "");
//            return pro;
            String pattern = "Process_(\\d+):.*";
            Pattern regex = Pattern.compile(pattern);
            Matcher matcher = regex.matcher(query.getProcessDefinitionId());

            if (matcher.find()) {
                String extractedNumber = matcher.group(1);
                return  extractedNumber;
            } else {
                return  null;
            }


    }
    else  return  null;
    }
}
