import type { Unit } from "@app/shared-types";
import { toGrams, type IngredientUnitInfo } from "@app/nutrition-engine";

export interface CostableIngredient {
  canonicalIngredientId: string;
  quantity: number;
  unit: Unit;
  optional: boolean;
}

export interface PriceInfo extends IngredientUnitInfo {
  /** SEK per kg – från kvittohistorik, användardata eller standardvärde (spec §26). */
  pricePerKgMinor: number;
  source: "receipt_history" | "user" | "default";
}

export interface CostEstimate {
  totalMinor: number | null;
  perPortionMinor: number | null;
  /** Andel av ingredienserna (viktat) som hade prisdata. */
  priceCoverage: number;
  sourcesUsed: PriceInfo["source"][];
}

/** Kostnadsuppskattning per portion – alltid märkt som uppskattning. */
export function estimateCost(
  ingredients: CostableIngredient[],
  portions: number,
  prices: Map<string, PriceInfo>,
): CostEstimate {
  let total = 0;
  let pricedCount = 0;
  let mandatoryCount = 0;
  const sources = new Set<PriceInfo["source"]>();

  for (const ing of ingredients) {
    if (ing.optional) continue;
    mandatoryCount += 1;
    const price = prices.get(ing.canonicalIngredientId);
    if (!price) continue;
    const grams = toGrams(ing.quantity, ing.unit, price);
    if (grams == null) continue;
    total += (grams / 1000) * price.pricePerKgMinor;
    pricedCount += 1;
    sources.add(price.source);
  }

  if (pricedCount === 0 || mandatoryCount === 0) {
    return { totalMinor: null, perPortionMinor: null, priceCoverage: 0, sourcesUsed: [] };
  }

  const coverage = pricedCount / mandatoryCount;
  return {
    totalMinor: Math.round(total),
    perPortionMinor: portions > 0 ? Math.round(total / portions) : null,
    priceCoverage: Math.round(coverage * 100) / 100,
    sourcesUsed: [...sources],
  };
}
