import { formatDate } from '$lib/shared/utils/date';
import { m } from '$lib/paraglide/messages.js';

type Person = { firstName?: string | null; lastName: string; displayName: string };
type DocForMeta = {
	sender?: Person | null;
	receivers?: Person[];
	documentDate?: string | null;
};

const AVATAR_PALETTE = ['#012851', '#5A3080', '#007596', '#2A6040', '#803020'] as const;

function djb2(str: string): number {
	let hash = 5381;
	for (let i = 0; i < str.length; i++) {
		hash = (hash * 33) ^ str.charCodeAt(i);
	}
	return Math.abs(hash);
}

/** Localized fallback when a person has no name parts. */
export function unknownPersonName(): string {
	return m.person_unknown();
}

/**
 * Single source for the join-names-or-fallback rule. Mirrors the server-side
 * fallback in GeschichteService.toView (which emits the literal '[Unbekannt]').
 */
export function joinNameOrUnknown(firstName?: string | null, lastName?: string | null): string {
	return [firstName, lastName].filter(Boolean).join(' ').trim() || unknownPersonName();
}

export function getInitials(name: string): string {
	const words = name.trim().split(/\s+/).filter(Boolean);
	if (words.length === 0) return '';
	if (words.length === 1) return words[0].charAt(0).toUpperCase();
	return (words[0].charAt(0) + words[words.length - 1].charAt(0)).toUpperCase();
}

export function abbreviateName(person: Person): string {
	if (!person.firstName) return person.lastName;
	const first = person.firstName.trim();
	const last = person.lastName.trim();
	if (!last) return first;
	return `${first.charAt(0)}. ${last}`;
}

function abbreviateCompact(person: Person): string {
	if (!person.firstName) return person.lastName;
	const first = person.firstName.trim();
	const last = person.lastName.trim();
	if (!last) return first;
	return `${first.charAt(0)}.${last}`;
}

export function formatXsMeta(doc: DocForMeta): string {
	const parts: string[] = [];

	const receivers = doc.receivers ?? [];
	if (doc.sender) {
		const senderAbbr = abbreviateCompact(doc.sender);
		if (receivers.length === 0) {
			parts.push(senderAbbr);
		} else {
			const extra = receivers.length - 1;
			const firstReceiver = abbreviateCompact(receivers[0]);
			parts.push(
				extra > 0
					? `${senderAbbr} → ${firstReceiver} +${extra}`
					: `${senderAbbr} → ${firstReceiver}`
			);
		}
	} else if (receivers.length > 0) {
		const extra = receivers.length - 1;
		const firstReceiver = abbreviateCompact(receivers[0]);
		parts.push(extra > 0 ? `${firstReceiver} +${extra}` : firstReceiver);
	}

	if (doc.documentDate) {
		parts.push(formatDate(doc.documentDate, 'short'));
	}

	return parts.join(' · ');
}

export function personAvatarColor(personId: string): string {
	return AVATAR_PALETTE[djb2(personId) % AVATAR_PALETTE.length];
}
