import { writable } from 'svelte/store';
import { ApiError } from './api';

export type ToastTone = 'info' | 'success' | 'warning' | 'error';

export interface Toast {
	id: number;
	message: string;
	tone: ToastTone;
	ttl: number;
}

let nextId = 0;
const timers = new Map<number, ReturnType<typeof setTimeout>>();

export const toasts = writable<Toast[]>([]);

export function toast(message: string, tone: ToastTone = 'info', ttl = 4000): number {
	const id = ++nextId;
	const entry: Toast = { id, message, tone, ttl };
	toasts.update((list) => [...list, entry]);
	if (ttl > 0 && typeof window !== 'undefined') {
		timers.set(
			id,
			setTimeout(() => dismissToast(id), ttl)
		);
	}
	return id;
}

export function dismissToast(id: number): void {
	const t = timers.get(id);
	if (t) {
		clearTimeout(t);
		timers.delete(id);
	}
	toasts.update((list) => list.filter((x) => x.id !== id));
}

// User-action error surface. Pulls the German message off ApiError; for
// anything else, falls back to a generic line so the user sees *something*.
export function toastError(err: unknown, fallback = 'Etwas ist schiefgelaufen.'): number {
	if (err instanceof ApiError) return toast(err.message || fallback, 'error', 5000);
	if (err instanceof Error && err.message) return toast(err.message, 'error', 5000);
	return toast(fallback, 'error', 5000);
}
