// app-shell.jsx — shared state + header/footer/cart drawer used by every page
// ─────────────────────────────────────────────────────────────────────────────
// WIRED TO REAL API — FF_API (api-client.js) must load before this file.
// localStorage is NO LONGER used for cart/user/orders.
// ─────────────────────────────────────────────────────────────────────────────

const { useState: useStateS, useEffect: useEffectS, useMemo: useMemoS } = React;

// FF_STORE kept ONLY for non-critical UI prefs (theme, cardStyle)
const FF_STORE = {
  get(k, d) { try { const v = localStorage.getItem(k); return v == null ? d : JSON.parse(v); } catch { return d; } },
  set(k, v) { try { localStorage.setItem(k, JSON.stringify(v)); } catch { } },
  del(k) { try { localStorage.removeItem(k); } catch { } },
};

const FF_BASE = (() => {
  const p = location.pathname;
  return p.includes('/pages/') ? '../' : './';
})();

const FF_URLS = {
  home: '/',
  shop: '/shop',
  product: (id) => '/product/' + encodeURIComponent(id),
  cart: '/cart',
  checkout: '/checkout',
  order: (id) => '/order/' + encodeURIComponent(id),
  account: (tab) => '/account' + (tab ? '?tab=' + tab : ''),
  login: (next) => '/login' + (next ? '?next=' + encodeURIComponent(next) : ''),
  admin: '/admin',
  dev: '/pages/dev.html',
  search: (q) => '/search' + (q ? '?q=' + encodeURIComponent(q) : ''),
  category: (slug) => '/category/' + encodeURIComponent(slug),
  notfound: '/pages/404.html',
};

const FF_QP = (k, d = '') => {
  const sp = new URLSearchParams(location.search);
  return sp.get(k) ?? d;
};

// Get ID from clean URL path (/product/FF-123 or /order/FF-123)
// Falls back to ?id= query param for backwards compat
const FF_PATH_ID = () => {
  const segs = location.pathname.split('/').filter(Boolean);
  const last = segs[segs.length - 1];
  return (last && last !== 'product' && last !== 'order' && last !== 'category') ? last : FF_QP('id');
};

// ─────────────────────────────────────────────────────────────────────────────
//  useAppState — THE CAVE KING
//  All state lives here. One change here = whole site updates.
// ─────────────────────────────────────────────────────────────────────────────
function useAppState() {
  const [cart, setCart] = useStateS([]);
  const [wishIds, setWishIds] = useStateS(new Set());
  const [user, setUser] = useStateS(null);
  const [orders, setOrders] = useStateS([]);
  const [toast, setToast] = useStateS('');
  const [cartOpen, setCartOpen] = useStateS(false);
  const [authOpen, setAuthOpen] = useStateS(false);
  const [loading, setLoading] = useStateS(true);

  // BOOT: load user + cart from API on every page load
  useEffectS(() => {
    const boot = async () => {
      if (typeof FF_API === 'undefined') {
        console.error('FF_API not defined — api-client.js must load before app-shell.jsx');
        setLoading(false);
        return;
      }
      try {
        if (FF_API.auth.isLoggedIn()) {
          const me = await FF_API.auth.me();
          if (me) setUser(me);
        }
        const cartData = await FF_API.cart.get();
        if (cartData?.items) setCart(cartData.items);
        // Load wishlist IDs for heart state on cards
        if (typeof FF_API !== 'undefined' && FF_API.wishlist) {
          FF_API.wishlist.ids().then(ids => setWishIds(new Set(ids))).catch(() => { });
        }
      } catch (err) {
        console.warn('Boot error:', err);
      } finally {
        setLoading(false);
        if (window.__ffHideBoot) window.__ffHideBoot();
      }
    };
    boot();
  }, []);

  // ADD TO CART — guest check + stock enforcement
  const addToCart = async (product, qty = 1) => {
    // Guest — show login prompt instead of silent fail
    if (!user) {
      setToast('Sign in to add to your bag ✦');
      setTimeout(() => setOpenLogin(true), 600);
      return;
    }
    try {
      const updated = await FF_API.cart.add(product.id, qty);
      if (!updated?.items) throw new Error('No response');
      setCart(updated.items);
      setToast('Added to bag ✦');
      setCartOpen(true);
      if (window.FF_TRACK) window.FF_TRACK('add_to_cart', { product_id: product.id, name: product.name, price: product.price });
    } catch (err) {
      const msg = err?.message || '';
      if (msg.includes('stock') || msg.includes('Stock')) setToast(msg);
      else if (msg.includes('401') || msg.includes('auth')) { setToast('Sign in to add to bag'); setOpenLogin(true); }
      else setToast('Could not add to cart — try again');
    }
  };

  // UPDATE QTY — was: setCart(map) | now: PUT /api/cart/items/:id
  const updateQty = async (productId, qty) => {
    try {
      const updated = await FF_API.cart.update(productId, qty);
      setCart(updated.items);
    } catch (err) {
      console.error('updateQty error:', err);
    }
  };

  // REMOVE ITEM — was: setCart(filter) | now: DELETE /api/cart/items/:id
  const removeItem = async (productId) => {
    try {
      const updated = await FF_API.cart.remove(productId);
      setCart(updated.items);
    } catch (err) {
      console.error('removeItem error:', err);
    }
  };

  const clearCart = () => setCart([]);

  // LOGIN — was: setUser(mock) | now: POST /api/auth/login
  const onLogin = async (email, password) => {
    try {
      const { ok, data } = await FF_API.auth.login(email, password);
      if (!ok) return { ok: false, error: data.error || 'Login failed' };
      setUser(data.user);
      setAuthOpen(false);
      setToast('Welcome back ' + data.user.name.split(' ')[0] + ' \u2736');
      const cartData = await FF_API.cart.get();
      if (cartData?.items) setCart(cartData.items);
      return { ok: true };
    } catch (err) {
      return { ok: false, error: 'Login failed' };
    }
  };

  // REGISTER — was: nothing | now: POST /api/auth/register
  const onRegister = async (email, password, name, phone) => {
    try {
      const { ok, data } = await FF_API.auth.register(email, password, name, phone);
      if (!ok) return { ok: false, error: data.errors?.[0]?.msg || data.error || 'Registration failed' };
      setUser(data.user);
      setAuthOpen(false);
      setToast('Welcome to Fussy Finds, ' + data.user.name.split(' ')[0] + ' \u2736');
      const cartData = await FF_API.cart.get();
      if (cartData?.items) setCart(cartData.items);
      return { ok: true };
    } catch (err) {
      return { ok: false, error: 'Registration failed' };
    }
  };

  // LOGOUT — was: setUser(null) | now: POST /api/auth/logout + clear state
  const onLogout = async () => {
    await FF_API.auth.logout().catch(() => { });
    setUser(null);
    setCart([]);
    setOrders([]);
    setToast('Logged out. See you soon \u2736');
    location.href = FF_URLS.home;
  };

  // PLACE ORDER — was: push fake order to localStorage array
  //              now: order already in DB, just clear cart + return id
  const placeOrder = (orderId) => {
    setCart([]);
    return orderId;
  };

  // LOAD ORDERS — for account page
  const loadOrders = async () => {
    if (!user) return;
    try {
      const data = await FF_API.orders.list();
      setOrders(data);
    } catch (err) {
      console.error('loadOrders error:', err);
    }
  };

  // Expose toast globally for pages that don't have it in props
  React.useEffect(() => { window.FF_TOAST = setToast; }, [setToast]);

  const toggleWishlist = async (productId) => {
    if (!user) { setToast('Sign in to save to wishlist ♡'); setTimeout(() => setAuthOpen(true), 500); return; }
    const was = wishIds.has(productId);
    setWishIds(prev => { const n = new Set(prev); was ? n.delete(productId) : n.add(productId); return n; });
    setToast(was ? 'Removed from wishlist' : 'Saved to wishlist ♥');
    try {
      await FF_API.wishlist.toggle(productId);
    } catch {
      setWishIds(prev => { const n = new Set(prev); was ? n.add(productId) : n.delete(productId); return n; });
    }
  };

  return {
    cart, setCart, user, setUser, orders, setOrders,
    wishIds, toggleWishlist,
    refreshUser: async () => { const me = await FF_API.auth.me(); if (me?.id) setUser(me); },
    toast, setToast, cartOpen, setCartOpen, authOpen, setAuthOpen,
    loading,
    addToCart, updateQty, removeItem, clearCart,
    onLogin, onRegister, onLogout,
    login: onLogin, logout: onLogout,
    placeOrder, loadOrders,
  };
}

// --- goto shim -----------------------------------------------------------
function makeGoto() {
  return (r = {}) => {
    if (r.openLogin) { location.href = FF_URLS.login(location.pathname + location.search); return; }
    switch (r.page) {
      case 'home': location.href = FF_URLS.home; break;
      case 'shop':
        if (r.filter === 'viral') location.href = FF_URLS.shop + '?filter=viral';
        else if (r.filter === 'new') location.href = FF_URLS.shop + '?filter=new';
        else if (r.cat) location.href = FF_URLS.shop + '?cat=' + r.cat;
        else if (r.q) location.href = FF_URLS.search(r.q);
        else location.href = FF_URLS.shop;
        break;
      case 'pdp': location.href = FF_URLS.product(r.id); break;
      case 'cart': location.href = FF_URLS.cart; break;
      case 'checkout': location.href = FF_URLS.checkout; break;
      case 'order-confirm': location.href = FF_URLS.order(r.id); break;
      case 'account': location.href = FF_URLS.account(r.tab); break;
      case 'admin': location.href = FF_URLS.admin; break;
      case 'dev': location.href = FF_URLS.dev; break;
      default: location.href = FF_URLS.home;
    }
  };
}

// --- AppShell -----------------------------------------------------------

// ── Page loading bar ──────────────────────────────────────────────────────────
function PageLoader() {
  const [visible, setVisible] = React.useState(false);
  const [width, setWidth] = React.useState(0);

  React.useEffect(() => {
    // Show bar when navigating (click on <a> tags)
    const handleClick = (e) => {
      const a = e.target.closest('a[href]');
      if (!a) return;
      const href = a.getAttribute('href');
      // Only internal page navigations
      if (!href || href.startsWith('#') || href.startsWith('mailto') || href.startsWith('http')) return;
      if (a.target === '_blank') return;
      setVisible(true);
      setWidth(20);
      setTimeout(() => setWidth(70), 100);
      setTimeout(() => setWidth(90), 800);
    };
    document.addEventListener('click', handleClick);
    // Complete bar when page loads
    setVisible(true); setWidth(20);
    setTimeout(() => setWidth(60), 200);
    setTimeout(() => { setWidth(100); setTimeout(() => setVisible(false), 300); }, 600);
    return () => document.removeEventListener('click', handleClick);
  }, []);

  if (!visible) return null;
  return (
    <div style={{
      position: 'fixed', top: 0, left: 0, zIndex: 9999,
      height: 3, background: 'var(--ff-accent)',
      width: width + '%',
      transition: width === 100 ? 'width .2s ease' : 'width .6s ease',
      boxShadow: '0 0 8px var(--ff-accent)',
    }} />
  );
}


// ── NotFoundPage — fallback for unknown routes (also defined in pages-extra) ──
if (typeof NotFoundPage === 'undefined') {
  window.NotFoundPage = function NotFoundPage() {
    return React.createElement('main', { style: { textAlign: 'center', padding: '80px 24px' } },
      React.createElement('div', { style: { fontSize: 48, marginBottom: 16 } }, '404'),
      React.createElement('h2', { style: { fontFamily: 'var(--ff-font-display)', fontSize: 32, marginBottom: 8 } }, 'Page not found'),
      React.createElement('p', { style: { color: 'var(--ff-muted)', marginBottom: 24 } }, "This page doesn't exist."),
      React.createElement('a', { href: '/', style: { color: 'var(--ff-accent)', fontWeight: 600 } }, '← Back home')
    );
  };
}

function AppShell({ children, accent = '#E4439C', cardStyle = 'sticker', hideChrome = false, requireAuth = false }) {
  const s = useAppState();
  const goto = makeGoto();
  const [search, setSearch] = useStateS('');

  useEffectS(() => {
    document.documentElement.style.setProperty('--ff-accent', accent);
  }, [accent]);

  useEffectS(() => {
    if (!s.loading && requireAuth && !s.user) {
      location.href = FF_URLS.login(location.pathname + location.search);
    }
  }, [requireAuth, s.user, s.loading]);

  if (requireAuth && !s.loading && !s.user) {
    return React.createElement('div', { style: { padding: 60, textAlign: 'center', color: 'var(--ff-muted)' } }, 'Redirecting to login\u2026');
  }

  const ctx = { ...s, goto, search, setSearch, cardStyle };

  if (hideChrome) {
    return React.createElement(React.Fragment, null,
      typeof children === 'function' ? children(ctx) : children,
      React.createElement(PageLoader),
      React.createElement(Toast, { toast: s.toast, onDismiss: () => s.setToast('') })
    );
  }

  return React.createElement(React.Fragment, null,
    React.createElement(Header, { goto, cart: s.cart, openCart: () => s.setCartOpen(true), user: s.user, onLogin: () => s.setAuthOpen(true), search, setSearch }),
    typeof children === 'function' ? children(ctx) : children,
    React.createElement(Footer, null),
    (typeof CartDrawer !== 'undefined') &&
    React.createElement(CartDrawer, {
      open: s.cartOpen,
      onClose: () => s.setCartOpen(false),
      cart: s.cart,
      updateQty: s.updateQty,
      removeItem: s.removeItem,
      goto
    }),

    (typeof AuthModal !== 'undefined') &&
    React.createElement(AuthModal, {
      open: s.authOpen,
      onClose: () => s.setAuthOpen(false),
      onLogin: s.onLogin,
      onRegister: s.onRegister,
      refreshUser: async () => {
        const me = await FF_API.auth.me();
        if (me?.id) s.setUser(me);
      }
    }),
    typeof ThemeSwitcher !== 'undefined' ? React.createElement(ThemeSwitcher) : null,
    React.createElement(Toast, { toast: s.toast, onDismiss: () => s.setToast('') })
  );
}

Object.assign(window, { FF_STORE, FF_URLS, FF_BASE, FF_QP, useAppState, makeGoto, AppShell });
