package com.storlead.message.contract.support;

import com.storlead.message.contract.MessageEventPort;
import com.storlead.message.contract.MessageVariables;
import com.storlead.message.contract.RowIdentity;
import com.storlead.message.service.impl.MessageService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * {@link MessageEventPort} 的默认实现，委托给 {@link MessageService}。
 */
@Service
public class MessageEventPortImpl implements MessageEventPort {

    @Resource
    private MessageService messageService;

    @Override
    public void fireDataChangeMessages(MessageVariables before, MessageVariables after, String templateServiceCode) {
        messageService.autoMatchEventSendMessage(toEngineMap(before), toEngineMap(after), templateServiceCode);
    }

    @Override
    public void fireDataChangeMessages(MessageVariables before, MessageVariables after, String templateServiceCode, String... channels) {
        messageService.autoMatchEventSendMessage(toEngineMap(before), toEngineMap(after), templateServiceCode, channels);
    }

    @Override
    public void fireByTemplateServiceTypeAndEvent(MessageVariables payload, String templateServiceType, String eventCode, Set<Long> toUserIds, String... args) {
        messageService.autoMatchEventSendMessage(toEngineMap(payload), templateServiceType, eventCode, toUserIds, args);
    }

    @Override
    public MessageVariables snapshotBeforeRow(RowIdentity row) {
        Map<String, Object> rowKey = new HashMap<>(2);
        rowKey.put("id", row.getId());
        @SuppressWarnings("unchecked")
        Map<String, Object> raw = messageService.getOldMapData(rowKey, row.getFieldColumn(), row.getTable());
        if (raw == null || raw.isEmpty()) {
            return MessageVariables.empty();
        }
        return MessageVariables.fromMap(raw);
    }

    private static Map<String, Object> toEngineMap(MessageVariables v) {
        if (v == null || v.isEmpty()) {
            return new HashMap<>();
        }
        Map<String, Object> m = new HashMap<>();
        v.forEach(m::put);
        return m;
    }
}
