/* © SRSoftware 2025 */
package de.srsoftware.umbrella.message.model;

import static de.srsoftware.umbrella.core.ModuleRegistry.translator;
import static de.srsoftware.umbrella.core.Util.dateTimeOf;
import static java.lang.System.Logger.Level.DEBUG;
import static java.lang.System.Logger.Level.TRACE;
import static java.text.MessageFormat.format;

import de.srsoftware.umbrella.core.model.*;
import java.util.*;

public class CombinedMessage {
	private static final System.Logger LOG = System.getLogger(CombinedMessage.class.getSimpleName());

	private final Set<Attachment> attachments = new HashSet<>();
	private final StringBuilder combinedBody = new StringBuilder();
	private final User receiver;
	private final String lang;
	private final User fallbackSender;
	private String combinedSubject = null;
	private final List<Message<?>> mergedMessages = new ArrayList<>();
	private final Translatable subjectForCombinedMessage;
	private User sender = null;
	public static final String SEPARATOR = "\n\n━━━━━━━━━━━━━━━━━━━━━\n\n";

	public CombinedMessage(Translatable subjectForCombinedMessage, User receiver, User fallbackSender){
		LOG.log(DEBUG,"Creating combined message for {0}…",receiver);
		this.subjectForCombinedMessage = subjectForCombinedMessage;
		this.receiver = receiver;
		this.lang = receiver.language();
		this.fallbackSender = fallbackSender;
	}

	public void addNote() {
		var text = translator().translate(lang,"You may change your notification settings at {base_url}/message/settings");
		combinedBody.append(SEPARATOR).append(text);
	}

	public Set<Attachment> attachments() {
		return attachments;
	}

	public String body() {
		return combinedBody.toString();
	}

	public void merge(Message<?> message) {
		LOG.log(TRACE,"Merging {0} into combined message…",message);

		if (message instanceof TranslatableMessage tm) message = tm.translate(lang);
		var body = message.body();
		var subject = message.subject().toString();
		switch (mergedMessages.size()){
			case 0:
				combinedBody.append(body);
				sender = message.sender();
				combinedSubject = subject;
				break;
			case 1:
				combinedBody.insert(0,format("# {0} @ {1}\n→ {2}:\n\n",sender, dateTimeOf(mergedMessages.getFirst().utcTime()),subject)); // insert sender and subject of first message right before the body of the first message
				combinedSubject = subjectForCombinedMessage.translate(lang);
				// no break here, we need to append the subject and content
			default:
				if (!sender.equals(message.sender())) sender = fallbackSender;
				combinedBody.append(SEPARATOR).append("# ").append(message.sender()).append(" @ ").append(dateTimeOf(message.utcTime())).append("\n→ ").append(subject).append(":\n\n");
				combinedBody.append(body);
		}
		if (message.attachments() != null) attachments.addAll(message.attachments());
		mergedMessages.add(message);
	}

	public List<Message<?>> messages() {
		return mergedMessages;
	}

	public User receiver(){
		return receiver;
	}

	public User sender() {
		return sender;
	}

	public String subject() {
		return combinedSubject;
	}

	@Override
	public String toString() {
		var body	 = body();
		if (body.length()>100) body = body.substring(0,99)+"…";
		return format("{0} for {1} ({2}): {3}",getClass().getSimpleName(),receiver.email(),subject(),body);
	}
}
