// static/js/product-cache.js – FINAL VERSION
// Shared IndexedDB for SwiftPOS (products + cart + offline_orders)

const DB_NAME = "swift_pos_db";
const DB_VERSION = 6; // bumped to 6 — forces re-fetch with image + category fields
let db;

function openDB() {
  return new Promise((resolve, reject) => {
    const req = indexedDB.open(DB_NAME, DB_VERSION);

    req.onupgradeneeded = (e) => {
      db = e.target.result;

      // Drop and recreate products store to clear stale cache
      if (db.objectStoreNames.contains("products")) {
        db.deleteObjectStore("products");
      }
      const p = db.createObjectStore("products", { keyPath: "id" });
      p.createIndex("name", "name");
      p.createIndex("barcode", "barcode");

      if (!db.objectStoreNames.contains("cart_items")) {
        db.createObjectStore("cart_items", { keyPath: "id" }); // id = productId
      }

      if (!db.objectStoreNames.contains("cart_totals")) {
        db.createObjectStore("cart_totals", { keyPath: "id" }); // id = "current"
      }

      if (!db.objectStoreNames.contains("offline_orders")) {
        db.createObjectStore("offline_orders", { keyPath: "id" });
      }
    };

    req.onsuccess = () => {
      db = req.result;
      resolve(db);
    };

    req.onerror = () => reject(req.error);
  });
}

// Save ALL products (including out-of-stock) into DB
function saveProductsToDB(products) {
  return new Promise((resolve) => {
    const tx = db.transaction("products", "readwrite");
    const store = tx.objectStore("products");
    store.clear();
    (products || []).forEach((p) => store.put(p));
    tx.oncomplete = () => resolve();
  });
}

// Load all products from DB
function loadProductsFromDB() {
  return new Promise((resolve) => {
    const tx = db.transaction("products", "readonly");
    const req = tx.objectStore("products").getAll();
    req.onsuccess = () => resolve(req.result || []);
  });
}

// Fetch from server + update DB
async function fetchProductsFromServer() {
  const res = await fetch("/inventory/api/products/json/");
  if (!res.ok) throw new Error("Network error");

  const data = await res.json();
  await saveProductsToDB(data);

  // return only in-stock
  return (data || []).filter((p) => Number(p.stock_quantity) > 0);
}

// Public API: load products (online → server, offline → DB)
async function loadProducts() {
  await openDB();
  if (navigator.onLine) {
    try {
      return await fetchProductsFromServer();
    } catch (err) {
      // network failed → fallback to DB
      return loadProductsFromDB();
    }
  }
  return loadProductsFromDB();
}

// Public API: force refresh from server (used by refresh button / auto-update)
async function refreshProducts() {
  await openDB();
  return fetchProductsFromServer();
}

window.swiftposOpenDB = openDB;
window.swiftposLoadProducts = loadProducts;
window.swiftposRefreshProducts = refreshProducts;
