/* ===========================================================
   State: hash router + Cart + Quote providers (localStorage)
   =========================================================== */
const { useState, useEffect, useRef, useCallback, createContext, useContext, useMemo } = React;

/* ---------------- hash router ---------------- */
function parseHash() {
  let h = window.location.hash.replace(/^#/, "") || "/";
  const [path, query] = h.split("?");
  const params = {};
  if (query) query.split("&").forEach(kv => { const [k, v] = kv.split("="); params[k] = decodeURIComponent(v || ""); });
  return { path, params };
}
const RouterCtx = createContext(null);
function RouterProvider({ children }) {
  const [route, setRoute] = useState(parseHash());
  useEffect(() => {
    const on = () => { setRoute(parseHash()); window.scrollTo(0, 0);
      const sc = document.querySelector(".app-scroll"); if (sc) sc.scrollTo(0,0); };
    window.addEventListener("hashchange", on);
    return () => window.removeEventListener("hashchange", on);
  }, []);
  const navigate = useCallback((to) => {
    if (("#" + to) === window.location.hash) { window.scrollTo(0,0); const sc=document.querySelector(".app-scroll"); if(sc) sc.scrollTo(0,0); }
    window.location.hash = to;
  }, []);
  return React.createElement(RouterCtx.Provider, { value: { ...route, navigate } }, children);
}
const useRouter = () => useContext(RouterCtx);
function Link({ to, children, className, style, onClick }) {
  const { navigate } = useRouter();
  return React.createElement("a", {
    href: "#" + to, className, style,
    onClick: (e) => { e.preventDefault(); onClick && onClick(e); navigate(to); }
  }, children);
}

/* ---------------- persistence helper ---------------- */
function usePersist(key, initial) {
  const [val, setVal] = useState(() => {
    try { const r = localStorage.getItem(key); return r ? JSON.parse(r) : initial; } catch (e) { return initial; }
  });
  useEffect(() => { try { localStorage.setItem(key, JSON.stringify(val)); } catch (e) {} }, [key, val]);
  return [val, setVal];
}

/* ---------------- Cart ---------------- */
const CartCtx = createContext(null);
function CartProvider({ children }) {
  const [items, setItems] = usePersist("dwt_cart", []); // {variant_id, sku, name, product_slug, quantity, unit_price, core_charge, image}
  const [reservationExpires, setReservationExpires] = usePersist("dwt_cart_exp", null);
  const add = useCallback((line) => {
    setItems(prev => {
      const i = prev.findIndex(x => x.variant_id === line.variant_id);
      let next;
      if (i >= 0) { next = prev.slice(); next[i] = { ...next[i], quantity: next[i].quantity + (line.quantity || 1) }; }
      else next = [...prev, { ...line, quantity: line.quantity || 1 }];
      return next;
    });
    setReservationExpires(Date.now() + 15 * 60 * 1000);
  }, []);
  const setQty = useCallback((vid, q) => setItems(prev => prev.map(x => x.variant_id === vid ? { ...x, quantity: Math.max(1, q) } : x)), []);
  const remove = useCallback((vid) => setItems(prev => prev.filter(x => x.variant_id !== vid)), []);
  const clear = useCallback(() => setItems([]), []);
  const count = items.reduce((s, x) => s + x.quantity, 0);
  const subtotal = items.reduce((s, x) => s + (x.unit_price || 0) * x.quantity, 0);
  const coreTotal = items.reduce((s, x) => s + (x.core_charge || 0) * x.quantity, 0);
  return React.createElement(CartCtx.Provider, { value: { items, add, setQty, remove, clear, count, subtotal, coreTotal, reservationExpires } }, children);
}
const useCart = () => useContext(CartCtx);

/* ---------------- Quote list ---------------- */
const QuoteCtx = createContext(null);
function QuoteProvider({ children }) {
  const [items, setItems] = usePersist("dwt_quote", []);     // catalog lines
  const [custom, setCustom] = usePersist("dwt_quote_custom", []); // {description, quantity}
  const addItem = useCallback((line) => {
    setItems(prev => {
      const i = prev.findIndex(x => x.variant_id === line.variant_id);
      if (i >= 0) { const n = prev.slice(); n[i] = { ...n[i], quantity: n[i].quantity + (line.quantity || 1) }; return n; }
      return [...prev, { ...line, quantity: line.quantity || 1 }];
    });
  }, []);
  const setQty = useCallback((vid, q) => setItems(prev => prev.map(x => x.variant_id === vid ? { ...x, quantity: Math.max(1, q) } : x)), []);
  const remove = useCallback((vid) => setItems(prev => prev.filter(x => x.variant_id !== vid)), []);
  const addCustom = useCallback((c) => setCustom(prev => [...prev, { description: "", quantity: 1, ...c, _id: Date.now() + Math.random() }]), []);
  const setCustomField = useCallback((id, field, v) => setCustom(prev => prev.map(c => c._id === id ? { ...c, [field]: v } : c)), []);
  const removeCustom = useCallback((id) => setCustom(prev => prev.filter(c => c._id !== id)), []);
  const clear = useCallback(() => { setItems([]); setCustom([]); }, []);
  const count = items.reduce((s, x) => s + x.quantity, 0) + custom.length;
  return React.createElement(QuoteCtx.Provider, {
    value: { items, custom, addItem, setQty, remove, addCustom, setCustomField, removeCustom, clear, count }
  }, children);
}
const useQuote = () => useContext(QuoteCtx);

/* ---------------- toast ---------------- */
const ToastCtx = createContext(null);
function ToastProvider({ children }) {
  const [toasts, setToasts] = useState([]);
  const push = useCallback((msg, opts = {}) => {
    const id = Date.now() + Math.random();
    setToasts(t => [...t, { id, msg, ...opts }]);
    setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), opts.duration || 2600);
  }, []);
  return React.createElement(ToastCtx.Provider, { value: { push } },
    children,
    React.createElement(Toaster, { toasts })
  );
}
const useToast = () => useContext(ToastCtx);
function Toaster({ toasts }) {
  return React.createElement("div", { className: "toaster" },
    toasts.map(t => React.createElement("div", { key: t.id, className: "toast" },
      React.createElement(Icon, { name: t.icon || "check", size: 16 }),
      React.createElement("span", null, t.msg),
      t.action ? React.createElement(Link, { to: t.action.to, className: "toast-action" }, t.action.label) : null
    ))
  );
}

/* ---------------- money fmt ---------------- */
function money(n) { if (n === null || n === undefined) return null; return "$" + n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }

/* ---------------- Tweaks context (values provided by TweaksProvider in app.jsx) ---------------- */
const TweaksCtx = createContext(null);
function useT() { return useContext(TweaksCtx) || { t: {}, setTweak: () => {} }; }

Object.assign(window, { RouterProvider, useRouter, Link, CartProvider, useCart, QuoteProvider, useQuote, ToastProvider, useToast, usePersist, money, TweaksCtx, useT });
