// pantry-prices.jsx — grocery price estimator (Québec, ~2026 CAD)
//
// NOTE ON REEBEE / FLIPP: there is no free public API for flyer/circular data
// (Reebee/Flipp don't expose one, and scraping their app is against ToS and
// blocked from the browser by CORS). So instead of fake "live prices", this
// gives an honest *estimate*: typical Québec grocery prices, adjusted by a
// regional cost-of-living multiplier the user picks. Clearly labelled as an
// estimate in the UI. If a real flyer API becomes available, swap estimatePrice.

// Typical price for a normal grocery purchase of the item (CAD).
// countable: true → multiply by the integer quantity (e.g. "3" avocados).
const _PRICE_TABLE = [
  // produce
  { re: /avocat|avocado/, price: 1.50, countable: true },
  { re: /citron|lime|lemon/, price: 0.90, countable: true },
  { re: /banane|banana/, price: 0.40, countable: true },
  { re: /pomme|apple/, price: 0.90, countable: true },
  { re: /tomate|tomato/, price: 1.10, countable: true },
  { re: /oignon|onion|[ée]chalote/, price: 0.80, countable: true },
  { re: /ail|garlic/, price: 1.20, countable: true },
  { re: /poivron|bell pepper|pepper/, price: 1.80, countable: true },
  { re: /patate douce|sweet potato/, price: 1.60, countable: true },
  { re: /pomme de terre|potato/, price: 0.60, countable: true },
  { re: /carotte|carrot/, price: 0.40, countable: true },
  { re: /concombre|cucumber/, price: 1.50, countable: true },
  { re: /brocoli|broccoli|chou-fleur|cauliflower/, price: 2.80 },
  { re: /[ée]pinard|spinach|laitue|lettuce|kale|salade|roquette|m[ée]sclun/, price: 3.50 },
  { re: /champignon|mushroom/, price: 3.00 },
  { re: /bleuet|fraise|framboise|berr|petits fruits/, price: 4.50 },
  { re: /banane congel|frozen|surgel|petits pois|edamame/, price: 3.50 },
  { re: /herbe|basilic|basil|persil|parsley|coriandre|cilantro|menthe|mint/, price: 2.00 },
  // proteins
  { re: /poitrine de poulet|poulet|chicken/, price: 9.00 },
  { re: /b[œo]uf hach[ée]|ground beef|bœuf|beef|cube|bifteck|steak/, price: 11.00 },
  { re: /porc|pork|c[ôo]telette|jambon|ham/, price: 8.00 },
  { re: /bacon|lard/, price: 6.50 },
  { re: /saumon|salmon|truite|trout/, price: 12.00 },
  { re: /thon|tuna|poisson|fish|dor[ée]|morue|cod|tilapia/, price: 10.00 },
  { re: /crevette|shrimp|fruits de mer|p[ée]toncle|scallop|crabe|homard/, price: 13.00 },
  { re: /tofu|tempeh/, price: 3.50 },
  { re: /[œo]uf|egg/, price: 4.00 },
  // dairy
  { re: /lait|milk/, price: 4.50 },
  { re: /cr[èe]me|cream/, price: 3.50 },
  { re: /beurre|butter/, price: 6.00 },
  { re: /yogourt|yogurt/, price: 5.00 },
  { re: /fromage en grains|cheese curd|fromage|cheese|parmesan|mozzarella|cheddar|f[ée]ta|gruy[èe]re|ricotta|mascarpone/, price: 6.50 },
  // pantry / dry
  { re: /p[âa]tes|pasta|spaghetti|macaroni|nouille|noodle|lasagne|gnocchi/, price: 2.50 },
  { re: /riz|rice|quinoa|couscous|orge/, price: 4.00 },
  { re: /farine|flour|sucre|sugar|cassonade|brown sugar/, price: 3.50 },
  { re: /pain|bread|bagel|pita|tortilla|muffin anglais/, price: 3.50 },
  { re: /huile|oil/, price: 7.00 },
  { re: /sauce|salsa|ketchup|moutarde|mustard|teriyaki|soya|soy|miso|tahini|gochujang|pâte de cari|curry paste/, price: 4.00 },
  { re: /tomates en|tomato sauce|conserve|en bo[îi]te|can|haricot|bean|pois chiche|chickpea|lentille|lentil|ma[ïi]s|corn/, price: 2.20 },
  { re: /lait de coco|coconut milk/, price: 2.50 },
  { re: /[ée]pice|spice|cannelle|cinnamon|cumin|paprika|garam|curcuma|gingembre moulu|levure|baking|sel|salt|poivre|pepper|vanille|vanilla/, price: 2.50 },
  { re: /pâte (à tarte|à pizza|brisée)|pie crust|pizza dough|doigts de dame|ladyfinger|chapelure|breadcrumb|croûton|crouton/, price: 4.00 },
  { re: /noix|nut|amande|almond|arachide|peanut|graine|seed|s[ée]same|sesame/, price: 5.00 },
  { re: /chocolat|chocolate|cacao|cocoa|brisure/, price: 4.50 },
  { re: /sirop d['']?[ée]rable|maple syrup|miel|honey|m[ée]lasse|molasses|datte|date/, price: 7.00 },
  { re: /caf[ée]|coffee|th[ée]|tea/, price: 8.00 },
  { re: /vin|wine|bi[èe]re|beer/, price: 14.00 },
  { re: /sauce hollandaise|hollandaise|b[ée]chamel|vinaigrette|dressing|mayonnaise|mayo/, price: 4.50 },
];
const _PRICE_DEFAULT = 3.00;

// Regional cost-of-living multipliers vs. a Montréal baseline.
const PRICE_REGIONS = [
  { id: 'mtl', label: { fr: 'Montréal', en: 'Montréal' }, mult: 1.00 },
  { id: 'qc', label: { fr: 'Québec', en: 'Québec City' }, mult: 0.98 },
  { id: 'region', label: { fr: 'Régions', en: 'Regional' }, mult: 1.06 },
  { id: 'remote', label: { fr: 'Régions éloignées', en: 'Remote' }, mult: 1.18 },
  { id: 'north', label: { fr: 'Grand Nord', en: 'Far North' }, mult: 1.45 },
];
function regionMult(id) { const r = PRICE_REGIONS.find(x => x.id === id); return r ? r.mult : 1.0; }

function _nameStr(name, lang) {
  if (!name) return '';
  if (typeof name === 'string') return name;
  return (name[lang] || name.fr || name.en || '');
}

// Estimate the price (CAD) for one grocery line.
function estimatePrice(name, qty, regionId, lang) {
  const n = _nameStr(name, lang || 'fr').toLowerCase();
  if (!n) return _PRICE_DEFAULT * regionMult(regionId);
  let base = _PRICE_DEFAULT, countable = false, hit = false;
  for (const row of _PRICE_TABLE) {
    if (row.re.test(n)) { base = row.price; countable = !!row.countable; hit = true; break; }
  }
  // Scale countable produce by an explicit small integer count ("3" avocados).
  const q = (qty || '').toString().trim();
  if (hit && countable && /^\d{1,2}$/.test(q)) {
    const c = parseInt(q, 10);
    if (c > 0 && c <= 24) base = base * c;
  }
  return Math.round(base * regionMult(regionId) * 100) / 100;
}

// Total for a grocery list (optionally only unchecked items).
function estimateListTotal(grocery, regionId, lang, onlyUnchecked) {
  let total = 0;
  (grocery || []).forEach(g => {
    if (onlyUnchecked && g.checked) return;
    total += estimatePrice(g.name, g.qty, regionId, lang);
  });
  return Math.round(total * 100) / 100;
}

// Estimated cost to cook a recipe = sum of all its ingredient lines.
function estimateRecipeCost(recipe, regionId, lang) {
  let total = 0;
  (recipe.ingredients || []).forEach(ing => {
    if (ing.pantry) { total += 0.5 * regionMult(regionId); return; } // pantry staple, token cost
    const q = ing.qty ? (ing.qty[lang] || ing.qty.fr || ing.qty.en || ing.qty) : '';
    total += estimatePrice(ing.name, q, regionId, lang);
  });
  return Math.round(total * 100) / 100;
}

window.estimatePrice = estimatePrice;
window.estimateListTotal = estimateListTotal;
window.estimateRecipeCost = estimateRecipeCost;
window.PRICE_REGIONS = PRICE_REGIONS;
