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

import cn.axzo.msg.center.api.request.v3.MessageSendReqV3;
import cn.axzo.msg.center.api.request.v3.PendingSendInfo;
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.MessageTemplateDTO;
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.bizevent.request.ReachDto;
import cn.axzo.msg.center.service.dto.PersonDTO;
import cn.axzo.msg.center.service.dto.PersonV3DTO;
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 MessageSendReqV3 sendRequestV3;
    private String sendRequestNo;
    private MessageTemplateDTO template;
    private ReachDto reachConfig;

    private List<PushPendingMessageDTO> sendResults;

    @Override
    public void saveRecords() {
        PendingSendInfo pendingInfo = sendRequestV3.getChannelParam(
                MessageSendReqV3.CHANNEL_PENDING, PendingSendInfo.class);
        PendingMessagePushParam request = new PendingMessagePushParam();
        if (pendingInfo != null)
            BeanUtils.copyProperties(pendingInfo, request);
        request.setPromoter(sendRequestV3.getSender() == null ? null : sendRequestV3.getSender().asV1());
        request.setExecutor(convertReceivers(sendRequestV3.getReceivers()));
        request.setTemplateCode(template.getCode());
        request.setOuId(sendRequestV3.getReceiversOuId());
        request.setWorkspaceId(sendRequestV3.getReceiversWorkspaceId());
        request.setPromoterOuId(sendRequestV3.getSenderOuId());
        request.setPromoterWorkspaceId(sendRequestV3.getSenderWorkspaceId());
        request.setBizCode(sendRequestV3.getBizCode());
        request.setOrgType(sendRequestV3.getReceiversOrgType());
        request.setBizExtParams(sendRequestV3.getBizExtParams() == null
                ? null : sendRequestV3.getBizExtParams().toJSONString());
        request.setRouterParams(sendRequestV3.getRouterParams() == null
                ? null : sendRequestV3.getRouterParams().toJSONString());
        TodoRequestContext ctx = TodoRequestContext.create(
                "MessageAPIV3#send", sendRequestNo, sendRequestV3);
        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(
                template.getCode(), reachConfig.getCategory());
        for (PushPendingMessageDTO todoResult : sendResults)
            resultV3.addResult(new MessageSendResultV3(
                    todoResult.getExecutorPersonId(), todoResult.getId()));
        return resultV3;
    }

}