package cn.axzo.workflow.core.service.impl;

import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum;
import cn.axzo.workflow.common.model.request.bpmn.task.ExtHiTaskSearchDTO;
import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst;
import cn.axzo.workflow.core.repository.mapper.ExtAxHiTaskInstMapper;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;

/**
 * 流程定义扩展表操作服务实现
 *
 * @author wangli
 * @since 2023/11/18 22:27
 */
@Service
@Slf4j
public class ExtAxHiTaskInstServiceImpl implements ExtAxHiTaskInstService {
    @Resource
    private ExtAxHiTaskInstMapper extAxHiTaskInstMapper;

    @Override
    public void save(ExtAxHiTaskInst entity) {
        extAxHiTaskInstMapper.insert(entity);
    }

    @Override
    public void update(ExtAxHiTaskInst entity) {
        extAxHiTaskInstMapper.updateById(entity);
    }

    @Override
    public List<ExtAxHiTaskInst> queryList(ExtHiTaskSearchDTO dto) {
        QueryWrapper<ExtAxHiTaskInst> queryWrapper = new QueryWrapper<ExtAxHiTaskInst>()
                .eq(StringUtils.hasLength(dto.getProcessInstanceId()), "proc_inst_id", dto.getProcessInstanceId())
                .eq(StringUtils.hasLength(dto.getTaskDefinitionKey()), "task_definition_key", dto.getTaskDefinitionKey())
                .eq(StringUtils.hasLength(dto.getTaskId()), "task_id", dto.getTaskId())
                .eq(Objects.nonNull(dto.getStatus()), "status", Objects.isNull(dto.getStatus()) ? "" :
                        dto.getStatus().getStatus())
                .eq(StringUtils.hasLength(dto.getAssignee()), "assignee", dto.getAssignee());
        return extAxHiTaskInstMapper.selectList(queryWrapper);
    }

    @Override
    public ExtAxHiTaskInst getByTaskId(String taskId, String processInstanceId) {
        QueryWrapper<ExtAxHiTaskInst> queryWrapper = new QueryWrapper<ExtAxHiTaskInst>()
                .eq("task_id", taskId)
                .eq("proc_inst_id", processInstanceId);
        return extAxHiTaskInstMapper.selectOne(queryWrapper);
    }

    @Override
    public void deleteStatusByTaskId(String taskId, String processInstanceId) {
        ExtAxHiTaskInst taskInst = getByTaskId(taskId, processInstanceId);
        taskInst.setStatus(BpmnProcessInstanceResultEnum.DELETED.getStatus());
        extAxHiTaskInstMapper.updateById(taskInst);
    }

    @Override
    public void updateByTaskIdAndInstanceId(String taskId, String processInstanceId, String assignee, BpmnProcessInstanceResultEnum resultEnum) {
        ExtAxHiTaskInst existence = getByTaskId(taskId, processInstanceId);
        if (Objects.nonNull(existence)) {
            log.info("更新扩展任务实例表数据: taskId:{}, instanceId:{}, currentStatus:{}, anticipateStatus: {}",
                    taskId, processInstanceId, existence.getStatus(), resultEnum.getStatus());
        } else {
            log.warn("无法正确更新扩展任务表数据: taskId:{}, instanceId:{}, anticipateStatus: {}",
                    taskId, processInstanceId, resultEnum.getStatus());
        }
        ExtAxHiTaskInst entity = new ExtAxHiTaskInst();
        if (StringUtils.hasText(assignee)) {
            entity.setAssignee(assignee);
        }
        entity.setStatus(resultEnum.getStatus());

        LambdaUpdateWrapper<ExtAxHiTaskInst> wrapper = new LambdaUpdateWrapper<ExtAxHiTaskInst>()
                .eq(ExtAxHiTaskInst::getTaskId, taskId)
                .eq(ExtAxHiTaskInst::getProcInstId, processInstanceId)
                // 可能由于事件消费时, 嵌套了引擎操作, 会引起一部分的消息顺序异常, 导致状态被异常变更
                .eq(ExtAxHiTaskInst::getStatus, PROCESSING.getStatus());
        extAxHiTaskInstMapper.update(entity, wrapper);
    }
}
