import { toast } from "../state/toast";
import type { InstanceEventPayload } from "../types/events";

const DEDUP_WINDOW_MS = 1000;
const lastToastTime = new Map<string, number>();

function makeDedupKey(instanceId: string, eventType: string): string {
	return `${instanceId}:${eventType}`;
}

function shouldShowToast(instanceId: string, eventType: string): boolean {
	const key = makeDedupKey(instanceId, eventType);
	const now = Date.now();
	const last = lastToastTime.get(key);
	if (last && now - last < DEDUP_WINDOW_MS) {
		return false;
	}
	lastToastTime.set(key, now);
	return true;
}

export function mapEventToCategory(event: InstanceEventPayload): string {
	if (event.event.startsWith("instance.")) return "instance";
	if (event.event.startsWith("health.")) return "health";
	return "system";
}

export function mapEventToSeverity(
	event: InstanceEventPayload,
): "info" | "warning" | "error" | "success" {
	switch (event.event) {
		case "instance.error":
		case "health.error":
			return "error";
		case "instance.health_changed":
			return event.status === "unhealthy" ? "warning" : "success";
		case "instance.created":
		case "instance.started":
		case "instance.stopped":
		case "instance.restarted":
		case "instance.deleted":
			return "info";
		default:
			return "info";
	}
}

export function handleEventToast(event: InstanceEventPayload): void {
	const { event: eventType, instance_id, status, message, metadata } = event;

	switch (eventType) {
		case "instance.started":
			if (shouldShowToast(instance_id, eventType)) {
				toast.info("Container starting...", { duration: 3000 });
			}
			break;
		case "instance.health_changed":
			if (status === "running" && shouldShowToast(instance_id, eventType)) {
				toast.success("Container running", { duration: 3000 });
			} else if (
				status === "unhealthy" &&
				shouldShowToast(instance_id, eventType)
			) {
				toast.warning("Container unhealthy", { duration: 5000 });
			}
			break;
		case "instance.error":
			if (shouldShowToast(instance_id, eventType)) {
				const msg = message ?? "Container error";
				const exitCode = metadata?.exit_code;
				const fullMsg =
					exitCode !== undefined ? `${msg} (exit code: ${exitCode})` : msg;
				toast.error(fullMsg, { duration: 10000 });
			}
			break;
		default:
			break;
	}
}

export function clearToastDedup(): void {
	lastToastTime.clear();
}
