// TownPost interactive prototype
// Wraps every screen in a router with back-stack and wires up the inter-screen taps
// (alerts → detail, posts → detail, compose FAB, tab bar, etc).
// Exposes a tweaks panel so the user can A/B variants, swap frames, and reset state.

const { useState, useEffect, useRef, useCallback, useMemo } = React;

// ─── iOS / Android frame wrappers (mirrors what TownPost.html had) ─────────
function ProtoIOS({ children, w = 380, h = 820, dark = false }) {
  return (
    <div data-frame="ios" style={{
      width: w, height: h, borderRadius: 48, overflow: 'hidden', position: 'relative',
      background: '#000',
      boxShadow: '0 30px 70px rgba(0,0,0,0.18), 0 0 0 1px rgba(0,0,0,0.12)',
      WebkitFontSmoothing: 'antialiased',
    }}>
      <div style={{
        position: 'absolute', top: 11, left: '50%', transform: 'translateX(-50%)',
        width: 116, height: 33, borderRadius: 22, background: '#000', zIndex: 50,
      }} />
      <div style={{ position: 'absolute', top: 0, left: 0, right: 0, zIndex: 10 }}>
        <IOSStatusBar dark={dark} />
      </div>
      <div style={{
        width: '100%', height: '100%', paddingTop: 47, boxSizing: 'border-box',
        display: 'flex', flexDirection: 'column', background: TP.cream,
      }}>
        <div style={{ flex: 1, overflow: 'hidden' }}>{children}</div>
      </div>
      <div style={{
        position: 'absolute', bottom: 0, left: 0, right: 0, zIndex: 60, height: 30,
        display: 'flex', justifyContent: 'center', alignItems: 'flex-end', paddingBottom: 8,
        pointerEvents: 'none',
      }}>
        <div style={{ width: 130, height: 5, borderRadius: 100, background: 'rgba(0,0,0,0.25)' }} />
      </div>
    </div>
  );
}

function ProtoAndroid({ children, w = 380, h = 820 }) {
  return (
    <div style={{
      width: w, height: h, borderRadius: 18, overflow: 'hidden', background: TP.cream,
      border: '8px solid rgba(116,119,117,0.5)',
      boxShadow: '0 30px 70px rgba(0,0,0,0.22)',
      display: 'flex', flexDirection: 'column', boxSizing: 'border-box',
    }}>
      <AndroidStatusBar dark={false} />
      <div style={{ flex: 1, overflow: 'hidden' }}>{children}</div>
      <AndroidNavBar />
    </div>
  );
}

// ─── Toast (transient feedback for actions like Bookmark / Mark helpful) ───
function Toast({ msg, onDone }) {
  useEffect(() => {
    if (!msg) return;
    const t = setTimeout(onDone, 1800);
    return () => clearTimeout(t);
  }, [msg, onDone]);
  if (!msg) return null;
  return (
    <div style={{
      position: 'absolute', bottom: 84, left: '50%', transform: 'translateX(-50%)',
      background: 'rgba(34,30,22,0.92)', color: TP.cream,
      padding: '9px 14px', borderRadius: 999,
      fontFamily: TP.sans, fontSize: 12.5, fontWeight: 500,
      whiteSpace: 'nowrap', zIndex: 100,
      boxShadow: '0 6px 20px rgba(0,0,0,0.18)',
      animation: 'tpToastIn 0.18s ease-out',
    }}>
      {msg}
    </div>
  );
}

// ─── Router state ──────────────────────────────────────────────────────────
// route is { name, props? } — stack is array of routes
const DEFAULT_ROUTE = { name: 'home' };

function useRouter(initialName) {
  const [stack, setStack] = useState([{ name: initialName || 'home' }]);
  const route = stack[stack.length - 1];

  const push = useCallback((name, props) => {
    setStack((s) => [...s, { name, props }]);
  }, []);
  const replace = useCallback((name, props) => {
    setStack((s) => [...s.slice(0, -1), { name, props }]);
  }, []);
  const back = useCallback(() => {
    setStack((s) => (s.length > 1 ? s.slice(0, -1) : [{ name: 'home' }]));
  }, []);
  const reset = useCallback((name) => {
    setStack([{ name: name || 'home' }]);
  }, []);

  return { route, stack, push, replace, back, reset };
}

// ─── Variant pickers ───────────────────────────────────────────────────────
function pickDashboard(v) {
  if (v === 'B') return ScreenDashboardB;
  if (v === 'C') return ScreenDashboardC;
  return ScreenDashboardA;
}
function pickFeed(v) {
  if (v === 'B') return ScreenFeedB;
  if (v === 'C') return ScreenFeedC;
  return ScreenFeedA;
}

// ─── The interactive prototype shell ───────────────────────────────────────
// Renders the chosen frame, owns router state, and dispatches inter-screen actions.
function TPInteractive({
  device = 'ios',
  dashboardVariant = 'A',
  feedVariant = 'A',
  tabVariant = 'classic',
  initial = 'home',
  showBackChip = true,
}) {
  const router = useRouter(initial);
  const [toast, setToast] = useState(null);

  // Whenever variants/initial change at the parent (via Tweaks), reset the stack
  // so we don't strand the user on a route that no longer matches.
  const lastInitial = useRef(initial);
  useEffect(() => {
    if (lastInitial.current !== initial) {
      lastInitial.current = initial;
      router.reset(initial);
    }
  }, [initial, router]);

  const Frame = device === 'ios' ? ProtoIOS : ProtoAndroid;

  // Universal nav handler used by tab bar — top-level routes
  const onTabNav = (id) => {
    // map tab ids to top-level screen names
    const map = { home: 'home', feed: 'feed', alerts: 'alerts', market: 'market', more: 'more' };
    const next = map[id] || id;
    if (router.route.name === next) return;
    router.reset(next);
  };

  // Helpers
  const flash = (m) => setToast(m);

  const Dashboard = pickDashboard(dashboardVariant);
  const Feed = pickFeed(feedVariant);

  // Wrap screens that have hand-rolled Back buttons. We can't easily intercept those
  // chevron buttons from the outside (they are buried in the screens) so we overlay
  // an invisible touch target on top of the back chevron.
  const renderRoute = () => {
    const r = router.route;
    switch (r.name) {
      case 'home':
        return (
          <Dashboard
            onNav={onTabNav}
            onOpenAlert={(a) => router.push('alertDetail', { alert: a })}
            onOpenPost={(p) => router.push('postDetail', { post: p })}
            onOpenEvents={() => router.push('events')}
            onOpenMarket={() => router.push('market')}
            onCompose={() => router.push('compose')}
            onSearch={() => flash('Search opened')}
            onProfile={() => router.push('profile')}
            onNotifs={() => router.push('notifs')}
            onMessages={() => router.push('messages')}
          />
        );

      case 'feed':
        return (
          <Feed
            onNav={onTabNav}
            onPost={() => router.push('compose')}
            onOpenPost={(p) => router.push('postDetail', { post: p })}
            onOpenAlert={(a) => router.push('alertDetail', { alert: a })}
            onProfile={() => router.push('profile')}
          />
        );

      case 'alerts':
        return (
          <ScreenAlerts
            onNav={onTabNav}
            onTap={(a) => router.push(a.official ? 'alertDetail' : 'alertVerify', { alert: a })}
            onReport={() => router.push('alertReport')}
          />
        );

      case 'alertDetail':
        return (
          <ScreenAlertDetail
            onNav={onTabNav}
            onBack={router.back}
            alert={r.props?.alert}
          />
        );

      case 'alertVerify':
        return (
          <ScreenAlertVerify
            onNav={onTabNav}
            onBack={router.back}
            alert={r.props?.alert}
          />
        );

      case 'alertReport':
        return (
          <ScreenAlertReport
            onNav={onTabNav}
            onBack={router.back}
            onPost={() => { router.back(); flash('Alert posted · awaiting confirms'); }}
          />
        );

      case 'postDetail':
        return (
          <ScreenPostDetail
            onNav={onTabNav}
            onBack={router.back}
            post={r.props?.post}
            onReply={() => flash('Reply sent')}
          />
        );

      case 'map':
        return (
          <ScreenMap
            onNav={onTabNav}
            onPin={(p) => flash(`Pin: ${p?.title || 'detail'}`)}
            onOpenAlert={(a) => router.push('alertDetail', { alert: a })}
          />
        );

      case 'profile':
        return (
          <ScreenProfile
            onNav={onTabNav}
            onSettings={() => router.push('onboarding')}
            onOpenPost={(p) => router.push('postDetail', { post: p })}
          />
        );

      case 'compose':
        return (
          <ScreenCompose
            onNav={onTabNav}
            onBack={router.back}
            onPost={() => { router.back(); flash('Posted to your block'); }}
          />
        );

      case 'events':
        return (
          <ScreenEvents
            onNav={onTabNav}
            onBack={router.back}
            onRSVP={() => flash('RSVP saved')}
          />
        );

      case 'market':
        return (
          <ScreenMarket
            onNav={onTabNav}
            onBack={router.back}
            onTap={(item) => router.push('marketDetail', { item })}
          />
        );

      case 'marketDetail': {
        const item = r.props?.item || r.params?.item;
        // Build the seller's thread descriptor + the quoted-item payload from the listing
        const buildThread = () => ({
          id: 'tm',
          kind: 'market',
          name: item?.seller?.name || 'Seller',
          hue: item?.seller?.hue ?? 1,
          last: '',
          online: true,
          role: 'Marketplace · seller',
        });
        const buildQuoted = () => ({
          id: item?.id,
          title: item?.title || 'Item',
          // Try to surface a numeric for offer math + a display-ready price string.
          priceVal: typeof item?.price === 'number' ? item.price : Number(String(item?.price || '').replace(/[^0-9.]/g, '')) || 0,
          price: typeof item?.price === 'string' ? item.price : item?.price ? `$${item.price}` : 'Free',
          image: item?.image || item?.cover,
        });
        return (
          <ScreenMarketDetail
            item={item}
            onNav={onTabNav}
            onBack={router.back}
            onMessage={() => router.push('messageThread', { thread: buildThread(), quotedItem: buildQuoted() })}
            onMakeOffer={() => router.push('messageThread', { thread: buildThread(), quotedItem: buildQuoted(), offerMode: true })}
          />
        );
      }

      case 'notifs':
        return (
          <ScreenNotifs
            onNav={onTabNav}
            onBack={router.back}
            onOpen={() => router.push('postDetail', { post: FEED[3] })}
          />
        );

      case 'messages':
        return (
          <ScreenMessages
            onNav={onTabNav}
            onBack={router.back}
            onOpenThread={(thread) => router.push('messageThread', { thread })}
            onCompose={() => router.push('compose')}
          />
        );

      case 'messageThread':
        return (
          <ScreenMessageThread
            thread={r.props?.thread || r.params?.thread || TP_THREADS[0]}
            quotedItem={r.props?.quotedItem || r.params?.quotedItem || null}
            offerMode={!!(r.props?.offerMode || r.params?.offerMode)}
            onNav={onTabNav}
            onBack={router.back}
          />
        );

      case 'onboarding':
        return (
          <ScreenOnboarding
            onNav={onTabNav}
            onBack={router.back}
            onDone={() => { router.reset('home'); flash('Welcome to TownPost'); }}
          />
        );

      case 'more':
        return (
          <ScreenMore
            onNav={onTabNav}
            onGo={(id) => {
              if (id === 'profile') router.push('profile');
              else if (id === 'map') router.push('map');
              else if (id === 'events') router.push('events');
              else if (id === 'jobs') router.push('jobs');
              else if (id === 'businesses') router.push('businesses');
              else if (id === 'notifs') router.push('notifs');
              else if (id === 'messages') router.push('messages');
              else if (id === 'onboarding') router.push('onboarding');
            }}
          />
        );

      case 'jobs':
        return (
          <ScreenJobs
            onNav={onTabNav}
            onBack={router.back}
            onTap={(j) => flash(`${j.title} · opened`)}
          />
        );

      case 'businesses':
        return (
          <ScreenBusinesses
            onNav={onTabNav}
            onBack={router.back}
            onTap={(b) => router.push('businessDetail', { business: b })}
          />
        );

      case 'businessDetail':
        return (
          <ScreenBusinessDetail
            business={router.route.params?.business}
            onNav={onTabNav}
            onBack={router.back}
            onTap={(action) => flash(typeof action === 'string' ? `${action} · tapped` : 'Tapped')}
          />
        );

      default:
        return <Dashboard onNav={onTabNav} />;
    }
  };

  // Overlay invisible back-button area for screens that have a top-left chevron
  // (alertDetail, postDetail, compose, etc) so router.back() works without us
  // having to thread an onBack prop through every screen's header.
  const HAS_TOP_BACK = new Set(['alertDetail', 'alertVerify', 'alertReport', 'postDetail', 'compose', 'events', 'market', 'marketDetail', 'notifs', 'messages', 'messageThread', 'jobs', 'businesses', 'businessDetail', 'profile', 'onboarding']);
  const showBackOverlay = HAS_TOP_BACK.has(router.route.name);

  return (
    <div style={{ position: 'relative' }}>
      <Frame>
        <TPTabBarContext.Provider value={{
          variant: tabVariant,
          onAction: (id) => {
            if (id === 'compose') router.push('compose');
          },
        }}>
        <div style={{ position: 'relative', width: '100%', height: '100%' }}>
          {renderRoute()}
          {showBackOverlay && (
            <button
              onClick={router.back}
              aria-label="Back"
              style={{
                position: 'absolute', top: 0, left: 0, width: 56, height: 56,
                background: 'transparent', border: 'none', cursor: 'pointer', zIndex: 30,
              }}
            />
          )}
          <Toast msg={toast} onDone={() => setToast(null)} />
          {showBackChip && router.stack.length > 1 && (
            <div style={{
              position: 'absolute', top: 8, right: 8, zIndex: 80,
              fontFamily: TP.mono, fontSize: 9, color: TP.muted,
              background: 'rgba(255,255,255,0.85)', padding: '3px 7px',
              borderRadius: 999, letterSpacing: 0.6,
              border: `1px solid ${TP.hairline}`,
              pointerEvents: 'none',
            }}>
              {router.stack.map(s => s.name).join(' › ')}
            </div>
          )}
        </div>
        </TPTabBarContext.Provider>
      </Frame>
      <style>{`
        @keyframes tpToastIn {
          from { opacity: 0; transform: translate(-50%, 6px); }
          to   { opacity: 1; transform: translate(-50%, 0); }
        }
      `}</style>
    </div>
  );
}

Object.assign(window, { TPInteractive, ProtoIOS, ProtoAndroid });
