const DIVISIONS: { amount: number; unit: Intl.RelativeTimeFormatUnit }[] = [
	{ amount: 60, unit: "seconds" },
	{ amount: 60, unit: "minutes" },
	{ amount: 24, unit: "hours" },
	{ amount: 7, unit: "days" },
	{ amount: 4.34524, unit: "weeks" },
	{ amount: 12, unit: "months" },
	{ amount: Number.POSITIVE_INFINITY, unit: "years" }
];

const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
const dtf = new Intl.DateTimeFormat("en", { year: "numeric", month: "short", day: "numeric" });

// "3 days ago", "in 2 hours", etc.
export const relativeTime = (input: string | Date, now: Date = new Date()): string => {
	const date = typeof input === "string" ? new Date(input) : input;
	if (Number.isNaN(date.getTime())) return "";
	let duration = (date.getTime() - now.getTime()) / 1000;
	for (const division of DIVISIONS) {
		if (Math.abs(duration) < division.amount)
			return rtf.format(Math.round(duration), division.unit);
		duration /= division.amount;
	}
	return rtf.format(Math.round(duration), "years");
};
export const compactRelativeTime = (input: string | Date, now: Date = new Date()): string => {
	const date = typeof input === "string" ? new Date(input) : input;
	if (Number.isNaN(date.getTime())) return "";
	let duration = Math.abs((now.getTime() - date.getTime()) / 1000);
	const suffix = date.getTime() > now.getTime() ? "from now" : "ago";

	if (duration < 60) return `${Math.floor(duration)}s ${suffix}`;
	duration /= 60;
	if (duration < 60) return `${Math.floor(duration)}m ${suffix}`;
	duration /= 60;
	if (duration < 24) return `${Math.floor(duration)}h ${suffix}`;
	duration /= 24;
	if (duration < 7) return `${Math.floor(duration)}d ${suffix}`;
	duration /= 7;
	if (duration < 4.34524) return `${Math.floor(duration)}w ${suffix}`;
	duration /= 4.34524;
	if (duration < 12) return `${Math.floor(duration)}mo ${suffix}`;
	duration /= 12;
	return `${Math.floor(duration)}y ${suffix}`;
};

export const formatDate = (input: string | Date): string => {
	const date = typeof input === "string" ? new Date(input) : input;
	return Number.isNaN(date.getTime()) ? "" : dtf.format(date);
};
