// App — routing, floating glass tab bar, pull-to-capture gesture.
// On real mobile (iPhone), renders full-screen without the IOSDevice phone frame.

const _isMobile = window.innerWidth <= 430 || /iPhone|iPad|Android/i.test(navigator.userAgent);

function App() {
  const [tab, setTab] = React.useState('today');
  const [subView, setSubView] = React.useState(null);
  const [captureOpen, setCaptureOpen] = React.useState(false);
  const [pullY, setPullY] = React.useState(0);
  const scrollerRef = React.useRef(null);

  // ── persistence
  React.useEffect(() => {
    try {
      const s = JSON.parse(localStorage.getItem('lifeos:state') || '{}');
      if (s.tab) setTab(s.tab);
      if (s.subView !== undefined) setSubView(s.subView);
    } catch {}
  }, []);
  React.useEffect(() => {
    localStorage.setItem('lifeos:state', JSON.stringify({ tab, subView }));
  }, [tab, subView]);

  const go = (target, arg) => {
    if (target === 'person') {
      setTab('radar');
      setSubView(`person:${arg}`);
    } else {
      setTab(target);
      setSubView(null);
    }
    if (scrollerRef.current) scrollerRef.current.scrollTop = 0;
  };

  // ── pull-to-capture (only on Today screen, only when at scroll top)
  const pullState = React.useRef({ startY: 0, active: false });
  const onTouchStart = (e) => {
    if (tab !== 'today' || captureOpen) return;
    if (scrollerRef.current && scrollerRef.current.scrollTop > 1) return;
    pullState.current = { startY: e.touches[0].clientY, active: true };
  };
  const onTouchMove = (e) => {
    if (!pullState.current.active) return;
    const dy = e.touches[0].clientY - pullState.current.startY;
    if (dy < 0) { setPullY(0); return; }
    setPullY(Math.min(dy / 180, 1));
  };
  const onTouchEnd = () => {
    if (!pullState.current.active) return;
    pullState.current.active = false;
    if (pullY > 0.6) { setCaptureOpen(true); }
    setPullY(0);
  };
  // pointer events (mouse drag for desktop/simulator)
  const pState = React.useRef({ y: 0, active: false });
  const onPointerDown = (e) => {
    if (tab !== 'today' || captureOpen) return;
    if (scrollerRef.current && scrollerRef.current.scrollTop > 1) return;
    if (e.pointerType === 'touch') return;
    pState.current = { y: e.clientY, active: true };
  };
  const onPointerMove = (e) => {
    if (!pState.current.active) return;
    const dy = e.clientY - pState.current.y;
    if (dy < 0) { setPullY(0); return; }
    setPullY(Math.min(dy / 180, 1));
  };
  const onPointerUp = () => {
    if (!pState.current.active) return;
    pState.current.active = false;
    if (pullY > 0.6) setCaptureOpen(true);
    setPullY(0);
  };

  // ── render active screen
  let screen;
  if (tab === 'today') screen = <TodayScreen go={go} pullProgress={pullY} openCapture={() => setCaptureOpen(true)} />;
  else if (tab === 'chat') screen = <ChatScreen go={go} />;
  else if (tab === 'radar' && subView && subView.startsWith('person:')) {
    screen = <PersonScreen id={subView.split(':')[1]} go={go} />;
  }
  else if (tab === 'radar') screen = <RadarScreen go={go} />;
  else if (tab === 'body') screen = <BodyScreen go={go} />;
  else if (tab === 'inbox') screen = <InboxScreen go={go} />;
  else if (tab === 'people') screen = <PeopleScreen go={go} />;

  const pendingCount = (LifeData.approvals || []).length;

  // ── pull-to-capture indicator (same in both mobile/desktop modes)
  const pullIndicator = tab === 'today' && pullY > 0 && (
    <div style={{
      position: 'absolute', top: _isMobile ? 74 : 54, left: 0, right: 0, height: pullY * 90,
      display: 'flex', alignItems: 'flex-end', justifyContent: 'center',
      zIndex: 5, pointerEvents: 'none',
    }}>
      <div style={{
        opacity: Math.min(pullY * 1.6, 1),
        transform: `scale(${0.7 + pullY * 0.4})`,
        background: pullY > 0.6 ? T.blue : 'rgba(255,255,255,0.9)',
        color: pullY > 0.6 ? '#fff' : T.label2,
        padding: '8px 16px', borderRadius: 999,
        fontSize: 13, fontWeight: 600,
        display: 'flex', alignItems: 'center', gap: 6,
        boxShadow: '0 4px 12px rgba(0,0,0,0.12)',
        backdropFilter: 'blur(20px) saturate(180%)',
        WebkitBackdropFilter: 'blur(20px) saturate(180%)',
        border: pullY > 0.6 ? 'none' : '0.5px solid rgba(0,0,0,0.06)',
      }}>
        <IconPlus size={14} color={pullY > 0.6 ? '#fff' : T.label2} />
        {pullY > 0.6 ? 'Release to capture' : 'Pull to capture'}
      </div>
    </div>
  );

  const scrollerDiv = (
    <div
      ref={scrollerRef}
      onTouchStart={onTouchStart} onTouchMove={onTouchMove} onTouchEnd={onTouchEnd}
      onPointerDown={onPointerDown} onPointerMove={onPointerMove} onPointerUp={onPointerUp} onPointerCancel={onPointerUp}
      style={{
        height: '100%', overflowY: 'auto', overflowX: 'hidden',
        background: T.bg,
        transform: `translateY(${pullY * 40}px)`,
        transition: pullY === 0 ? 'transform 0.25s cubic-bezier(.2,.8,.2,1)' : 'none',
        WebkitOverflowScrolling: 'touch',
      }}
    >
      {screen}
    </div>
  );

  const fabButton = tab === 'today' && (
    <div style={{ position: 'absolute', top: _isMobile ? 74 : 64, right: 16, zIndex: 6 }}>
      <button onClick={() => setCaptureOpen(true)} style={{
        width: 36, height: 36, borderRadius: 999, border: 'none', cursor: 'pointer',
        background: 'rgba(255,255,255,0.8)',
        backdropFilter: 'blur(20px)',
        WebkitBackdropFilter: 'blur(20px)',
        boxShadow: '0 1px 3px rgba(0,0,0,0.08)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <IconPlus size={18} color={T.label} />
      </button>
    </div>
  );

  if (_isMobile) {
    // Full-screen mobile layout — no phone frame, respects safe area via CSS
    return (
      <div className="lifeos-root" style={{
        width: '100vw', height: '100dvh', overflow: 'hidden',
        position: 'relative', background: T.bg,
        fontFamily: '-apple-system, system-ui, sans-serif',
        WebkitFontSmoothing: 'antialiased',
      }}>
        {pullIndicator}
        {scrollerDiv}
        <TabBar tab={tab} setTab={go} pendingCount={pendingCount} />
        <CaptureSheet visible={captureOpen} onClose={() => setCaptureOpen(false)} />
        {fabButton}
      </div>
    );
  }

  // Desktop — wrapped in the iOS device frame for the phone-in-browser look
  return (
    <IOSDevice width={402} height={874}>
      {pullIndicator}
      {scrollerDiv}
      <TabBar tab={tab} setTab={go} pendingCount={pendingCount} />
      <CaptureSheet visible={captureOpen} onClose={() => setCaptureOpen(false)} />
      {fabButton}
    </IOSDevice>
  );
}

function TabBar({ tab, setTab, pendingCount }) {
  const tabs = [
    { id: 'today',  label: 'Today',  Icon: IconHouse },
    { id: 'chat',   label: 'Chat',   Icon: IconChat },
    { id: 'radar',  label: 'Radar',  Icon: IconRadar },
    { id: 'people', label: 'People', Icon: IconPeople },
    { id: 'inbox',  label: 'Inbox',  Icon: IconInbox, badge: pendingCount },
  ];
  return (
    <div style={{
      position: 'absolute', bottom: 16, left: 12, right: 12, zIndex: 30,
      height: 60, borderRadius: 999,
      background: 'rgba(255,255,255,0.78)',
      backdropFilter: 'blur(24px) saturate(180%)',
      WebkitBackdropFilter: 'blur(24px) saturate(180%)',
      border: '0.5px solid rgba(0,0,0,0.06)',
      boxShadow: '0 6px 24px rgba(0,0,0,0.10), 0 1px 3px rgba(0,0,0,0.04)',
      display: 'flex', alignItems: 'center', padding: '0 4px',
    }}>
      {tabs.map(t => {
        const active = tab === t.id;
        return (
          <button key={t.id} onClick={() => setTab(t.id)} style={{
            flex: 1, height: 52, border: 'none', background: 'transparent', cursor: 'pointer',
            display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
            gap: 2, position: 'relative',
          }}>
            <div style={{ position: 'relative' }}>
              <t.Icon size={22} color={active ? T.blue : T.label2} sw={active ? 2 : 1.8} />
              {t.badge ? (
                <span style={{
                  position: 'absolute', top: -3, right: -8,
                  minWidth: 16, height: 16, borderRadius: 999,
                  background: T.red, color: '#fff',
                  fontSize: 10, fontWeight: 700, padding: '0 4px',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  border: '1.5px solid rgba(255,255,255,0.95)',
                  boxSizing: 'border-box',
                }}>{t.badge}</span>
              ) : null}
            </div>
            <span style={{
              fontSize: 10, fontWeight: 600,
              color: active ? T.blue : T.label2,
              letterSpacing: 0.1,
            }}>{t.label}</span>
          </button>
        );
      })}
    </div>
  );
}

// ── Entry point: wait for data, then render ──────────────────────────────────
window.LifeDataReady.then(function() {
  if (!window.LifeData) {
    document.getElementById('root').innerHTML =
      '<div style="height:100vh;display:flex;align-items:center;justify-content:center;font-family:-apple-system;text-align:center;padding:20px">' +
      '<div><div style="font-size:32px;margin-bottom:12px">⚠️</div>' +
      '<div style="font-size:17px;font-weight:600">Could not connect to Life OS</div>' +
      '<div style="font-size:14px;color:rgba(60,60,67,0.6);margin-top:8px">Make sure the backend is running on port 8443</div></div></div>';
    return;
  }
  const root = ReactDOM.createRoot(document.getElementById('root'));
  root.render(<App />);
});
