/** Mirrors MealPlan.Api IngredientScalingHelper — AmountGrams is grams, not piece count. */

const COUNT_AMOUNT_THRESHOLD = 10;

const NON_QUANTIFIED_UNITS = new Set([
  "to taste",
  "for serving",
  "optional",
  "do smaku",
  "do podania",
  "opcjonalnie",
  "garnish",
  "szczypta",
]);

function normalizeUnit(unit: string): string {
  return unit.trim().toLowerCase().replace(/\.$/, "");
}

export function isNonQuantifiedUnit(unit: string | null | undefined): boolean {
  if (!unit?.trim()) return false;
  return NON_QUANTIFIED_UNITS.has(normalizeUnit(unit));
}

function isCountUnit(unit: string | null | undefined): boolean {
  if (!unit?.trim()) return false;
  const u = normalizeUnit(unit);
  return (
    u === "szt" ||
    u === "sztuka" ||
    u === "sztuki" ||
    u === "ząbek" ||
    u === "zabek" ||
    u === "zabki" ||
    u === "clove" ||
    u === "cloves" ||
    u === "łyżka" ||
    u === "lyzka" ||
    u === "łyżeczka" ||
    u === "lyzeczka" ||
    u === "jajko" ||
    u === "jajka" ||
    u === "egg" ||
    u === "eggs"
  );
}

function gramsPerCountUnit(unit: string): number {
  const u = normalizeUnit(unit);
  switch (u) {
    case "ząbek":
    case "zabek":
    case "zabki":
    case "clove":
    case "cloves":
      return 4;
    case "łyżka":
    case "lyzka":
      return 15;
    case "łyżeczka":
    case "lyzeczka":
      return 5;
    default:
      return 60;
  }
}

function roundAmount(value: number): number {
  return Math.round(value * 10) / 10;
}

/** Converts recipe ingredient rows to gram weights for aggregation / display. */
export function normalizeIngredientQuantity(
  amountGrams: number | null | undefined,
  unit: string | null | undefined,
): { amountGrams: number | null; unit: string | null } {
  const unitRaw = unit?.trim() || null;

  if (isNonQuantifiedUnit(unitRaw)) {
    return { amountGrams: amountGrams ?? null, unit: unitRaw };
  }

  if (amountGrams == null || amountGrams <= 0) {
    return { amountGrams: null, unit: unitRaw };
  }

  if (isCountUnit(unitRaw) && unitRaw) {
    if (amountGrams <= COUNT_AMOUNT_THRESHOLD) {
      return {
        amountGrams: roundAmount(amountGrams * gramsPerCountUnit(unitRaw)),
        unit: null,
      };
    }
    return { amountGrams: roundAmount(amountGrams), unit: null };
  }

  return { amountGrams: roundAmount(amountGrams), unit: null };
}

function formatNumber(value: number): string {
  return Number.isInteger(value) ? value.toString() : value.toFixed(1).replace(/\.0$/, "");
}

/** Human-readable amount for recipe cards and PDF recipe pages. */
export function formatIngredientAmount(amountGrams: number | null, unit: string | null): string {
  if (isNonQuantifiedUnit(unit)) {
    return unit?.trim() ?? "";
  }

  const normalized = normalizeIngredientQuantity(amountGrams, unit);
  if (normalized.amountGrams == null || normalized.amountGrams <= 0) {
    return normalized.unit ?? "";
  }

  return `${formatNumber(normalized.amountGrams)} g`;
}
