// Shopping-cart store + useCart hook + <CartDrawer /> component.
// Exposes window.__bbCart = { useCart, addItem, removeItem, updateGuests, clearCart, openDrawer, closeDrawer, Drawer }
//
// Cart item shape:
//   { id, expId, date, departure, guests, addedAt }
//
// - Dedup rule: same (expId, date, departure) → update guests (don't create a second row)
// - Past-date items are pruned on every store read
// - localStorage key "bb-cart"

(function () {
  const STORAGE_KEY = "bb-cart";
  const DRAWER_KEY  = "bb-cart-drawer";

  // ─── storage ────────────────────────────────────────────
  function load() {
    try {
      const raw = localStorage.getItem(STORAGE_KEY);
      const arr = raw ? JSON.parse(raw) : [];
      return Array.isArray(arr) ? prune(arr) : [];
    } catch { return []; }
  }
  function save(items) {
    try { localStorage.setItem(STORAGE_KEY, JSON.stringify(items)); } catch {}
  }
  function prune(items) {
    const todayISO = new Date().toISOString().slice(0, 10);
    return items.filter(i => i && i.date >= todayISO);
  }

  // ─── state + subscribers ────────────────────────────────
  let items = load();
  let drawerOpen = false;
  const listeners = new Set();
  function notify() { listeners.forEach(fn => fn()); }

  function makeId(expId, date, departure) {
    return `${expId}_${date}_${departure}_${Math.random().toString(36).slice(2, 6)}`;
  }

  function addItem({ expId, date, departure, guests }) {
    if (!expId || !date || !departure || !guests) return null;
    const existing = items.find(i => i.expId === expId && i.date === date && i.departure === departure);
    if (existing) {
      items = items.map(i => i === existing ? { ...i, guests } : i);
    } else {
      items = [...items, {
        id: makeId(expId, date, departure),
        expId, date, departure, guests,
        addedAt: Date.now(),
      }];
    }
    save(items);
    notify();
    return items[items.length - 1].id;
  }

  function removeItem(id) {
    items = items.filter(i => i.id !== id);
    save(items);
    notify();
  }

  function updateGuests(id, guests) {
    const clamped = Math.max(1, Math.min(12, guests));
    items = items.map(i => i.id === id ? { ...i, guests: clamped } : i);
    save(items);
    notify();
  }

  function clearCart() {
    items = [];
    save(items);
    notify();
  }

  function openDrawer()  { drawerOpen = true;  notify(); }
  function closeDrawer() { drawerOpen = false; notify(); }

  // Totals helper — expects a fresh window.EXPERIENCES lookup
  function computeTotals(list) {
    const expIndex = Object.fromEntries((window.EXPERIENCES || []).map(e => [e.id, e]));
    let subtotal = 0, paxTotal = 0;
    const enriched = list.map(i => {
      const exp = expIndex[i.expId];
      const line = exp ? exp.price * i.guests : 0;
      subtotal += line;
      paxTotal += i.guests;
      return { ...i, exp, line };
    });
    const reserve4 = Math.round(subtotal * 0.04);
    return { items: enriched, subtotal, reserve4, paxTotal, rowCount: list.length };
  }

  // ─── React hook ─────────────────────────────────────────
  function useCart() {
    const [, force] = React.useReducer(x => x + 1, 0);
    React.useEffect(() => {
      listeners.add(force);
      return () => listeners.delete(force);
    }, []);
    const totals = computeTotals(items);
    return {
      ...totals,
      drawerOpen,
      addItem, removeItem, updateGuests, clearCart,
      openDrawer, closeDrawer,
    };
  }

  // ─── Cart drawer ─────────────────────────────────────────
  function CartDrawer({ lang }) {
    const cart = useCart();
    const router = window.__bbRouter;
    const t = (window.COPY && window.COPY[lang] && window.COPY[lang].cart) || {};
    const onCheckout = () => { cart.closeDrawer(); router.navigate("checkout"); };

    React.useEffect(() => {
      const onKey = (e) => { if (e.key === "Escape") cart.closeDrawer(); };
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }, []);

    return (
      <>
        <div className={`cart-scrim ${cart.drawerOpen ? "open" : ""}`} onClick={cart.closeDrawer} aria-hidden="true" />
        <aside className={`cart-drawer ${cart.drawerOpen ? "open" : ""}`} aria-hidden={!cart.drawerOpen}>
          <header className="cart-drawer-head">
            <span className="eyebrow">{t.eyebrow}</span>
            <button className="cart-drawer-close" onClick={cart.closeDrawer} aria-label={t.close}>×</button>
          </header>

          {cart.items.length === 0 ? (
            <div className="cart-empty">
              <p className="display small">{t.empty}</p>
              <p className="cart-empty-sub">{t.emptySub}</p>
              <button className="btn btn-primary" onClick={() => { cart.closeDrawer(); router.navigate("catalog"); }}>
                {t.browse} →
              </button>
            </div>
          ) : (
            <>
              <ul className="cart-list">
                {cart.items.map((item) => {
                  if (!item.exp) return null;
                  const dateStr = formatDate(item.date, lang);
                  return (
                    <li key={item.id} className="cart-line">
                      <a href={"/experiences/" + item.exp.slug}
                         onClick={(e) => { if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return; e.preventDefault(); cart.closeDrawer(); router.navigate("detail", item.exp); }}
                         className="cart-line-img">
                        <img src={item.exp.thumb} alt="" />
                      </a>
                      <div className="cart-line-body">
                        <strong className="cart-line-title">{item.exp.title[lang]}</strong>
                        <span className="mono cart-line-meta">{dateStr} · {item.departure}</span>
                        <div className="cart-line-row">
                          <div className="cart-stepper">
                            <button type="button" onClick={() => cart.updateGuests(item.id, item.guests - 1)} aria-label="−">−</button>
                            <span>{item.guests}</span>
                            <button type="button" onClick={() => cart.updateGuests(item.id, item.guests + 1)} aria-label="+">+</button>
                          </div>
                          <span className="cart-line-price mono">${item.line} USD</span>
                        </div>
                      </div>
                      <button className="cart-line-remove" onClick={() => cart.removeItem(item.id)} aria-label={t.remove}>×</button>
                    </li>
                  );
                })}
              </ul>

              <footer className="cart-drawer-foot">
                <div className="cart-totals">
                  <div><span className="mono">{t.subtotal}</span><span>${cart.subtotal} USD</span></div>
                  <div className="cart-total-row"><span className="mono">{t.total}</span><strong className="display small">${cart.subtotal}</strong></div>
                  <p className="mono cart-totals-note">{t.plusReserve}</p>
                </div>
                <button className="btn btn-primary btn-lg full" onClick={onCheckout}>{t.checkout} →</button>
                <button className="btn btn-ghost" onClick={cart.closeDrawer}>{t.keepBrowsing}</button>
              </footer>
            </>
          )}
        </aside>
      </>
    );
  }

  // ─── date formatter (shared) ────────────────────────────
  function formatDate(iso, lang) {
    if (!iso) return "";
    const [y, m, d] = iso.split("-").map(Number);
    const dt = new Date(y, m - 1, d);
    return dt.toLocaleDateString(lang === "en" ? "en-US" : "es-ES", { weekday: "short", day: "numeric", month: "short" });
  }

  window.__bbCart = {
    useCart, addItem, removeItem, updateGuests, clearCart,
    openDrawer, closeDrawer, Drawer: CartDrawer, formatDate,
  };
})();
