package cn.axzo.msg.center.message.service.todo.manage;

import cn.axzo.maokai.api.vo.response.tree.ValueNode;
import cn.axzo.msg.center.domain.entity.MessageGroupNode;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig;
import cn.axzo.msg.center.message.service.group.GroupTemplateService;
import cn.axzo.msg.center.message.service.group.NodeWrapper;
import cn.axzo.msg.center.message.service.group.TemplateGroups;
import cn.axzo.msg.center.service.enums.AppTerminalTypeEnum;
import cn.axzo.msg.center.service.pending.response.PendingMessageResponse;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import static java.util.stream.Collectors.toList;

/**
 * @author yanglin
 */
@Component
@RequiredArgsConstructor
public class TodoTerminalHelper {

    private final GroupTemplateService groupTemplateService;
    private final PendingMessageBizConfig cfg;

    public List<Todo> maybeFilterByTerminal(List<Todo> todos, @Nullable List<AppTerminalTypeEnum> terminals) {
        if (CollectionUtils.isEmpty(terminals))
            return todos;
        List<ValueNode<NodeWrapper>> todoGroups = groupTemplateService.getTodoGroups(terminals);
        List<String> templateCodes = groupTemplateService.collectTemplateCodes(todoGroups);
        return todos.stream()
                .filter(todo -> templateCodes.contains(todo.getTemplateCode()))
                .collect(toList());
    }

    public void populateTemplateTerminals(List<PendingMessageResponse> responses) {
        if (CollectionUtils.isEmpty(responses)) return;
        List<String> templateCodes = responses.stream()
                .map(PendingMessageResponse::getTemplateCode)
                .collect(toList());
        TemplateGroups templateGroups = groupTemplateService.getTemplateGroups(templateCodes);
        Map<Long, AppTerminalTypeEnum> nodeId2Terminal = cfg.fetchNodeId2Terminal();
        Function<String, List<AppTerminalTypeEnum>> collector = templateCode -> {
            ArrayList<AppTerminalTypeEnum> terminals = new ArrayList<>();
            for (MessageGroupNode node : templateGroups.collectPathNodes(templateCode)) {
                if (nodeId2Terminal.containsKey(node.getId()))
                    terminals.add(nodeId2Terminal.get(node.getId()));
            }
            return terminals;
        };
        for (PendingMessageResponse response : responses) {
            List<AppTerminalTypeEnum> terminals = collector.apply(response.getTemplateCode());
            response.setTemplateTerminals(terminals);
        }
    }

}