// main.jsx — Lasso app shell, router, cart state, tweaks

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "heroVariant": "living",
  "menuLayout": "image-led",
  "trackingLayout": "map-led",
  "trackingStatus": "auto",
  "devOverlay": false
}/*EDITMODE-END*/;

function App({ tweaks, setTweak }) {
  // ── Route stack ───────────────────────────────────────────────────
  const [stack, setStack] = React.useState([{ name: 'home' }]);
  const cur = stack[stack.length - 1];

  const nav = (name, params = {}) => setStack(s => [...s, { name, ...params }]);
  const back = () => setStack(s => s.length > 1 ? s.slice(0, -1) : [{ name: 'home' }]);
  const replaceTo = (name, params = {}) => setStack([{ name, ...params }]);

  // ── Auth ──────────────────────────────────────────────────────────
  const [authed, setAuthedRaw] = React.useState(() => {
    try { return localStorage.getItem('lasso_customer_session_v1') === '1'; } catch (e) { return false; }
  });
  const setAuthed = (v) => {
    setAuthedRaw(v);
    try { v ? localStorage.setItem('lasso_customer_session_v1', '1') : localStorage.removeItem('lasso_customer_session_v1'); } catch (e) {}
  };
  const [redirectAfterAuth, setRedirectAfterAuth] = React.useState(null);

  // ── Lucky Strike (route-owned; loaded only when entered) ──────────
  const luckyStrike = {
    open: cur.name === 'lucky-strike',
    source: cur.name === 'lucky-strike' ? cur.source || null : null,
  };
  const [lsJoined, setLsJoined] = React.useState(() => {
    try { return localStorage.getItem('lasso_lucky_strike_waitlist_v1') === '1'; } catch (e) { return false; }
  });
  const openLuckyStrike = (source) => nav('lucky-strike', { source });
  const closeLuckyStrike = () => back();
  const joinLuckyStrike = () => {
    setLsJoined(true);
    try { localStorage.setItem('lasso_lucky_strike_waitlist_v1', '1'); } catch (e) {}
    toast('You’re on the Lucky Strike waitlist', 'success');
  };

  // ── Cart ──────────────────────────────────────────────────────────
  const [cart, setCart] = React.useState([]);

  const addToCart = ({ item, restaurant, modifiers = [], computedPrice }) => {
    const price = computedPrice != null ? computedPrice : item.price;
    const cart_id = `${item.id}-${Date.now()}-${Math.floor(Math.random()*999)}`;
    setCart(c => [...c, {
      cart_id, item_id: item.id, restaurant_id: restaurant.id,
      item_name: item.name, price, quantity: 1, modifiers, hue: item.hue,
    }]);
  };
  const removeFromCart = (cart_id) => setCart(c => c.filter(i => i.cart_id !== cart_id));
  const updateCartQty = (cart_id, qty) => setCart(c => c.map(i => i.cart_id === cart_id ? { ...i, quantity: qty } : i));
  const clearCart = () => setCart([]);

  // ── Favourites ────────────────────────────────────────────────────
  const [favourites, setFavourites] = React.useState(() => new Set());
  const isFavourite = (itemId) => favourites.has(itemId);
  const toggleFavourite = (itemId) => {
    let added = false;
    setFavourites(prev => {
      const next = new Set(prev);
      if (next.has(itemId)) { next.delete(itemId); added = false; }
      else { next.add(itemId); added = true; }
      return next;
    });
    return !favourites.has(itemId);
  };

  // ── Favourite stores (whole restaurants) ──────────────────────────
  const [favStores, setFavStores] = React.useState(() => new Set());
  const isFavStore = (rid) => favStores.has(rid);
  const toggleFavStore = (rid) => {
    let added = false;
    setFavStores(prev => {
      const next = new Set(prev);
      if (next.has(rid)) next.delete(rid); else { next.add(rid); added = true; }
      return next;
    });
    return !favStores.has(rid);
  };

  // ── Promo (applied basket-wide) ────────────────────────────────────
  const [promo, setPromo] = React.useState(null); // one of EARNED_PROMOS or custom {code,...}

  // ── Trail Pass — per-kitchen stamp bumps this session ─────────────
  const [passStamps, setPassStamps] = React.useState({});
  const bumpPass = (rid) => { if (rid) setPassStamps(s => ({ ...s, [rid]: (s[rid] || 0) + 1 })); };

  // ── Rewards loop — live XP / streak / challenge progress ──────────
  const [xp, setXp] = React.useState(PROFILE.xp_points);
  const [streak, setStreak] = React.useState(PROFILE.streak_current);
  const [ordersCount, setOrdersCount] = React.useState(PROFILE.total_orders);
  const [challengeProgress, setChallengeProgress] = React.useState(() =>
    Object.fromEntries(PROFILE.challenges.map(c => [c.id, c.progress])));
  const [lastEarn, setLastEarn] = React.useState(null);
  const awardOrder = (order) => {
    const gained = Math.max(10, Math.round(order.total * 2));
    const firstOfDay = !lastEarn; // first order this session secures the streak day
    const nextStreak = streak + (firstOfDay ? 1 : 0);
    const c1 = PROFILE.challenges[0]; // 'Three for the trail'
    const prev = challengeProgress[c1.id] || 0;
    const c1next = Math.min(c1.total, prev + 1);
    const completed = c1next === c1.total && prev < c1.total;
    const bonus = completed ? c1.xp : 0;
    setXp(x => x + gained + bonus);
    setStreak(nextStreak);
    setOrdersCount(n => n + 1);
    bumpPass(order.restaurantId);
    setChallengeProgress(p => ({ ...p, [c1.id]: c1next }));
    setLastEarn({
      gained, bonus, streak: nextStreak,
      challenge: { title: c1.title, progress: c1next, total: c1.total, completed, xp: c1.xp },
    });
  };

  // ── Wallet + friends (gifting) ─────────────────────────────────────
  const [walletBalance, setWalletBalance] = React.useState(PROFILE.wallet_balance);
  const [friends, setFriends] = React.useState(FRIENDS);
  const addFriend = (name, initials) => setFriends(f => [...f, { id: 'f' + Date.now(), name, initials: initials || name.split(' ').map(w => w[0]).join(''), orders: 0, mutual: 'New to the posse', online: true }]);
  const sendGift = (friendId, amount) => {
    setWalletBalance(b => Math.max(0, +(b - amount).toFixed(2)));
  };
  const topUpWallet = (amount) => setWalletBalance(b => +(b + amount).toFixed(2));

  // ── Active order (for tracking) ────────────────────────────────────
  const [activeOrder, setActiveOrder] = React.useState(null);

  // ── Toast ─────────────────────────────────────────────────────────
  const [toastMsg, setToastMsg] = React.useState(null);
  const [toastKind, setToastKind] = React.useState('success');
  const toast = (msg, kind = 'success') => { setToastMsg(msg); setToastKind(kind); };

  // ── Restaurant nav ────────────────────────────────────────────────
  const [activeRestaurantId, setActiveRestaurantId] = React.useState(null);
  const openRestaurant = (id) => { setActiveRestaurantId(id); nav('restaurant'); };

  // ── Map route → bottom-nav tab ────────────────────────────────────
  const tabFromRoute = ({
    home: 'home', restaurant: 'home', auth: 'home', checkout: 'home', confirmation: 'home',
    tracking: 'orders', orders: 'orders', rewards: 'rewards', 'lucky-strike': 'rewards', showdowns: 'shootout', profile: 'profile', notifications: 'profile',
  })[cur.name] || 'home';

  const onTabChange = (tab) => {
    if (tab === 'home') replaceTo('home');
    else if (tab === 'orders') replaceTo('orders');
    else if (tab === 'shootout') replaceTo('showdowns');
    else if (tab === 'rewards') replaceTo('rewards');
    else if (tab === 'profile') replaceTo('profile');
  };

  const showNav = ['home', 'orders', 'rewards', 'profile'].includes(cur.name);

  const app = {
    nav, back, replaceTo, currentRoute: cur.name,
    activeRestaurantId, openRestaurant,
    authed, setAuthed, redirectAfterAuth, setRedirectAfterAuth,
    luckyStrike, openLuckyStrike, closeLuckyStrike, lsJoined, joinLuckyStrike,
    cart, addToCart, removeFromCart, updateCartQty, clearCart,
    activeOrder, setActiveOrder, activeOrderId: activeOrder?.id,
    favourites, isFavourite, toggleFavourite,
    favStores, isFavStore, toggleFavStore,
    promo, setPromo,
    xp, streak, ordersCount, challengeProgress, lastEarn, awardOrder,
    grantXp: (n) => setXp(x => x + n),
    passStamps, bumpPass,
    walletBalance, friends, addFriend, sendGift, topUpWallet,
    toast, tweaks, setTweak,
  };

  // Apply theme attribute
  React.useEffect(() => {
    document.body.setAttribute('data-theme', tweaks.theme || 'light');
  }, [tweaks.theme]);

  // Expose for demo helpers
  React.useEffect(() => { window.__appInstance = app; });

  const renderScreen = () => {
    switch (cur.name) {
      case 'home': return <HomeScreen app={app}/>;
      case 'auth': return <AuthScreen app={app}/>;
      case 'restaurant': return <RestaurantScreen app={app}/>;
      case 'checkout': return <CheckoutScreen app={app}/>;
      case 'confirmation': return <ConfirmationScreen app={app}/>;
      case 'tracking': return <PrototypeRouteBoundary routeName="tracking" app={app}/>;
      case 'orders': return <OrdersScreen app={app}/>;
      case 'rewards': return <RewardsScreen app={app}/>;
      case 'lucky-strike': return <PrototypeRouteBoundary routeName="lucky-strike" app={app}/>;
      case 'showdowns': return <PrototypeRouteBoundary routeName="showdowns" app={app}/>;
      case 'profile': return <ProfileScreen app={app}/>;
      case 'notifications': return <NotificationsScreen app={app}/>;
      default: return <HomeScreen app={app}/>;
    }
  };

  const cartCount = cart.reduce((s,i)=>s+i.quantity, 0);

  return (
    <div data-lv-anim="" className={tweaks.devOverlay ? 'lasso-dev-overlay' : ''} style={{
      width: '100%', height: '100%', display: 'flex', flexDirection: 'column',
      paddingTop: 0, background: 'var(--bg-app)', position: 'relative', overflow: 'hidden',
    }}>
      <LivingStyles/>
      <div key={cur.name} style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden', minHeight: 0 }}>
        {renderScreen()}
      </div>
      {showNav && (
        <div data-production-mobile-nav-layer="" style={{
          position: 'absolute',
          left: 0,
          right: 0,
          bottom: 0,
          zIndex: 180,
          padding: '0 0 max(24px, env(safe-area-inset-bottom))',
          pointerEvents: 'none',
        }}>
          <div style={{ pointerEvents: 'auto' }}>
            {activeOrder && <LiveOrderBar app={app}/>}
            <BottomNav active={tabFromRoute} onChange={onTabChange} cartCount={cartCount}/>
          </div>
        </div>
      )}
      <LevelUpOverlay app={app}/>
      {/* Frame-level layer for bottom sheets / drawers (non-scrolling) */}
      <div id="lasso-sheet-layer" style={{ position: 'absolute', inset: 0, zIndex: 1400, pointerEvents: 'none' }}/>
      <Toast msg={toastMsg} kind={toastKind} onDone={() => setToastMsg(null)}/>
    </div>
  );
}

// ── Live order bar — persistent “order in flight” strip above the nav ─
function LiveOrderBar({ app }) {
  const order = app.activeOrder;
  const r = RESTAURANT_LOOKUP[order.restaurantId];
  return (
    <div onClick={() => app.nav('tracking')} data-lasso="live-order-bar" style={{
      margin: '0 12px 8px', padding: '10px 12px', borderRadius: 16, cursor: 'pointer',
      background: 'var(--dark-chocolate)', color: 'var(--dust-cream)',
      display: 'flex', alignItems: 'center', gap: 10, boxShadow: 'var(--shadow-lg)',
      animation: 'lasso-slide-up 320ms var(--ease-out)',
    }}>
      <span style={{ width: 9, height: 9, borderRadius: '50%', background: 'var(--brand-orange)', animation: 'lasso-pulse 1.4s infinite', flexShrink: 0 }}/>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 12.5, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
          Order from {r?.name || 'the kitchen'} is live
        </div>
        <div style={{ fontFamily: 'var(--font-body)', fontSize: 10.5, color: '#9F8979', marginTop: 1 }}>Diego’s on the trail · tap to watch the ride</div>
      </div>
      <span style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 11.5, color: '#fff', background: 'var(--brand-orange)', padding: '7px 13px', borderRadius: 10, flexShrink: 0 }}>Track →</span>
    </div>
  );
}

// ── Tweaks panel ─────────────────────────────────────────────────────
function LassoTweaks({ tweaks, setTweak }) {
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="Theme">
        <TweakRadio label="Mode" options={[
          { value: 'light', label: 'Light' },
          { value: 'dark', label: 'Dark' },
        ]} value={tweaks.theme} onChange={v => setTweak('theme', v)}/>
      </TweakSection>

      <TweakSection label="Home hero">
        <TweakSelect label="Variant" options={[
          { value: 'living', label: 'Living — dusk scene' },
          { value: 'classic', label: 'Classic — bull + headline' },
          { value: 'illustration', label: 'Illustration — full art' },
          { value: 'trust', label: 'Trust — stats forward' },
        ]} value={tweaks.heroVariant} onChange={v => setTweak('heroVariant', v)}/>
      </TweakSection>

      <TweakSection label="Restaurant menu">
        <TweakRadio label="Layout" options={[
          { value: 'image-led', label: 'Image-led' },
          { value: 'list-led', label: 'List-led' },
        ]} value={tweaks.menuLayout} onChange={v => setTweak('menuLayout', v)}/>
      </TweakSection>

      <TweakSection label="Live tracking">
        <TweakRadio label="Layout" options={[
          { value: 'map-led', label: 'Map-led' },
          { value: 'status-led', label: 'Status-led' },
        ]} value={tweaks.trackingLayout} onChange={v => setTweak('trackingLayout', v)}/>
        <TweakSelect label="Status (force)" options={[
          { value: 'auto', label: 'Auto-progress' },
          { value: 'payment_confirmed', label: '1 · Order confirmed' },
          { value: 'sent_to_kitchen', label: '2 · Sent to kitchen' },
          { value: 'preparing', label: '3 · Being prepared' },
          { value: 'ready_for_collection', label: '4 · Ready for pickup' },
          { value: 'agent_assigned', label: '5 · Rider assigned' },
          { value: 'agent_collected', label: '6 · Order collected' },
          { value: 'en_route', label: '7 · On the way' },
          { value: 'delivered', label: '8 · Delivered' },
          { value: 'payment_pending', label: '⚠ Pending payment' },
          { value: 'cancelled', label: '⚠ Cancelled' },
          { value: 'refunded', label: '⚠ Refunded' },
        ]} value={tweaks.trackingStatus} onChange={v => setTweak('trackingStatus', v)}/>
      </TweakSection>

      <TweakSection label="Developer">
        <TweakToggle label="Show data-lasso hooks" value={tweaks.devOverlay} onChange={v => setTweak('devOverlay', v)}/>
      </TweakSection>

      <TweakSection label="Demo helpers">
        <TweakButton label="Jump to live tracking" onClick={() => {
          const app = window.__appInstance;
          if (!app) return;
          app.setActiveOrder({
            id: 'LSO-22141', restaurantId: 'rojo-smoke',
            items: [{ item_name: 'Brisket Tacos', quantity: 1 }, { item_name: 'Smoked Mac', quantity: 1 }],
            total: 21.00, address: ADDRESSES[0],
          });
          app.replaceTo('tracking');
        }}/>
        <TweakButton secondary label="Trigger level-up" onClick={() => {
          const app = window.__appInstance;
          if (!app) return;
          app.grantXp(Math.max(0, 2500 - app.xp) + 20);
        }}/>
        <TweakButton secondary label="Reset to home" onClick={() => {
          const app = window.__appInstance;
          if (!app) return;
          app.clearCart();
          app.setActiveOrder(null);
          app.replaceTo('home');
        }}/>
      </TweakSection>
    </TweaksPanel>
  );
}

// ── Root mount ───────────────────────────────────────────────────────
function Root() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);

  React.useEffect(() => {
    const setViewportHeight = () => {
      const height = window.visualViewport?.height || window.innerHeight;
      document.documentElement.style.setProperty('--lasso-viewport-height', `${height}px`);
    };
    setViewportHeight();
    window.visualViewport?.addEventListener('resize', setViewportHeight);
    window.addEventListener('resize', setViewportHeight);
    return () => {
      window.visualViewport?.removeEventListener('resize', setViewportHeight);
      window.removeEventListener('resize', setViewportHeight);
    };
  }, []);

  return (
    <div data-production-mobile-root="" style={{
      width: '100vw',
      height: 'var(--lasso-viewport-height, 100dvh)',
      minHeight: 0,
      maxHeight: 'var(--lasso-viewport-height, 100dvh)',
      display: 'flex',
      alignItems: 'stretch',
      justifyContent: 'center',
      padding: 0,
      margin: 0,
      background: '#F2F2F7',
      overflow: 'hidden',
    }}>
      <IOSDevice width={390} height={844} dark={false}>
        <App tweaks={tweaks} setTweak={setTweak}/>
      </IOSDevice>
      <LassoTweaks tweaks={tweaks} setTweak={setTweak}/>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Root/>);
