export type WeightUnit = "g" | "oz" | "lb" | "kg";

const GRAMS_PER_OZ = 28.3495;
const GRAMS_PER_LB = 453.592;
const GRAMS_PER_KG = 1000;

export function formatWeight(
	grams: number | null | undefined,
	unit: WeightUnit = "g",
	locale = "en",
): string {
	if (grams == null) return "--";
	let value: number;
	let fractionDigits: number;
	switch (unit) {
		case "g":
			value = Math.round(grams);
			fractionDigits = 0;
			break;
		case "oz":
			value = grams / GRAMS_PER_OZ;
			fractionDigits = 1;
			break;
		case "lb":
			value = grams / GRAMS_PER_LB;
			fractionDigits = 2;
			break;
		case "kg":
			value = grams / GRAMS_PER_KG;
			fractionDigits = 2;
			break;
	}
	const formatted = new Intl.NumberFormat(locale, {
		minimumFractionDigits: fractionDigits,
		maximumFractionDigits: fractionDigits,
	}).format(value);
	return unit === "g" ? `${formatted}g` : `${formatted} ${unit}`;
}

export type Currency = "USD" | "EUR" | "GBP" | "JPY" | "CAD" | "AUD";

export function formatPrice(
	cents: number | null | undefined,
	currency: Currency = "USD",
	locale = "en",
): string {
	if (cents == null) return "--";
	return new Intl.NumberFormat(locale, {
		style: "currency",
		currency,
		minimumFractionDigits: currency === "JPY" ? 0 : 2,
		maximumFractionDigits: currency === "JPY" ? 0 : 2,
	}).format(cents / 100);
}

export interface DualPriceOptions {
	sourceCents: number;
	sourceCurrency: Currency;
	targetCurrency: Currency;
	convertedCents: number;
	locale?: string;
}

/**
 * Format a price with dual display: source price + converted in parentheses.
 * Per D-14: "€2,000 (~£1,720)" — source prominent, converted approximate.
 */
export function formatDualPrice(options: DualPriceOptions): {
	source: string;
	converted: string;
} {
	const locale = options.locale ?? "en";
	const source = formatPrice(options.sourceCents, options.sourceCurrency, locale);
	const converted = `~${formatPrice(options.convertedCents, options.targetCurrency, locale)}`;
	return { source, converted };
}
