package cn.axzo.msg.center.inside.notices.service.impl.v3.todo;

import cn.axzo.msg.center.api.request.v3.PendingSendInfo;
import cn.axzo.msg.center.api.request.v4.MessageSendBasicInfoV4;
import cn.axzo.msg.center.api.request.v4.MessageSendRequestV4;
import cn.axzo.msg.center.api.response.v3.MessageSendResultV3;
import cn.axzo.msg.center.api.response.v3.TemplateSendResultV3;
import cn.axzo.msg.center.inside.notices.service.impl.v3.EventMappingProcessor;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import cn.axzo.msg.center.message.domain.param.PendingMessagePushParam;
import cn.axzo.msg.center.message.service.todo.manage.TodoManager;
import cn.axzo.msg.center.message.service.todo.manage.TodoRequestContext;
import cn.axzo.msg.center.service.dto.PersonDTO;
import cn.axzo.msg.center.service.dto.PersonV3DTO;
import cn.axzo.msg.center.service.enums.Channel;
import cn.axzo.msg.center.service.pending.response.PushPendingMessageDTO;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author yanglin
 */
@Slf4j
@Setter
@Component
@Scope("prototype")
@RequiredArgsConstructor
public class TodoMappingProcessor implements EventMappingProcessor {

    private final TodoManager todoManager;
    private MessageSendRequestV4 req;
    private String sendRequestNo;
    private TemplateModelV3 templateModel;
    private Channel channel;

    private List<PushPendingMessageDTO> sendResults;

    @Override
    public void saveRecords() {
        PendingSendInfo pendingInfo = req.getPendingSendInfo();
        PendingMessagePushParam request = new PendingMessagePushParam();
        if (pendingInfo != null)
            BeanUtils.copyProperties(pendingInfo, request);
        MessageSendBasicInfoV4 sendBasicInfo = req.getSendBasicInfo();
        request.setPromoter(sendBasicInfo.getSender() == null ? null : sendBasicInfo.getSender().asV1());
        request.setExecutor(convertReceivers(sendBasicInfo.getReceivers()));
        request.setTemplateCode(templateModel.getTemplateCode());
        request.setOuId(sendBasicInfo.getReceiversOuId());
        request.setWorkspaceId(sendBasicInfo.getReceiversWorkspaceId());
        request.setPromoterOuId(sendBasicInfo.getSenderOuId());
        request.setPromoterWorkspaceId(sendBasicInfo.getSenderWorkspaceId());
        request.setBizCode(sendBasicInfo.getBizCode());
        request.setOrgType(sendBasicInfo.getReceiversOrgType());
        request.setBizExtParams(sendBasicInfo.getBizExtParams() == null
                ? null : sendBasicInfo.getBizExtParams().toJSONString());
        request.setRouterParams(sendBasicInfo.getRouterParams() == null
                ? null : sendBasicInfo.getRouterParams().toJSONString());
        TodoRequestContext ctx = TodoRequestContext.create(
                "MessageAPIV3#send", sendRequestNo, sendBasicInfo);
        sendResults = todoManager.send(ctx, request);
    }

    private List<PersonDTO> convertReceivers(List<PersonV3DTO> executors) {
        if (executors == null)
            return null;
        return executors.stream()
                .filter(Objects::nonNull)
                .map(PersonV3DTO::asV1)
                .collect(Collectors.toList());
    }

    @Override
    public void maybeAsyncSend() {
        // NOP
    }

    @Override
    public TemplateSendResultV3 buildTemplateSendResult() {
        TemplateSendResultV3 resultV3 = new TemplateSendResultV3(
                templateModel.getTemplateCode(), channel.name());
        for (PushPendingMessageDTO todoResult : sendResults)
            resultV3.addResult(new MessageSendResultV3(
                    todoResult.getExecutorPersonId(), todoResult.getId()));
        return resultV3;
    }

}