package cn.axzo.msg.center.message.service.todo.card.workflow;

import cn.axzo.msg.center.common.utils.BizAssertions;
import cn.axzo.msg.center.dal.TodoBusinessDao;
import cn.axzo.msg.center.dal.TodoDao;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.domain.entity.TodoBusiness;
import cn.axzo.msg.center.message.service.card.interceptor.CardButtonInterceptor;
import cn.axzo.msg.center.message.service.card.interceptor.CardButtonInterceptorFactory;
import cn.axzo.msg.center.message.service.todo.card.TodoSyncCardService;
import cn.axzo.msg.center.message.service.todo.manage.TodoLogger;
import cn.axzo.msg.center.message.service.todo.manage.TodoRequestContext;
import cn.axzo.msg.center.service.enums.BizCategoryEnum;
import cn.axzo.msg.center.service.pending.request.CardContent;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskButtonSearchDTO;
import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskButtonVo;
import cn.axzo.workflow.starter.api.WorkflowCoreService;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Nullable;

/**
 * @author yanglin
 */
@Slf4j
@Component
@RequiredArgsConstructor
class WorkflowTodoCardButtonInterceptorFactory implements CardButtonInterceptorFactory {

    private final TodoBusinessDao todoBusinessDao;
    private final TodoDao todoDao;
    private final WorkflowCoreService workflowCoreService;
    private final TodoLogger todoLogger;

    @Override @Nullable
    public CardButtonInterceptor create(CardContent card) {
        BizCategoryEnum category = TodoSyncCardService.findTodoBizCategory(card.getBizParam()).orElse(null);
        if (category != BizCategoryEnum.FLOW)
            return null;
        String identityCode = TodoSyncCardService.findTodoIdentityCode(card.getBizParam()).orElse(null);
        if (identityCode == null)
            return null;
        Todo todo = todoDao.findTodoByCode(identityCode).orElse(null);
        if (todo == null) {
            log.warn("todo not found. identityCode={}", card.getBizParam());
            return null;
        }
        BpmnTaskButtonVo taskInfo = fetchWorkflowButtons(todo);
        log.info("fetchWorkflowButtons, todoIdentityCode={}, workflowTaskInfo: {}",
                todo.getIdentityCode(), JSON.toJSONString(taskInfo));
        TodoRequestContext ctx = TodoRequestContext.create("syncWorkflowButtons", card)
                .addLogContent("workflowTaskInfo", taskInfo);
        todoLogger.logTodoUpdated(ctx, todo);
        return new WorkflowTodoCardButtonInterceptor(todo, taskInfo);
    }

    BpmnTaskButtonVo fetchWorkflowButtons(Todo todo) {
        TodoBusiness business = todoBusinessDao.getBusinesses(todo).findBusiness(todo).orElse(null);
        BizAssertions.assertNotNull(business, "todo business not found. todoIdentityCode={}", todo.getIdentityCode());
        BpmnTaskButtonSearchDTO workflowRequest = new BpmnTaskButtonSearchDTO();
        workflowRequest.setProcessInstanceId(todo.getBizCode());
        workflowRequest.setTaskId(todo.getSubBizCode());
        workflowRequest.setInitiatorPersonId(business.getPromoterPersonId());
        workflowRequest.setExecutorPersonId(todo.getExecutorPersonId());
        return workflowCoreService.findProcessSingleTaskButtons(workflowRequest);
    }

}