// store.jsx — products, filament color palette, cart + orders (localStorage).
// Exports to window: PRODUCTS, FILAMENTS, fmtPrice, useCart, useOrders, genOrderId, findFilament

// 3 keychain packs. `count` = number of personalisable keychains in the pack.
const PRODUCTS = [
  {
    id: "solo",
    slotId: "photo-solo",
    count: 1,
    price: 9.99,
    badge: null,
    name_fr: "1 Porte-clé QR Code",
    name_en: "1 QR Code keychain",
    desc_fr: "\nPorte-clé QR Code personnalisé imprimé en 3D.\n\n",
    desc_en: "Custom 3D-printed QR Code keychain.",
    dims_fr: "≈ 35 mm · anneau inclus",
    dims_en: "≈ 35 mm · ring included",
  },
  {
    id: "duo",
    slotId: "photo-duo",
    count: 2,
    price: 17.99,
    badge: "popular",
    name_fr: "Pack Duo - 2 Porte-clés QR Code",
    name_en: "Duo Pack - 2 QR Code keychains",
    desc_fr: "Deux porte-clés QR Code personnalisés imprimés en 3D. Idéal pour un couple ou pour avoir un double.",
    desc_en: "Two custom 3D-printed QR Code keychains. Perfect for a couple or to keep a spare.",
    dims_fr: "2 × ≈ 35 mm · anneaux inclus",
    dims_en: "2 × ≈ 35 mm · rings included",
  },
  {
    id: "famille",
    slotId: "photo-famille",
    count: 3,
    price: 24.99,
    badge: "best",
    name_fr: "Pack Famille - 3 Porte-clés QR Code",
    name_en: "Family Pack - 3 QR Code keychains",
    desc_fr: "Trois porte-clés QR Code personnalisés imprimés en 3D. Parfait pour toute la famille.\n\n",
    desc_en: "Three custom 3D-printed QR Code keychains. Perfect for the whole family.",
    dims_fr: "3 × ≈ 35 mm · anneaux inclus",
    dims_en: "3 × ≈ 35 mm · rings included",
  },
];

// The real filament colors (matching the product band photos).
const FILAMENTS = [
  { id: "green", hex: "#24963A", fr: "Vert", en: "Green" },
  { id: "red", hex: "#EF090A", fr: "Rouge", en: "Red" },
  { id: "blue", hex: "#1E3CD0", fr: "Bleu", en: "Blue" },
  { id: "teal", hex: "#0499A4", fr: "Bleu turquoise", en: "Turquoise" },
  { id: "yellow", hex: "#F3B604", fr: "Jaune", en: "Yellow" },
  { id: "orange", hex: "#FE4C02", fr: "Orange", en: "Orange" },
  { id: "black", hex: "#121313", fr: "Noir", en: "Black" },
  { id: "white", hex: "#E5E5E9", fr: "Blanc", en: "White" },
  { id: "clear", hex: "#CED6DC", fr: "Transparent", en: "Clear" },
  { id: "pink", hex: "#E96E9E", fr: "Rose", en: "Pink" },
  { id: "gold", hex: "#C59955", fr: "Gold silk", en: "Gold silk" },
  { id: "applegreen", hex: "#5FBB03", fr: "Vert pomme", en: "Apple green" },
];

function findFilament(id) {
  return FILAMENTS.find((f) => f.id === id) || FILAMENTS[0];
}

// --- Auto contrast for QR scannability ------------------------------------
// A colored QR code (anything but strong dark/light) is unreadable by phone
// cameras: the code MUST contrast strongly with the plate. So the client only
// picks the PLATE color; the code color is derived here — whichever of the two
// print filaments (black or white) gives the higher contrast ratio with the
// chosen plate. Light plate -> black code, dark plate -> white code.
function _relLum(hex) {
  const c = String(hex).replace("#", "");
  const ch = (i) => {
    const v = parseInt(c.substr(i, 2), 16) / 255;
    return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
  };
  return 0.2126 * ch(0) + 0.7152 * ch(2) + 0.0722 * ch(4);
}
function _contrast(a, b) {
  const L1 = _relLum(a), L2 = _relLum(b);
  const hi = Math.max(L1, L2), lo = Math.min(L1, L2);
  return (hi + 0.05) / (lo + 0.05);
}
function autoCodeColor(plateId) {
  const plate = findFilament(plateId).hex;
  const black = findFilament("black").hex;
  const white = findFilament("white").hex;
  return _contrast(plate, black) >= _contrast(plate, white) ? "black" : "white";
}

// Plates that offer a manual code choice (both colors scan fine) with a
// recommended default. Everything else is fully automatic (autoCodeColor).
const CODE_CHOICE = { pink: { options: ["white", "black"], default: "white" }, teal: { options: ["white", "black"], default: "white" }, orange: { options: ["white", "black"], default: "white" }, green: { options: ["white", "black"], default: "white" }, red: { options: ["white", "black"], default: "white" }, applegreen: { options: ["white", "black"], default: "black" }, yellow: { options: ["white", "black"], default: "black" }, gold: { options: ["white", "black"], default: "black" } };

// Resolve the code color actually used for a unit: honor a valid manual choice
// on a choice-enabled plate, otherwise fall back to the automatic contrast pick.
function codeForUnit(u) {
  const choice = CODE_CHOICE[u.plate];
  if (choice) {
    return choice.options.includes(u.code) ? u.code : choice.default;
  }
  return autoCodeColor(u.plate);
}

function fmtPrice(n, lang) {
  const v = (Math.round(n * 100) / 100).toFixed(2);
  return lang === "en" ? `€${v}` : `${v.replace(".", ",")} €`;
}

function genOrderId() {
  const n = Math.floor(1000 + Math.random() * 9000);
  return `QBT-${n}`;
}

const CART_KEY = "qbt_cart_v1";
const ORDERS_KEY = "qbt_orders_v1";

function readLS(key, fallback) {
  try {
    const raw = localStorage.getItem(key);
    return raw ? JSON.parse(raw) : fallback;
  } catch (e) {
    return fallback;
  }
}
function writeLS(key, val) {
  try {
    localStorage.setItem(key, JSON.stringify(val));
  } catch (e) {}
}

function useCart() {
  const [items, setItems] = React.useState(() => readLS(CART_KEY, []));
  React.useEffect(() => {
    writeLS(CART_KEY, items);
  }, [items]);
  const add = (item) => setItems((prev) => [...prev, { ...item, lineId: Date.now() + "-" + Math.random().toString(36).slice(2, 7) }]);
  const remove = (lineId) => setItems((prev) => prev.filter((i) => i.lineId !== lineId));
  const update = (lineId, patch) =>
    setItems((prev) => prev.map((i) => (i.lineId === lineId ? { ...i, ...patch } : i)));
  const clear = () => setItems([]);
  const count = items.reduce((s, i) => s + (i.qty || 1), 0);
  const subtotal = items.reduce((s, i) => s + (i.price || 0) * (i.qty || 1), 0);
  return { items, add, remove, update, clear, count, subtotal };
}

function useOrders() {
  const [orders, setOrders] = React.useState(() => readLS(ORDERS_KEY, []));
  React.useEffect(() => {
    writeLS(ORDERS_KEY, orders);
  }, [orders]);
  const place = (order) => setOrders((prev) => [order, ...prev]);
  const setStatus = (id, status) =>
    setOrders((prev) => prev.map((o) => (o.id === id ? { ...o, status } : o)));
  const clearAll = () => setOrders([]);
  return { orders, place, setStatus, clearAll };
}

Object.assign(window, {
  PRODUCTS, FILAMENTS, fmtPrice, useCart, useOrders, genOrderId, findFilament, autoCodeColor, codeForUnit, CODE_CHOICE,
});
