/**
 * Format an ISO date string (YYYY-MM-DD) for display.
 * Uses T12:00:00 to avoid UTC timezone off-by-one when converting to local time.
 * Defaults to 'long' (e.g. "24. Dezember 1943"); pass 'short' for DD.MM.YYYY.
 */
export function formatDate(isoDate: string, format: 'short' | 'long' = 'long'): string {
	const date = new Date(isoDate + 'T12:00:00');
	if (format === 'short') {
		return new Intl.DateTimeFormat('de-DE', {
			day: '2-digit',
			month: '2-digit',
			year: 'numeric'
		}).format(date);
	}
	return new Intl.DateTimeFormat('de-DE', {
		day: 'numeric',
		month: 'long',
		year: 'numeric'
	}).format(date);
}

/**
 * Format an ISO date string for medium-length display (e.g. "15. Jun. 1920").
 * Uses T12:00:00 to avoid UTC timezone off-by-one.
 * Pass an explicit BCP 47 locale tag to respect the app locale; defaults to 'de-DE'.
 */
export function formatMCDate(isoDate: string, locale: string = 'de-DE'): string {
	return new Intl.DateTimeFormat(locale, {
		day: 'numeric',
		month: 'short',
		year: 'numeric'
	}).format(new Date(isoDate + 'T12:00:00'));
}

/**
 * Converts an ISO date string (YYYY-MM-DD) to German display format (DD.MM.YYYY).
 * Returns an empty string for invalid or empty input.
 */
export function isoToGerman(iso: string): string {
	if (!iso || !/^\d{4}-\d{2}-\d{2}$/.test(iso)) return '';
	const [y, m, d] = iso.split('-');
	return `${d}.${m}.${y}`;
}

/**
 * Converts a German date string (DD.MM.YYYY) to ISO format (YYYY-MM-DD).
 * Returns an empty string for invalid or empty input.
 */
export function germanToIso(german: string): string {
	const match = german.match(/^(\d{2})\.(\d{2})\.(\d{4})$/);
	if (!match) return '';
	const [, d, m, y] = match;
	return `${y}-${m}-${d}`;
}

/**
 * Formats a raw date string into German DD.MM.YYYY format.
 *
 * Handles two modes:
 * - Pure digit stream (no dots): auto-inserts dots after position 2 and 4
 * - Manual dot entry: preserves user-typed dots, pads single-digit day/month,
 *   and overflows extra digits from day→month and month→year
 */
export function formatGermanDateInput(raw: string): string {
	if (!raw.includes('.')) {
		const digits = raw.replace(/\D/g, '').slice(0, 8);
		if (digits.length <= 2) return digits;
		if (digits.length <= 4) return `${digits.slice(0, 2)}.${digits.slice(2)}`;
		return `${digits.slice(0, 2)}.${digits.slice(2, 4)}.${digits.slice(4)}`;
	}

	const trailingDot = raw.endsWith('.');
	const parts = raw.split('.').map((p) => p.replace(/\D/g, ''));

	let day = parts[0] ?? '';
	let month = parts[1] ?? '';
	let year = parts[2] ?? '';

	let dayOverflowed = false;
	if (day.length > 2) {
		month = day.slice(2) + month;
		day = day.slice(0, 2);
		dayOverflowed = true;
	}

	let monthOverflowed = false;
	if (month.length > 2) {
		year = month.slice(2) + year;
		month = month.slice(0, 2);
		monthOverflowed = true;
	}

	year = year.slice(0, 4);

	const afterDay = !dayOverflowed && parts.length >= 2;

	if (day.length === 1 && (month || (trailingDot && !dayOverflowed))) {
		day = '0' + day;
	}
	if (month.length === 1 && (year || (trailingDot && afterDay && !monthOverflowed))) {
		month = '0' + month;
	}

	if (year) return `${day}.${month}.${year}`;
	if (month) {
		const dot2 = trailingDot && afterDay && !monthOverflowed ? '.' : '';
		return `${day}.${month}${dot2}`;
	}
	const dot1 = trailingDot && !dayOverflowed ? '.' : '';
	return `${day}${dot1}`;
}

/**
 * Handles a date input event for German-format date fields (DD.MM.YYYY).
 * Strips non-digits, formats with dots, mutates the input's displayed value,
 * and returns the display string and its ISO equivalent.
 */
export function handleGermanDateInput(e: Event): { display: string; iso: string } {
	const input = e.target as HTMLInputElement;
	const display = formatGermanDateInput(input.value);
	input.value = display;
	return { display, iso: germanToIso(display) };
}
