package cn.axzo.msg.center.message.send.processor;

import cn.axzo.basics.common.util.AssertUtil;
import cn.axzo.msg.center.api.request.GeneralMessageReq;
import cn.axzo.msg.center.domain.enums.BizActionCategory;
import cn.axzo.msg.center.message.service.BizEventMappingService;
import cn.axzo.msg.center.message.service.PendingMessageNewService;
import cn.axzo.msg.center.service.dto.PersonDTO;
import cn.axzo.msg.center.service.enums.BizCategoryEnum;
import cn.axzo.msg.center.service.enums.IdentityTypeEnum;
import cn.axzo.msg.center.service.enums.OrganizationTypeEnum;
import cn.axzo.msg.center.service.pending.request.PendingMessagePushRequest;
import cn.axzo.msg.center.utils.PersonIdentityUtil;
import cn.hutool.core.collection.CollUtil;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author syl
 * @date 2023/12/18
 */
@Slf4j
@Component
public class PendingProcessor implements ISendProcessor {

    @Autowired
    private PendingMessageNewService pendingMessageNewService;

    @Autowired
    private BizEventMappingService bizEventMappingService;

    @Override
    public void check(SendContext context) {
        AssertUtil.notNull(context.getMessageParam(), "待办消息的参数错误，请检查");
        AssertUtil.isTrue(CollUtil.isNotEmpty(context.getToIdMessageRecordMap()), "待办消息的人员信息不存在");
        AssertUtil.notNull(context.getReachConfig(), "触达配置不能为空");
        AssertUtil.isTrue(BizActionCategory.PENDING.getCode().equals(context.getReachConfig()
                .getCategory()), "待办业务动作不匹配");

        bizEventMappingService.checkTemplateCodeByBizEvent(context.getReachConfig());
    }

    @Override
    public void send(SendContext context) {
        // 检查
        this.check(context);
        log.info("PendingProcessor start to async send pending message. bizCode= [{}]"
                        + ", templateCode= [{}]", context.getBizEvent().getBizCode(),
                context.getReachConfig().getTemplateCode());

        // 由于之前业务方这期未做改造，而之前对外提供的参数只满足消息，待办这块的发送需要定义待办相关的业务属性
        // 迁移到新接口
//        PendingMessagePushRequest request = buildSendRequest(context);
//        pendingMessageNewService.push(PendingMessagePushParam.from(request));
    }


    private PendingMessagePushRequest buildSendRequest(SendContext context) {
        GeneralMessageReq request = context.getMessageParam();
        String templateCode = context.getReachConfig().getTemplateCode();
        Collection<Long> subReceiverIds = context.getToIdMessageRecordMap().keySet();

        PersonDTO promoter = PersonDTO.from(null, request.getFromId(), null);
        IdentityTypeEnum identityType = PersonIdentityUtil.toIdentityType(request.getReceiveType());
        List<PersonDTO> receivers = subReceiverIds.stream()
                .filter(request.getToldIdPersonIdMap()::containsKey)
                .map(e -> PersonDTO.from(request.getToldIdPersonIdMap().get(e), e, identityType))
                .collect(Collectors.toList());
        OrganizationTypeEnum orgType = Objects.isNull(request.getTerminalType()) ? OrganizationTypeEnum.UNKNOWN :
                OrganizationTypeEnum.valueOf(request.getTerminalType().name());
        return PendingMessagePushRequest.builder()
                .templateCode(templateCode)
                .promoter(promoter)
                .executor(receivers)
                .orgType(orgType)
                .workspaceId(request.getTerminalId())
                .ouId(null)
                .bizCategory(BizCategoryEnum.OTHER)
                .bizCode(Optional.ofNullable(request.getBizId()).map(String::valueOf).orElse(""))
                .routerParams(null)
                .bizExtParams(null)
                .build();
    }

    @Override
    public void checkReach(ReachContext context) {

    }
    @Override
    public void reach(ReachContext context) {
        // 等后续im具有待办消息的能力，再接入，目前统一走待办中心
    }

    @Override
    public void save(ReachContext context) {
    }
}
