// Caffè Italia · catalogue produits.
//
// Champs localisés : { fr: "...", it: "..." }. La fonction window.pick(field)
// renvoie automatiquement la valeur dans la langue active.
//
// Chaque produit a aussi `image` (photo principale), `images` (photos
// supplémentaires, optionnel), `price` (€), `category`
// (id catégorie), `weight`, `palette` (3 couleurs dérivées de l'emballage
// pour le halo de la carte) et `intensity` (1-10 si pertinent, sinon null).

const CATEGORIES = [
  { id: "grain",    slug: "/collections/cafe-grain",
    name: { fr: "Café en grain",      it: "Caffè in grani" },
    it:   "In Grani" },
  { id: "moulu",    slug: "/collections/cafe-moulu",
    name: { fr: "Café moulu",          it: "Caffè macinato" },
    it:   "Macinato" },
  { id: "capsules", slug: "/collections/capsule-et-dosettes-compatible",
    name: { fr: "Capsules & dosettes", it: "Capsule & cialde" },
    it:   "Capsule" },
  { id: "machines", slug: "/collections/machine",
    name: { fr: "Machines à café",     it: "Macchine da caffè" },
    it:   "Macchine" },
  { id: "tasses",   slug: "/collections/tasses-a-cafe",
    name: { fr: "Tasses",              it: "Tazzine" },
    it:   "Tazze" },
  { id: "epicerie", slug: "/collections/autres-produits",
    name: { fr: "Épicerie italienne",  it: "Specialità italiane" },
    it:   "Alimentari" },
];

const PRODUCTS = [
  // ─── CAFÉ EN GRAIN ───────────────────────────────────────────────────
  {
    id: "moreno-top-espresso-extra-1kg",
    name: { fr: "Café en grain Moreno Top Espresso Extra · 1 kg",
            it: "Caffè in grani Moreno Top Espresso Extra · 1 kg" },
    sub:  { fr: "Mélange premium en grain · Intensité I",
            it: "Miscela premium in grani · Intensità I" },
    tasting: { fr: "Chocolat noir, cacao, longueur intense",
               it: "Cioccolato fondente, cacao, persistenza intensa" },
    price: 32.00, weight: "1 kg", intensity: 10,
    badge: { fr: "Premium", it: "Premium" },
    category: "grain",
    image: "images/products/moreno-top-extra-espresso-1kg.jpg",
    palette: ["#1c1410","#8d1620","#e8c98a"],
  },
  {
    id: "moreno-top-espresso-80-arabica-1kg",
    name: { fr: "Café en grain Moreno Top Espresso · 80 % Arabica · 1 kg",
            it: "Caffè in grani Moreno Top Espresso · 80 % Arabica · 1 kg" },
    sub:  { fr: "Mélange Arabica majoritaire en grain",
            it: "Miscela Arabica prevalente in grani" },
    tasting: { fr: "Rond, cacao au lait, finale longue",
               it: "Rotondo, cacao al latte, finale lungo" },
    price: 28.00, weight: "1 kg", intensity: 8,
    badge: { fr: "Arabica 80 %", it: "Arabica 80 %" },
    category: "grain",
    image: "images/products/moreno-top-espresso-80.jpg",
    palette: ["#0e0d0c","#c8202c","#f4ede0"],
  },
  {
    id: "moreno-gran-miscela-grain-1kg",
    name: { fr: "Café en grain Moreno Gran Miscela · 1 kg",
            it: "Caffè in grani Moreno Gran Miscela · 1 kg" },
    sub:  { fr: "Mélange signature en grain",
            it: "Miscela signature in grani" },
    tasting: { fr: "Équilibré, noisette, cacao",
               it: "Equilibrato, nocciola, cacao" },
    price: 26.00, weight: "1 kg", intensity: 7,
    badge: null,
    category: "grain",
    image: "images/products/gran-miscela-cafe-grain-1kg.png",
    palette: ["#3a1f12","#caa451","#f4ede0"],
  },
  {
    id: "moreno-vending-grain-1kg",
    name: { fr: "Café en grain Moreno Vending · 1 kg",
            it: "Caffè in grani Moreno Vending · 1 kg" },
    sub:  { fr: "Mélange pour bar et distributeur",
            it: "Miscela per bar e distributore" },
    tasting: { fr: "Corsé, cacaoté, persistant",
               it: "Corposo, cacao, persistente" },
    price: 19.50, weight: "1 kg", intensity: 9,
    badge: { fr: "Bar & Vending", it: "Bar & Vending" },
    category: "grain",
    image: "images/products/moreno-vending-grain.jpg",
    palette: ["#2b1f17","#d8b27a","#f4ede0"],
  },
  {
    id: "electus-grain-100-arabica-1kg",
    name: { fr: "Electus · Grain 100 % Arabica · 1 kg",
            it: "Electus · Grani 100 % Arabica · 1 kg" },
    sub:  { fr: "Pure origine Arabica, en grain",
            it: "Pura origine Arabica, in grani" },
    tasting: { fr: "Floral, miel, agrumes confits",
               it: "Floreale, miele, agrumi canditi" },
    price: 37.80, weight: "1 kg", intensity: 6,
    badge: { fr: "100 % Arabica", it: "100 % Arabica" },
    category: "grain",
    image: "images/products/elctus-grain-100-arabica.png",
    palette: ["#caa451","#0e0d0c","#f4ede0"],
  },

  // ─── CAFÉ MOULU ──────────────────────────────────────────────────────
  {
    id: "moreno-gran-miscela-moulu-250g",
    name: { fr: "Café Moreno Gran Miscela · moulu · 250 g",
            it: "Caffè Moreno Gran Miscela · macinato · 250 g" },
    sub:  { fr: "Pour Moka · Mélange signature",
            it: "Per Moka · Miscela signature" },
    tasting: { fr: "Équilibré, noisette, cacao",
               it: "Equilibrato, nocciola, cacao" },
    price: 5.70, weight: "250 g", intensity: 7,
    badge: null,
    category: "moulu",
    image: "images/products/cafe-moreno-moulu.png",
    palette: ["#3a1f12","#caa451","#f4ede0"],
  },
  {
    id: "moreno-classica-moulu-250g",
    name: { fr: "Café Moreno Miscela Classica · moulu · 250 g",
            it: "Caffè Moreno Miscela Classica · macinato · 250 g" },
    sub:  { fr: "Pour Moka · Mélange classique",
            it: "Per Moka · Miscela classica" },
    tasting: { fr: "Doux, équilibré, notes torréfiées",
               it: "Dolce, equilibrato, note tostate" },
    price: 5.90, weight: "250 g", intensity: 6,
    badge: null,
    category: "moulu",
    image: "images/products/cafe-moreno-moulu-intensa.png",
    palette: ["#2b1f17","#d8b27a","#f4ede0"],
  },

  // ─── CAPSULES & DOSETTES ─────────────────────────────────────────────
  {
    id: "moreno-aroma-top-nespresso-50",
    name: { fr: "Capsules Moreno · Aroma Top · Nespresso®",
            it: "Capsule Moreno · Aroma Top · Nespresso®" },
    sub:  { fr: "Compatibles Nespresso® · Premium · 50 cps",
            it: "Compatibili Nespresso® · Premium · 50 cps" },
    tasting: { fr: "Intense, persistant, chocolat noir",
               it: "Intenso, persistente, cioccolato fondente" },
    price: 20.50, weight: "50 cps", intensity: 10,
    badge: { fr: "Premium", it: "Premium" },
    category: "capsules",
    variantGroup: "moreno-aroma-top-nespresso",
    image: "images/products/capsule-moreno-top-aromanespresso.jpg",
    palette: ["#c8202c","#0e0d0c","#f4ede0"],
  },
  {
    id: "moreno-aroma-top-nespresso-100",
    name: { fr: "Capsules Moreno · Aroma Top · Nespresso®",
            it: "Capsule Moreno · Aroma Top · Nespresso®" },
    sub:  { fr: "Compatibles Nespresso® · Premium · 100 cps",
            it: "Compatibili Nespresso® · Premium · 100 cps" },
    tasting: { fr: "Intense, persistant, chocolat noir",
               it: "Intenso, persistente, cioccolato fondente" },
    price: 36.00, weight: "100 cps", intensity: 10,
    badge: { fr: "Premium", it: "Premium" },
    category: "capsules",
    variantGroup: "moreno-aroma-top-nespresso",
    image: "images/products/capsule-moreno-top-aromanespresso.jpg",
    palette: ["#c8202c","#0e0d0c","#f4ede0"],
  },
  {
    id: "moreno-capsule-nespresso-alluminio",
    name: { fr: "Capsule Moreno · Aluminium · Nespresso®",
            it: "Capsula Moreno · Alluminio · Nespresso®" },
    sub:  { fr: "Compatible Nespresso® · à l'unité",
            it: "Compatibile Nespresso® · al pezzo" },
    tasting: { fr: "Crème dense, arôme préservé",
               it: "Crema densa, aroma preservato" },
    price: 3.90, weight: "1 cps", intensity: 9,
    badge: { fr: "Aluminium", it: "Alluminio" },
    category: "capsules",
    image: "images/products/moreno-capsule-nespresso-alumin.jpg",
    palette: ["#bdb6ad","#0e0d0c","#c8202c"],
  },
  {
    id: "capsules-dolce-gusto",
    name: { fr: "Capsules compatibles Dolce Gusto®",
            it: "Capsule compatibili Dolce Gusto®" },
    sub:  { fr: "Compatibles Nescafé Dolce Gusto®",
            it: "Compatibili Nescafé Dolce Gusto®" },
    tasting: { fr: "Corsé, équilibré, crème onctueuse",
               it: "Corposo, equilibrato, crema vellutata" },
    price: 16.50, weight: "Boîte", intensity: 8,
    badge: null,
    category: "capsules",
    image: "images/products/capsules-compatible-dolce-gusto.jpg",
    palette: ["#8d1620","#0e0d0c","#f4ede0"],
  },
  {
    id: "capsules-a-modo-mio",
    name: { fr: "Capsules compatibles A Modo Mio®",
            it: "Capsule compatibili A Modo Mio®" },
    sub:  { fr: "Compatibles Lavazza A Modo Mio®",
            it: "Compatibili Lavazza A Modo Mio®" },
    tasting: { fr: "Rond, gourmand, longueur en bouche",
               it: "Rotondo, goloso, persistente in bocca" },
    price: 14.50, weight: "Boîte", intensity: 8,
    badge: null,
    category: "capsules",
    image: "images/products/capsules-compatible-a-modo-mio.jpg",
    palette: ["#1a3a7a","#e8c98a","#f4ede0"],
  },
  {
    id: "moreno-dosettes-ese-aroma-top-50",
    name: { fr: "Dosettes ESE 44 mm · Aroma Top · Caffè Moreno",
            it: "Cialde ESE 44 mm · Aroma Top · Caffè Moreno" },
    sub:  { fr: "Dosettes papier compostables · 50 pz",
            it: "Cialde di carta compostabili · 50 pz" },
    tasting: { fr: "Intense, persistant, chocolat noir",
               it: "Intenso, persistente, cioccolato fondente" },
    price: 16.50, weight: "50 pz", intensity: 10,
    badge: { fr: "Compostable", it: "Compostabile" },
    category: "capsules",
    variantGroup: "moreno-dosettes-ese-aroma-top",
    image: "images/products/moreno-aroma-top-capsule.png",
    palette: ["#c8202c","#0e0d0c","#f4ede0"],
  },
  {
    id: "moreno-dosettes-ese-aroma-top",
    name: { fr: "Dosettes ESE 44 mm · Aroma Top · Caffè Moreno",
            it: "Cialde ESE 44 mm · Aroma Top · Caffè Moreno" },
    sub:  { fr: "Dosettes papier compostables · 150 pz",
            it: "Cialde di carta compostabili · 150 pz" },
    tasting: { fr: "Intense, persistant, chocolat noir",
               it: "Intenso, persistente, cioccolato fondente" },
    price: 45.00, weight: "150 pz", intensity: 10,
    badge: { fr: "Compostable", it: "Compostabile" },
    category: "capsules",
    variantGroup: "moreno-dosettes-ese-aroma-top",
    image: "images/products/moreno-aroma-top-capsule.png",
    palette: ["#c8202c","#0e0d0c","#f4ede0"],
  },
  {
    id: "moreno-dosettes-ese-aroma-top-300",
    name: { fr: "Dosettes ESE 44 mm · Aroma Top · Caffè Moreno",
            it: "Cialde ESE 44 mm · Aroma Top · Caffè Moreno" },
    sub:  { fr: "300 pz · kit sucre, touillettes et gobelets inclus",
            it: "300 pz · kit zucchero, palette e bicchieri inclusi" },
    tasting: { fr: "Intense, persistant, chocolat noir",
               it: "Intenso, persistente, cioccolato fondente" },
    price: 95.00, weight: "300 pz", intensity: 10,
    badge: { fr: "Kit inclus", it: "Kit incluso" },
    category: "capsules",
    variantGroup: "moreno-dosettes-ese-aroma-top",
    image: "images/products/moreno-aroma-top-capsule.png",
    palette: ["#c8202c","#0e0d0c","#f4ede0"],
  },
  {
    id: "moreno-dosettes-ese-decafeine",
    name: { fr: "Dosettes ESE 44 mm · Aroma Décaféiné · Caffè Moreno",
            it: "Cialde ESE 44 mm · Aroma Decaffeinato · Caffè Moreno" },
    sub:  { fr: "Dosettes papier compostables · sans caféine",
            it: "Cialde di carta compostabili · senza caffeina" },
    tasting: { fr: "Doux, malté, fruits secs",
               it: "Dolce, maltato, frutta secca" },
    price: 46.00, weight: "150 pz", intensity: 5,
    badge: { fr: "Sans caféine", it: "Senza caffeina" },
    category: "capsules",
    image: "images/products/moreno-dosette-aroma-decafeine.png",
    palette: ["#2b1f17","#6b7a3a","#f4ede0"],
  },

  // ─── MACHINES ────────────────────────────────────────────────────────
  {
    id: "machine-tube-ese-44",
    name: { fr: "Machine à dosettes ESE 44 mm · Tube",
            it: "Macchina a cialde ESE 44 mm · Tube" },
    sub:  { fr: "Machine à dosettes papier · design tube",
            it: "Macchina per cialde di carta · design tube" },
    tasting: { fr: "Compatible toutes dosettes ESE 44 mm",
               it: "Compatibile con tutte le cialde ESE 44 mm" },
    price: 180.00, weight: "1 pz", intensity: null,
    badge: { fr: "Made in Italy", it: "Made in Italy" },
    category: "machines",
    image: "images/products/machine.jpg",
    palette: ["#2a2522","#bdb6ad","#c8202c"],
  },
  {
    id: "machine-ese-50-dosettes-aroma",
    name: { fr: "Machine ESE Espresso + 50 dosettes Aroma",
            it: "Macchina ESE Espresso + 50 cialde Aroma" },
    sub:  { fr: "Pack machine + dosettes ESE 44 mm",
            it: "Pack macchina + cialde ESE 44 mm" },
    tasting: { fr: "Le bar à la maison, en pack complet",
               it: "Il bar a casa tua, in pacchetto completo" },
    price: 128.99, weight: "Pack", intensity: null,
    badge: { fr: "Pack", it: "Pack" },
    category: "machines",
    image: "images/products/machine-compatible-e-s-e-espresso.png",
    palette: ["#bdb6ad","#0e0d0c","#c8202c"],
  },

  // ─── TASSES ──────────────────────────────────────────────────────────
  {
    id: "tasse-classique",
    name: { fr: "Tazzina classique",
            it: "Tazzina classica" },
    sub:  { fr: "Porcelaine blanche · espresso italien",
            it: "Porcellana bianca · espresso italiano" },
    tasting: null,
    price: 22.90, weight: "6 tasses + 6 sous-tasses", weightIt: "6 tazze + 6 piattini",
    intensity: null,
    badge: null,
    category: "tasses",
    image: "images/products/tasse.png",
    palette: ["#f4ede0","#c8202c","#0e0d0c"],
  },

  // ─── ÉPICERIE ────────────────────────────────────────────────────────
  {
    id: "danti-tartufo-nero-500g",
    name: { fr: "Sauce truffe noire 5 % · Danti · 500 g",
            it: "Salsa al tartufo nero 5 % · Danti · 500 g" },
    sub:  { fr: "Sauce gourmet à la truffe noire",
            it: "Salsa gourmet al tartufo nero" },
    tasting: { fr: "Truffe noire 5 %, intense, terreuse",
               it: "Tartufo nero 5 %, intenso, terroso" },
    price: 14.50, weight: "500 g", intensity: null,
    badge: { fr: "Gourmet", it: "Gourmet" },
    category: "epicerie",
    image: "images/products/black-truffle-sauce-5-500gr.jpg",
    palette: ["#1a1410","#6b7a3a","#caa451"],
  },
];

const PRESS = ["LE MONDE", "ELLE À TABLE", "TIME OUT", "TÉLÉRAMA", "VOGUE ITALIA", "LE FIGARO"];

// Defaults · le catalogue hardcodé tel que livré.
window.DEFAULT_PRODUCTS = PRODUCTS;
window.CATEGORIES = CATEGORIES;
window.PRESS = PRESS;

// Catalogue chargé au runtime depuis Supabase (voir bootCatalog dans app.jsx).
// Fallback synchrone : les defaults sont disponibles immédiatement pour le
// premier render, puis remplacés au retour de la requête Supabase.
window.PRODUCTS = PRODUCTS;

// ─── Variantes (même produit, plusieurs formats) ──────────────────────
// Deux SKU qui partagent `variantGroup` sont le même produit en deux
// formats : chacun garde son id, son prix et son price ID Stripe, mais les
// listings n'en affichent qu'un et la fiche produit propose un sélecteur.

// Tous les SKU d'un même groupe, dans l'ordre du catalogue.
window.variantsOf = function variantsOf(p, list){
  const src = list || window.PRODUCTS || [];
  if (!p || !p.variantGroup) return p ? [p] : [];
  return src.filter(x => x.variantGroup === p.variantGroup);
};

// Le catalogue tel qu'il s'affiche en grille : un seul SKU par groupe de
// variantes (le premier du groupe), enrichi de `variantCount` et `priceFrom`.
window.listedProducts = function listedProducts(list){
  const src = list || window.PRODUCTS || [];
  const seen = new Set();
  const out = [];
  for (const p of src){
    if (!p.variantGroup) { out.push(p); continue; }
    if (seen.has(p.variantGroup)) continue;
    seen.add(p.variantGroup);
    const group = src.filter(x => x.variantGroup === p.variantGroup);
    out.push({ ...p, variantCount: group.length,
               priceFrom: Math.min(...group.map(x => x.price)) });
  }
  return out;
};

// Le format affiché · `weightIt` n'existe que quand la traduction diffère
// (« 6 tasses + 6 sous-tasses » / « 6 tazze + 6 piattini »).
window.fmtWeight = function fmtWeight(p){
  if (!p) return "";
  return (window.__LANG__ === "it" && p.weightIt) ? p.weightIt : (p.weight || "");
};

// Loader async exposé pour app.jsx. Renvoie le tableau de produits prêt
// à être consommé par les écrans (même shape que window.DEFAULT_PRODUCTS).
window.fetchCatalog = async function fetchCatalog(){
  if (!window.sb) return { ok: false, products: PRODUCTS, source: "fallback-no-supabase" };
  const { data, error } = await window.sb
    .from("products")
    .select("*")
    .eq("active", true)
    .order("sort", { ascending: true })
    .order("id", { ascending: true });
  if (error) {
    console.warn("[catalog] fallback to data.jsx defaults:", error.message);
    return { ok: false, products: PRODUCTS, source: "fallback-error" };
  }
  return { ok: true, products: (data || []).map(_rowToProduct), source: "supabase" };
};

// Local mirror of the rowToProduct mapper used in admin.jsx — keep the two
// in sync. If you change one, change the other.
function _rowToProduct(row){
  return {
    id: row.id,
    name:    { fr: row.name_fr || "",  it: row.name_it || "" },
    sub:     { fr: row.sub_fr  || "",  it: row.sub_it  || "" },
    tasting: row.tasting_fr || row.tasting_it
               ? { fr: row.tasting_fr||"", it: row.tasting_it||"" }
               : null,
    badge:   row.badge_fr || row.badge_it
               ? { fr: row.badge_fr||"", it: row.badge_it||"" }
               : null,
    price:    Number(row.price) || 0,
    weight:   row.weight || "",
    weightIt: row.weight_it || "",
    images:   Array.isArray(row.images) ? row.images.filter(Boolean) : [],
    intensity: row.intensity ?? null,
    category:  row.category || "",
    variantGroup: row.variant_group || null,
    image:     row.image || "",
    palette:   Array.isArray(row.palette) ? row.palette : ["#0e0d0c","#c8202c","#f4ede0"],
    stripePriceId: row.stripe_price_id || "",
  };
}
