/* © SRSoftware 2025 */
package de.srsoftware.umbrella.messagebus.events;


import static de.srsoftware.umbrella.core.ModuleRegistry.*;
import static de.srsoftware.umbrella.core.constants.Field.*;
import static de.srsoftware.umbrella.core.constants.Module.TASK;
import static de.srsoftware.umbrella.core.model.Translatable.t;
import static de.srsoftware.umbrella.messagebus.events.Event.EventType.MEMBER_ADDED;

import de.srsoftware.umbrella.core.constants.Field;
import de.srsoftware.umbrella.core.model.*;
import java.util.Collection;
import java.util.List;
import java.util.Map;


public class TaskEvent extends Event<Task>{
	private final UmbrellaUser newMember;

	public TaskEvent(UmbrellaUser initiator, Task task, EventType type){
		super(initiator, TASK, task, type);
		newMember = null;
	}

	public TaskEvent(UmbrellaUser initiator, Task task, Map<String, Object> oldData){
		super(initiator, TASK, task, oldData);
		newMember = null;
	}

	public TaskEvent(UmbrellaUser initiator, Task task, UmbrellaUser newMember) {
		super(initiator, TASK, task, MEMBER_ADDED);
		this.newMember = newMember;
	}

	@Override
	public Collection<UmbrellaUser> audience() {
		return payload().members().values().stream().map(Member::user).toList();
	}

	@Override
	public Translatable describe() {
		return switch (eventType()){
			case CREATE -> describeCreate();
			case DELETE -> t("The task '{task}' has been deleted by {user}",Field.TASK, payload().name(), USER, initiator().name());
			case MEMBER_ADDED -> describeMemberAdded();
			case UPDATE -> describeUpdate();
		};
	}

	private Translatable describeCreate() {
		String parentName = null;
		var pid = payload().parentTaskId();
		if (pid != null) {
			var parent = taskService().load(List.of(pid)).get(pid);
			if (parent != null) parentName = parent.name();
		}
		if (parentName == null){
			var project = projectService().load(payload().projectId());
			if (project != null) parentName = project.name();
		}
		if (parentName == null) parentName = "?";
		var head =  t("'{task}' has been added to '{object}':\n\n{body}", Field.TASK, payload().name(), OBJECT, parentName, BODY, payload().description());
		return t("{head}\n\n{link}","head",head,"link",link());
	}

	private Translatable describeMemberAdded() {
		var head = t("'{name}' has been added to '{object}' by '{user}'.",NAME,newMember.name(), OBJECT,payload().name(),USER,initiator().name());
		return t("{head}\n\n{link}","head",head,"link",link());
	}

	private Translatable describeUpdate() {
		var head = t("Changes in task '{task}':\n\n{body}",Field.TASK,payload().name(),BODY,diff().orElse(""));
		return t("{head}\n\n{link}","head",head,"link",link());
	}

	@Override
	protected Map<String, Object> filter(Map<String, Object> map) {
		map.remove(MEMBERS);
		var o = map.get(STATUS);
		if (o instanceof Number status) try {
			map.put(STATUS,Status.of(status.intValue()).name());
		} catch (IllegalArgumentException ignores){}
		return super.filter(map);
	}

	@Override
	public boolean isIntendedFor(UmbrellaUser user) {
		for (var member : payload().members().values()){
			if (member.user().equals(user)) return true;
		}
		return false;
	}

	private Translatable link() {
		return t("You can view/edit this task at {base_url}/task/{id}/view",ID,payload().id());
	}

	@Override
	public Translatable subject() {
		return switch (eventType()){
			case CREATE -> t("The task '{task}' has been created", Field.TASK, payload().name());
			case DELETE -> t("The task '{task}' has been deleted",Field.TASK, payload().name());
			case MEMBER_ADDED, UPDATE -> t("Task '{task}' was edited",Field.TASK,payload().name());
		};
	}}
