// App shell — real mobile-first web app, backed by the Node server in
// server/server.js. Store is in state.jsx; every mutation goes through
// the server and the returned bundle replaces our local state.

function App() {
  return (
    <StoreProvider>
      <AppInner/>
    </StoreProvider>
  );
}

function AppInner() {
  const { state, dispatch, actions } = useStore();
  const { booting, user, huddle, items, comments, tab, activeItemId, authPhase, pendingEmail, devMagicLink, youPhase, busy } = state;

  const scrollRef = React.useRef(null);
  React.useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = 0;
  }, [tab, activeItemId]);

  if (booting) return <Frame><BootingSplash/></Frame>;

  // ── Auth gate ──
  if (!user) {
    if (authPhase === 'signin' || authPhase === 'signup') {
      return (
        <Frame>
          <AuthSignIn
            mode={authPhase}
            busy={busy}
            onSent={(email, remember) => actions.requestMagicLink(email, remember)}
            onToggleMode={() => dispatch({ type: 'authPhase', phase: authPhase === 'signin' ? 'signup' : 'signin' })}
          />
        </Frame>
      );
    }
    return (
      <Frame>
        <AuthLinkSent
          email={pendingEmail}
          devLink={devMagicLink}
          onBack={() => dispatch({ type: 'authPhase', phase: 'signin' })}
          onResend={() => actions.requestMagicLink(pendingEmail, true)}
        />
      </Frame>
    );
  }

  // ── Main app ──
  const myId = user.id;
  const setTab = (t) => dispatch({ type: 'tab', tab: t });
  const openAdd = () => setTab('add');
  const openItem = (id) => dispatch({ type: 'open', id });
  const closeItem = () => dispatch({ type: 'close' });
  const activeItem = activeItemId ? items.find(i => i.id === activeItemId) : null;
  const activeComments = activeItemId ? (comments[activeItemId] || []) : [];

  const membership = huddle ? 'member' : 'none';
  const huddleGuard = !huddle && tab !== 'me';

  return (
    <Frame scroll={false}>
      <div style={{ background: C.cream, height: '100%', position: 'relative', overflow: 'hidden' }}>
        <div ref={scrollRef} style={{
          height: '100%', overflowY: 'auto', overflowX: 'hidden',
          WebkitOverflowScrolling: 'touch',
        }}>
          {huddleGuard && <NotInHuddleScreen onGoToYou={() => setTab('me')}/>}

          {!huddleGuard && !activeItem && tab === 'feed' && (
            <FeedScreen items={items} userId={myId} huddle={huddle} onOpen={openItem} onAdd={openAdd} onToggleDown={actions.toggleDown}/>
          )}
          {!huddleGuard && !activeItem && tab === 'board' && (
            <BoardScreen items={items} userId={myId} huddle={huddle} onOpen={openItem} onAdd={openAdd} onToggleDown={actions.toggleDown}/>
          )}
          {!huddleGuard && !activeItem && tab === 'add' && (
            <AddScreen
              huddle={huddle}
              onClose={() => setTab('feed')}
              onAdd={async (item) => { await actions.addItem(item); setTab('feed'); }}
              extractLink={actions.extractLink}
              extractImage={actions.extractImage}
            />
          )}
          {!huddleGuard && !activeItem && tab === 'cal' && (
            <CalendarScreen items={items} huddle={huddle} onAdd={openAdd} onOpen={openItem}/>
          )}
          {!activeItem && tab === 'me' && (
            <YouTabRouter
              state={state}
              dispatch={dispatch}
              actions={actions}
              membership={membership}
            />
          )}

          {activeItem && (
            <ItemCardScreen
              item={activeItem}
              userId={myId}
              huddle={huddle}
              comments={activeComments}
              onClose={closeItem}
              onToggleDown={actions.toggleDown}
              onComment={(text) => actions.addComment(activeItemId, text)}
            />
          )}
        </div>

        {tab !== 'add' && !activeItem && (
          <TabBar active={tab} onTab={(id) => id === 'add' ? openAdd() : setTab(id)}/>
        )}
      </div>
    </Frame>
  );
}

function YouTabRouter({ state, dispatch, actions, membership }) {
  const { huddle, user, youPhase } = state;
  const setPhase = (p) => dispatch({ type: 'youPhase', phase: p });

  if (membership === 'member' && youPhase !== 'join' && youPhase !== 'create') {
    return (
      <YouScreen
        inHuddle={true}
        huddle={huddle}
        email={user?.email || ''}
        onSignOut={actions.signOut}
        onJoin={() => setPhase('join')}
        onCreate={() => setPhase('create')}
      />
    );
  }
  if (youPhase === 'join') {
    return (
      <JoinHuddleScreen
        onBack={() => setPhase('member')}
        onJoined={async (code) => { try { await actions.joinHuddle(code); setPhase('member'); } catch (e) { alert(e.message); } }}
      />
    );
  }
  if (youPhase === 'create') {
    return (
      <CreateHuddleScreen
        onBack={() => setPhase('member')}
        onCreated={async (name, emoji) => { try { await actions.createHuddle(name, emoji); setPhase('member'); } catch (e) { alert(e.message); } }}
      />
    );
  }
  return (
    <YouScreen
      inHuddle={false}
      huddle={null}
      email={user?.email || ''}
      onSignOut={actions.signOut}
      onJoin={() => setPhase('join')}
      onCreate={() => setPhase('create')}
    />
  );
}

// Responsive shell — full-width on mobile, phone-sized column on desktop.
function Frame({ children, scroll = true }) {
  return (
    <div className="huddle-frame">
      <div style={{
        background: C.cream,
        height: '100%',
        overflow: scroll ? 'auto' : 'hidden',
        WebkitOverflowScrolling: 'touch',
        position: 'relative',
      }}>
        {children}
      </div>
    </div>
  );
}

function BootingSplash() {
  return (
    <div style={{
      background: C.cream, height: '100%',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      <div style={{ textAlign: 'center' }}>
        <div style={{
          width: 22, height: 22, borderRadius: '50%',
          border: `2.5px solid ${C.coralSoft}`,
          borderTopColor: C.coral,
          animation: 'spin 700ms linear infinite',
          margin: '0 auto 16px',
        }}/>
        <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
        <div style={{
          fontFamily: '"Instrument Serif",serif', fontStyle: 'italic',
          fontSize: 28, color: C.navy, letterSpacing: -0.4,
        }}>Shephrd</div>
      </div>
    </div>
  );
}

function NotInHuddleScreen({ onGoToYou }) {
  return (
    <Screen>
      <div style={{
        padding: 'calc(env(safe-area-inset-top, 12px) + 60px) 28px 28px',
        textAlign: 'center',
      }}>
        <div style={{
          width: 72, height: 72, borderRadius: 22,
          background: C.coralSoft, margin: '0 auto 18px',
          display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 32,
        }}>🌴</div>
        <h1 style={{
          margin: 0, fontFamily: '"Instrument Serif",serif', fontStyle: 'italic',
          fontSize: 34, color: C.navy, letterSpacing: -0.6, fontWeight: 400, lineHeight: 1.1,
        }}>you're not in a flock yet</h1>
        <p style={{
          fontFamily: '"DM Sans",system-ui', fontSize: 14.5, color: C.inkMuted,
          marginTop: 10, lineHeight: 1.5,
        }}>
          Join one with a code from a friend, or start a new flock. The Feed comes alive once you're in.
        </p>
        <button onClick={onGoToYou} style={{
          marginTop: 22, height: 50, padding: '0 24px',
          borderRadius: 999, border: 'none',
          background: `linear-gradient(180deg, ${C.coral}, ${C.coralDeep})`,
          color: '#fff', fontFamily: '"DM Sans",system-ui',
          fontWeight: 700, fontSize: 15, cursor: 'pointer',
          boxShadow: '0 6px 18px rgba(255,107,91,0.4)',
        }}>Join or create a flock</button>
      </div>
    </Screen>
  );
}

function CalendarScreen({ items, huddle, onAdd, onOpen }) {
  const [tab, setTab] = React.useState('upcoming');
  const events = items.filter(i => i.type === 'event' && i.date);
  const now = new Date();
  const isPast = (e) => {
    const d = labelToDate(e.endDate || e.date, now.getFullYear());
    if (!d) return false;
    // Event is past once the (end) day is strictly before today
    return d.getTime() < new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
  };
  const upcoming = events.filter(e => !isPast(e)).sort((a, b) => {
    const ad = labelToDate(a.date, now.getFullYear())?.getTime() || 0;
    const bd = labelToDate(b.date, now.getFullYear())?.getTime() || 0;
    return ad - bd;
  });
  const past = events.filter(isPast).sort((a, b) => {
    const ad = labelToDate(a.endDate || a.date, now.getFullYear())?.getTime() || 0;
    const bd = labelToDate(b.endDate || b.date, now.getFullYear())?.getTime() || 0;
    return bd - ad;
  });
  const active = tab === 'upcoming' ? upcoming : past;

  return (
    <Screen>
      <GroupBar group={huddle} members={huddle.members}/>
      <HuddleHeader title="Calendar" subtitle="dates on the books" onAdd={onAdd}/>
      <div style={{ padding: '0 16px 10px' }}>
        <div style={{
          background: 'rgba(30,42,74,0.06)', borderRadius: 999,
          padding: 4, display: 'flex', gap: 2,
        }}>
          {[
            { id: 'upcoming', label: `Upcoming${upcoming.length ? ` · ${upcoming.length}` : ''}` },
            { id: 'did',      label: `Did${past.length ? ` · ${past.length}` : ''}` },
          ].map(t => (
            <button key={t.id} onClick={() => setTab(t.id)} style={{
              flex: 1, padding: '8px 0', border: 'none', cursor: 'pointer',
              background: tab === t.id ? C.white : 'transparent',
              borderRadius: 999,
              fontFamily: '"DM Sans",system-ui',
              fontSize: 12.5, fontWeight: tab === t.id ? 700 : 500,
              color: tab === t.id ? C.navy : C.inkMuted,
              boxShadow: tab === t.id ? '0 1px 3px rgba(30,42,74,0.08)' : 'none',
            }}>{t.label}</button>
          ))}
        </div>
      </div>
      <div style={{ padding: '0 16px' }}>
        {active.length === 0 ? (
          <div style={{
            background: C.white, borderRadius: 18, padding: 22,
            textAlign: 'center',
            boxShadow: '0 1px 3px rgba(30,42,74,0.04)',
          }}>
            <div style={{
              fontFamily: '"Instrument Serif",serif', fontStyle: 'italic',
              fontSize: 22, color: C.navy, letterSpacing: -0.3,
            }}>{tab === 'upcoming' ? 'No upcoming events' : 'Nothing in the archive yet'}</div>
            <div style={{
              fontFamily: '"DM Sans",system-ui', fontSize: 13.5, color: C.inkMuted,
              marginTop: 6, lineHeight: 1.4,
            }}>{tab === 'upcoming'
                ? 'Add a specific date when you post and it shows up here.'
                : 'Past events land here — rate them to build a group memory.'}</div>
          </div>
        ) : active.map(e => {
          const cat = catById(e.category);
          const multiDay = !!e.endDate;
          const dayLbl = (s) => s?.split(' ').pop() || '';
          return (
            <div key={e.id} onClick={() => onOpen(e.id)} style={{
              display: 'flex', gap: 12, alignItems: 'center',
              background: C.white, borderRadius: 18, padding: 12,
              marginBottom: 10,
              boxShadow: '0 1px 3px rgba(30,42,74,0.04)',
              cursor: 'pointer',
              position: 'relative', overflow: 'hidden',
            }}>
              {multiDay && (
                <div style={{
                  position: 'absolute', top: 0, left: 0, height: 4,
                  width: '100%', background: `linear-gradient(90deg, ${C.coral}, ${C.coralSoft})`,
                }}/>
              )}
              <div style={{
                minWidth: 64, textAlign: 'center', background: C.coralSoft,
                borderRadius: 12, padding: '8px 10px',
              }}>
                <div style={{ fontFamily: '"DM Sans",system-ui', fontSize: 10, fontWeight: 700, color: C.coralDeep, letterSpacing: 0.6 }}>
                  {e.date?.split(',')[0].toUpperCase()}
                </div>
                <div style={{ fontFamily: '"Instrument Serif",serif', fontStyle: 'italic', fontSize: 22, lineHeight: 1, color: C.navy }}>
                  {multiDay ? `${dayLbl(e.date)}–${dayLbl(e.endDate)}` : dayLbl(e.date)}
                </div>
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontFamily: '"DM Sans",system-ui', fontWeight: 600, fontSize: 14, color: C.navy, letterSpacing: -0.1 }}>
                  {e.title}
                </div>
                <div style={{ fontFamily: '"DM Sans",system-ui', fontSize: 12, color: C.inkMuted, marginTop: 3 }}>
                  {multiDay
                    ? (dateRangeLabel ? dateRangeLabel(e.date, e.endDate) : `${e.date} → ${e.endDate}`)
                    : (e.time ? `${e.time}${e.location ? ' · ' + e.location : ''}` : (e.location || ''))}
                </div>
                <div style={{ marginTop: 6 }}>
                  <AvatarStack users={e.downs.map(id => huddle.members.find(m => m.id === id)).filter(Boolean)} size={18} max={4}/>
                </div>
              </div>
              <div style={{ fontSize: 18 }}>{cat?.emoji}</div>
            </div>
          );
        })}
      </div>
    </Screen>
  );
}

Object.assign(window, { App, Frame, CalendarScreen, NotInHuddleScreen, BootingSplash });
