// HomeHub — shell that wires navigation, screens, tweaks persistence

// Time-ago helper for notifications
function timeAgo(dateStr) {
  if (!dateStr) return '';
  const now = Date.now();
  const normalized = dateStr.includes('T') ? dateStr : dateStr.replace(' ', 'T');
  const then = new Date(normalized + (normalized.endsWith('Z') ? '' : 'Z')).getTime();
  if (isNaN(then)) return '';
  const diff = Math.floor((now - then) / 1000);
  if (diff < 60) return 'just now';
  if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
  if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;
  return `${Math.floor(diff / 86400)}d ago`;
}

// Notification icon map
const NOTIF_ICONS = { geofence: 'pin', battery: 'bolt', todo: 'check', waste: 'trash', warning: 'sparkle', bell: 'bell', calendar: 'calendar', shopping: 'cart' };

function App({ user, onLogout }) {
  // Tweak defaults (persisted via edit-mode host)
  const TWEAKS = /*EDITMODE-BEGIN*/{
    "theme": "light",
    "accent": "terracotta",
    "density": "comfy",
    "iconVariant": "duotone",
    "layout": "cozy"
  }/*EDITMODE-END*/;

  const [cfg, setCfg] = React.useState(TWEAKS);
  const [showTweaks, setShowTweaks] = React.useState(false);
  const [notifOpen, setNotifOpen] = React.useState(false);
  const notifPanelRef = React.useRef(null);
  const store = useStore();

  // Persisted tab + route
  const [tab, setTab] = React.useState(() => localStorage.getItem('hh_tab') || 'home');
  const [route, setRoute] = React.useState(() => localStorage.getItem('hh_route') || null);
  const [selectedDeviceId, setSelectedDeviceId] = React.useState(null);

  React.useEffect(() => { localStorage.setItem('hh_tab', tab); }, [tab]);
  React.useEffect(() => { localStorage.setItem('hh_route', route || ''); }, [route]);

  React.useEffect(() => {
    const updateViewportHeight = () => {
      const nextHeight = window.visualViewport?.height || window.innerHeight;
      document.documentElement.style.setProperty('--hh-app-height', `${Math.round(nextHeight)}px`);
    };

    updateViewportHeight();
    window.addEventListener('resize', updateViewportHeight);
    window.visualViewport?.addEventListener('resize', updateViewportHeight);
    window.visualViewport?.addEventListener('scroll', updateViewportHeight);
    return () => {
      window.removeEventListener('resize', updateViewportHeight);
      window.visualViewport?.removeEventListener('resize', updateViewportHeight);
      window.visualViewport?.removeEventListener('scroll', updateViewportHeight);
    };
  }, []);

  // Close notification panel on outside click
  React.useEffect(() => {
    if (!notifOpen) return;
    const handler = (e) => {
      if (notifPanelRef.current && !notifPanelRef.current.contains(e.target)) setNotifOpen(false);
    };
    document.addEventListener('mousedown', handler);
    document.addEventListener('touchstart', handler);
    return () => { document.removeEventListener('mousedown', handler); document.removeEventListener('touchstart', handler); };
  }, [notifOpen]);

  // Edit mode protocol
  React.useEffect(() => {
    const onMsg = (e) => {
      const d = e.data;
      if (!d) return;
      if (d.type === '__activate_edit_mode') setShowTweaks(true);
      if (d.type === '__deactivate_edit_mode') setShowTweaks(false);
    };
    window.addEventListener('message', onMsg);
    window.parent.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', onMsg);
  }, []);

  const updateCfg = (patch) => {
    setCfg(c => ({ ...c, ...patch }));
    window.parent.postMessage({ type: '__edit_mode_set_keys', edits: patch }, '*');
  };

  // Accent application
  const ACCENTS = {
    terracotta: { a: '#C9562E', s: '#F0C9B8', t: '#FBEADF' },
    sage:       { a: '#6E8662', s: '#CBDABB', t: '#EAF0E4' },
    mustard:    { a: '#C99A2E', s: '#F0DCA8', t: '#FBF1D9' },
    plum:       { a: '#7A4F6B', s: '#DCC7D5', t: '#F2E7ED' },
    sky:        { a: '#5F7E91', s: '#C5D5DE', t: '#E7EEF2' },
    clay:       { a: '#B26749', s: '#E5C2B0', t: '#F7EBE3' },
  };
  const themeStyle = React.useMemo(() => {
    const acc = ACCENTS[cfg.accent] || ACCENTS.terracotta;
    return { '--hh-accent': acc.a, '--hh-accent-soft': acc.s, '--hh-accent-tint': acc.t };
  }, [cfg.accent]);

  // Sync iOS status bar theme-color with the current theme
  React.useEffect(() => {
    const color = cfg.theme === 'dark' ? '#1B1612' : '#F5EDE3';
    let light = document.querySelector('meta[name="theme-color"][media*="light"]');
    let dark = document.querySelector('meta[name="theme-color"][media*="dark"]');
    if (light) light.content = color;
    if (dark) dark.content = cfg.theme === 'dark' ? '#1B1612' : '#F5EDE3';
    // Also update the no-media fallback if any
    let plain = document.querySelector('meta[name="theme-color"]:not([media])');
    if (plain) plain.content = color;
  }, [cfg.theme]);

  // Detect iOS standalone (added to home screen)
  const isIosStandalone = typeof window !== 'undefined' &&
    ((window.navigator.standalone === true) ||
     window.matchMedia('(display-mode: standalone)').matches);

  // Enable :active on iOS (needs a touchstart listener)
  React.useEffect(() => {
    document.addEventListener('touchstart', function(){}, {passive: true});
  }, []);

  const nav = (to) => {
    if (['home', 'map', 'lists', 'calendar', 'settings'].includes(to)) {
      setTab(to); setRoute(null);
    } else setRoute(to);
  };

  const currentUser = user || { name: 'Guest', avatar: '👤' };

  const selectedDevice = React.useMemo(() => {
    if (!selectedDeviceId) return null;
    return store.devices.find(d => String(d.id) === String(selectedDeviceId)) || null;
  }, [store.devices, selectedDeviceId]);

  const openDevice = (d) => setSelectedDeviceId(d?.id || null);

  const screen = () => {
    if (route === 'rules') return <RulesScreen store={store} cfg={cfg} user={currentUser} onBack={() => setRoute(null)}/>;
    if (route === 'scenes') return <ScenesScreen store={store} cfg={cfg} onBack={() => setRoute(null)}/>;
    if (route === 'activity') return <ActivityScreen store={store} cfg={cfg} onBack={() => setRoute(null)}/>;
    if (route === 'cameras') return <CamerasScreen store={store} cfg={cfg} onBack={() => setRoute(null)}/>;
    if (route === 'devices') return <DevicesScreen store={store} cfg={cfg} onBack={() => setRoute(null)} onOpenDevice={openDevice}/>;
    if (route === 'family') return <FamilyScreen store={store} cfg={cfg} onBack={() => setRoute(null)}/>;
    if (route === 'waste') return <WasteScreen store={store} cfg={cfg} onBack={() => setRoute(null)}/>;
    if (route === 'privacy') return <PrivacyScreen store={store} cfg={cfg} onBack={() => setRoute(null)}/>;
    if (route === 'locHistory') return <LocationHistoryScreen store={store} cfg={cfg} onBack={() => setRoute(null)}/>;
    if (route === 'hubs') return <HubsScreen store={store} cfg={cfg} onBack={() => setRoute(null)}/>;
    if (route === 'energy') return <EnergyScreen store={store} cfg={cfg} onBack={() => setRoute(null)}/>;
    if (route === 'appSettings') return <AppSettingsScreen store={store} cfg={cfg} onBack={() => setRoute(null)} updateCfg={updateCfg}/>;
    const isMapActive = tab === 'map' && !route;
    return (
      <>
        {/* MapScreen is always mounted (keep-alive) so Mapbox initialises once.
            CSS display:none hides it; the map instance stays alive and markers persist. */}
        <div style={{
          display: isMapActive ? 'flex' : 'none',
          flexDirection: 'column', flex: 1, minHeight: 0, height: '100%',
        }}>
          <MapScreen store={store} cfg={cfg} onNav={nav} active={isMapActive}/>
        </div>
        {/* Other tab screens — only render the active one */}
        {!isMapActive && (() => {
          switch (tab) {
            case 'home': return <DashboardHome store={store} cfg={cfg} onNav={nav} onOpenDevice={openDevice} user={currentUser} onLogout={onLogout}/>;
            case 'lists': return <ListsScreen store={store} cfg={cfg} user={currentUser}/>;
            case 'calendar': return <CalendarScreen store={store} cfg={cfg}/>;
            case 'settings': return <SettingsScreen store={store} cfg={cfg} onNav={nav} user={currentUser} onLogout={onLogout}/>;
            default: return null;
          }
        })()}
      </>
    );
  };

  const Phone = ({ kind, children }) => {
    if (kind === 'ios') {
      return (
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14 }}>
          <div style={{ fontFamily: 'var(--hh-font)', fontSize: 15, color: '#6B5C4A', letterSpacing: '0.02em' }}>iPhone · iOS</div>
          <IOSDevice width={390} height={844} dark={cfg.theme === 'dark'}>
            <div data-screen-label="ios-app" className="hh-screen" data-theme={cfg.theme} data-density={cfg.density} style={{ ...themeStyle, paddingTop: 54 }}>
              {children}
            </div>
          </IOSDevice>
        </div>
      );
    }
    return (
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14 }}>
        <div style={{ fontFamily: 'var(--hh-font)', fontSize: 15, color: '#6B5C4A', letterSpacing: '0.02em' }}>Pixel · Android</div>
        <AndroidDevice width={390} height={844} dark={cfg.theme === 'dark'}>
          <div data-screen-label="android-app" className="hh-screen" data-theme={cfg.theme} data-density={cfg.density} style={{ ...themeStyle }}>
            {children}
          </div>
        </AndroidDevice>
      </div>
    );
  };

  // ── Command Palette (Cmd+K / Ctrl+K) ──
  const [cmdOpen, setCmdOpen] = React.useState(false);
  const [cmdQuery, setCmdQuery] = React.useState('');
  const [cmdIdx, setCmdIdx] = React.useState(0);
  const cmdInputRef = React.useRef(null);

  React.useEffect(() => {
    const handler = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
        e.preventDefault();
        setCmdOpen(o => !o);
        setCmdQuery('');
        setCmdIdx(0);
      }
      if (e.key === 'Escape' && cmdOpen) setCmdOpen(false);
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [cmdOpen]);

  React.useEffect(() => {
    if (cmdOpen && cmdInputRef.current) cmdInputRef.current.focus();
  }, [cmdOpen]);

  const cmdItems = React.useMemo(() => {
    const items = [];
    // Navigation tabs
    [['home','Home','🏠'],['map','Map','🗺'],['lists','Board','📝'],['calendar','Calendar','📅'],['settings','More','⚙️'],
     ['rules','Smart Rules','✨'],['scenes','Scenes','🎬'],['cameras','Cameras','📷'],['activity','Activity','⚡'],
     ['devices','Devices','🔌'],['family','Family','👨‍👩‍👧‍👦'],['waste','Waste','🗑'],['privacy','Privacy & Data','🔒'],
     ['locHistory','Location History','📍'],['hubs','Hubs & Bridges','📡'],['energy','Energy','⚡'],['appSettings','App Settings','🎨']].forEach(([id,l,emoji]) => {
      items.push({ type: 'nav', id, label: l, emoji, action: () => { nav(id); setCmdOpen(false); } });
    });
    // Devices
    store.devices.forEach(d => {
      items.push({ type: 'device', id: `d_${d.id}`, label: d.name, emoji: d.on ? '💡' : '⚫', sub: `${d.room} · ${d.on ? 'On' : 'Off'}`, action: () => { store.toggleDevice(d.id).catch(() => {}); setCmdOpen(false); } });
    });
    // Scenes
    store.scenes.forEach(s => {
      items.push({ type: 'scene', id: `s_${s.id}`, label: s.name, emoji: s.emoji, sub: `${s.devices} devices`, action: () => { store.activateScene(s.id); setCmdOpen(false); } });
    });
    return items;
  }, [store.devices, store.scenes, cmdOpen]);

  const filteredCmd = cmdQuery.trim()
    ? cmdItems.filter(i => i.label.toLowerCase().includes(cmdQuery.toLowerCase()) || (i.sub || '').toLowerCase().includes(cmdQuery.toLowerCase()))
    : cmdItems.slice(0, 12);

  const handleCmdKey = (e) => {
    if (e.key === 'ArrowDown') { e.preventDefault(); setCmdIdx(i => Math.min(i + 1, filteredCmd.length - 1)); }
    if (e.key === 'ArrowUp') { e.preventDefault(); setCmdIdx(i => Math.max(i - 1, 0)); }
    if (e.key === 'Enter' && filteredCmd[cmdIdx]) { filteredCmd[cmdIdx].action(); }
  };

  const content = (
    <>
      {store.loading ? (
        <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--hh-bg)' }}>
          <div style={{ textAlign: 'center' }}>
            <div className="hh-serif" style={{ fontSize: 24, color: 'var(--hh-accent)', marginBottom: 8 }}>HomeHub</div>
            <div style={{ fontSize: 12, color: 'var(--hh-ink-mute)' }}>Loading…</div>
          </div>
        </div>
      ) : screen()}
      {/* Tab bar hidden on deep routes or while loading */}
      {!route && !store.loading && <TabBar active={tab} onChange={setTab} iconVariant={cfg.iconVariant} notifCount={store.notifications.filter(n => !n.read).length} onNotifClick={() => setNotifOpen(o => !o)}/>}
      <DeviceDetailSheet device={selectedDevice} open={!!selectedDevice} onClose={() => setSelectedDeviceId(null)} store={store} cfg={cfg}/>

      {/* ── Notification Panel (anchored to bottom-right, above tab bar) ── */}
      {!store.loading && notifOpen && (
        <div ref={notifPanelRef} style={{ position: 'fixed', bottom: 'calc(var(--hh-tabbar-h) + env(safe-area-inset-bottom) + 22px)', right: 12, zIndex: 12020 }}>
            <div style={{
              width: 'min(320px, calc(100vw - 24px))', maxHeight: 'min(480px, calc(100dvh - var(--hh-tabbar-h) - env(safe-area-inset-bottom) - 140px))',
              background: 'var(--hh-surface)',
              borderRadius: 18, boxShadow: 'var(--hh-shadow-lg)',
              border: '1px solid var(--hh-line-soft)',
              overflow: 'hidden', display: 'flex', flexDirection: 'column',
            }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 14px 8px' }}>
                <span className="hh-serif" style={{ fontSize: 15 }}>Notifications</span>
                <div style={{ display: 'flex', gap: 8 }}>
                  {store.notifications.filter(n => !n.read).length > 0 && (
                    <button onClick={() => store.markAllNotifsRead()} className="press" style={{ fontSize: 11, color: 'var(--hh-accent)' }}>Mark all read</button>
                  )}
                  <button onClick={() => setNotifOpen(false)} className="press" style={{ fontSize: 11, color: 'var(--hh-ink-mute)' }}>Close</button>
                </div>
              </div>
              <div style={{ flex: 1, overflowY: 'auto', padding: '0 6px 8px' }}>
                {store.notifications.length === 0 && (
                  <div style={{ padding: '20px 14px', textAlign: 'center', fontSize: 13, color: 'var(--hh-ink-mute)' }}>No notifications</div>
                )}
                {store.notifications.slice(0, 30).map(n => {
                  const iconName = NOTIF_ICONS[n.icon] || NOTIF_ICONS[n.type] || 'bell';
                  return (
                    <div
                      key={n.id}
                      onClick={() => !n.read && store.markNotifRead(n.id)}
                      style={{
                        display: 'flex', gap: 10, alignItems: 'flex-start',
                        padding: '8px 10px', borderRadius: 12, marginBottom: 2,
                        background: n.read ? 'transparent' : 'var(--hh-accent-tint)',
                        cursor: n.read ? 'default' : 'pointer',
                      }}
                    >
                      <div style={{
                        width: 28, height: 28, borderRadius: 999,
                        background: n.type === 'geofence' ? '#C9562E22' : n.type === 'warning' ? '#d4440022' : 'var(--hh-surface-2)',
                        display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, marginTop: 2,
                      }}>
                        <Icon name={iconName} size={13} color={n.type === 'geofence' ? '#C9562E' : n.type === 'warning' ? '#d44' : 'var(--hh-ink-mute)'}/>
                      </div>
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontSize: 12, fontWeight: n.read ? 400 : 600, lineHeight: 1.3 }}>{n.title}</div>
                        {n.message && <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 1, lineHeight: 1.3 }}>{n.message}</div>}
                        <div style={{ fontSize: 10, color: 'var(--hh-ink-mute)', marginTop: 3 }} className="hh-mono">{timeAgo(n.created_at)}</div>
                      </div>
                      <button
                        onClick={(e) => { e.stopPropagation(); store.deleteNotif(n.id); }}
                        className="press"
                        style={{ width: 22, height: 22, borderRadius: 999, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, marginTop: 2 }}
                      >
                        <Icon name="close" size={10} color="var(--hh-ink-mute)"/>
                      </button>
                    </div>
                  );
                })}
              </div>
            </div>
        </div>
      )}

      {/* ── Toast Stack ── */}
      {store.toasts.length > 0 && (
        <div style={{
          position: 'fixed',
          top: 'calc(60px + env(safe-area-inset-top))', left: '50%', transform: 'translateX(-50%)',
          zIndex: 300, display: 'flex', flexDirection: 'column', gap: 8,
          width: '90%', maxWidth: 360,
          pointerEvents: 'none',
        }}>
          {store.toasts.map(t => {
            const iconName = NOTIF_ICONS[t.icon] || NOTIF_ICONS[t.type] || 'bell';
            return (
              <div
                key={t.id}
                style={{
                  background: 'var(--hh-surface)',
                  borderRadius: 16,
                  boxShadow: '0 8px 32px rgba(0,0,0,0.18)',
                  border: '1px solid var(--hh-line-soft)',
                  display: 'flex', gap: 10, alignItems: 'center',
                  padding: '10px 14px',
                  pointerEvents: 'auto',
                  animation: 'hh-toast-in 0.3s ease-out',
                }}
              >
                <div style={{
                  width: 32, height: 32, borderRadius: 999,
                  background: t.type === 'geofence' ? '#C9562E22' : t.type === 'warning' ? '#d4440022' : 'var(--hh-accent-tint)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                }}>
                  <Icon name={iconName} size={15} color={t.type === 'geofence' ? '#C9562E' : t.type === 'warning' ? '#d44' : 'var(--hh-accent)'}/>
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, lineHeight: 1.3 }}>{t.title}</div>
                  {t.message && <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)', marginTop: 1 }}>{t.message}</div>}
                </div>
                <button
                  onClick={() => store.dismissToast(t.id)}
                  className="press"
                  style={{ width: 24, height: 24, borderRadius: 999, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}
                >
                  <Icon name="close" size={12} color="var(--hh-ink-mute)"/>
                </button>
              </div>
            );
          })}
        </div>
      )}

      {/* ── Command Palette (Cmd+K) ── */}
      {cmdOpen && (
        <div onClick={() => setCmdOpen(false)} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.4)', zIndex: 500, display: 'flex', alignItems: 'flex-start', justifyContent: 'center', paddingTop: '15vh', backdropFilter: 'blur(4px)' }}>
          <div onClick={e => e.stopPropagation()} style={{ width: '90%', maxWidth: 480, background: 'var(--hh-surface)', borderRadius: 18, boxShadow: '0 24px 80px rgba(0,0,0,0.3)', overflow: 'hidden', border: '1px solid var(--hh-line-soft)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '12px 16px', borderBottom: '1px solid var(--hh-line-soft)' }}>
              <Icon name="search" size={18} color="var(--hh-ink-mute)"/>
              <input ref={cmdInputRef} value={cmdQuery} onChange={e => { setCmdQuery(e.target.value); setCmdIdx(0); }} onKeyDown={handleCmdKey}
                placeholder="Search tabs, devices, scenes…"
                style={{ flex: 1, height: 36, background: 'transparent', border: 'none', outline: 'none', fontSize: 15, color: 'var(--hh-ink)', fontFamily: 'var(--hh-font)' }}/>
              <span style={{ fontSize: 10, padding: '2px 8px', borderRadius: 6, background: 'var(--hh-surface-2)', color: 'var(--hh-ink-mute)' }}>ESC</span>
            </div>
            <div style={{ maxHeight: 360, overflowY: 'auto', padding: '4px 0' }}>
              {filteredCmd.length === 0 && <div style={{ padding: '20px', textAlign: 'center', color: 'var(--hh-ink-mute)', fontSize: 13 }}>No results</div>}
              {filteredCmd.map((item, i) => (
                <button key={item.id} onClick={item.action} className="press" style={{
                  width: '100%', textAlign: 'left', padding: '10px 16px', display: 'flex', gap: 10, alignItems: 'center',
                  background: i === cmdIdx ? 'var(--hh-accent-tint)' : 'transparent',
                  borderLeft: i === cmdIdx ? '3px solid var(--hh-accent)' : '3px solid transparent',
                }}>
                  <span style={{ fontSize: 18 }}>{item.emoji}</span>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 14, fontWeight: 500 }}>{item.label}</div>
                    {item.sub && <div style={{ fontSize: 11, color: 'var(--hh-ink-mute)' }}>{item.sub}</div>}
                  </div>
                  <span style={{ fontSize: 10, color: 'var(--hh-ink-mute)', textTransform: 'capitalize' }}>{item.type}</span>
                </button>
              ))}
            </div>
          </div>
        </div>
      )}
    </>
  );

  return (
    <div className="hh-stage" data-theme={cfg.theme}>
      <div className="hh-app-shell">
        <div
          className="hh-screen"
          data-theme={cfg.theme}
          data-density={cfg.density}
          data-tabbar={!route && !store.loading ? 'true' : 'false'}
          data-standalone={isIosStandalone ? 'true' : 'false'}
          style={{ ...themeStyle }}
        >
          {content}
        </div>
      </div>

      {showTweaks && (
        <div className="hh-tweaks">
          <header>
            <span>Tweaks</span>
            <button onClick={() => setShowTweaks(false)} style={{ background: 'none', border: 'none', color: '#8B7763', fontSize: 20, cursor: 'pointer' }}>×</button>
          </header>
          <section>
            <h4>Theme</h4>
            <div className="chips">
              {['light', 'dark'].map(v => (
                <button key={v} className="chip" data-on={cfg.theme === v} onClick={() => updateCfg({ theme: v })}>{v}</button>
              ))}
            </div>
          </section>
          <section>
            <h4>Accent</h4>
            <div className="chips">
              {Object.entries(ACCENTS).map(([k, v]) => (
                <button key={k} className="swatch" data-on={cfg.accent === k} onClick={() => updateCfg({ accent: k })} style={{ background: v.a }} title={k}/>
              ))}
            </div>
          </section>
          <section>
            <h4>Density</h4>
            <div className="chips">
              {['comfy', 'compact'].map(v => (
                <button key={v} className="chip" data-on={cfg.density === v} onClick={() => updateCfg({ density: v })}>{v}</button>
              ))}
            </div>
          </section>
          <section>
            <h4>Icon style</h4>
            <div className="chips">
              {['outline', 'filled', 'duotone'].map(v => (
                <button key={v} className="chip" data-on={cfg.iconVariant === v} onClick={() => updateCfg({ iconVariant: v })}>{v}</button>
              ))}
            </div>
          </section>
          <section>
            <h4>Dashboard layout</h4>
            <div className="chips">
              {['cozy', 'compact', 'wide'].map(v => (
                <button key={v} className="chip" data-on={cfg.layout === v} onClick={() => updateCfg({ layout: v })}>{v}</button>
              ))}
            </div>
          </section>
          <section style={{ borderBottom: 'none' }}>
            <h4>Navigate to screen</h4>
            <div className="chips">
              {[['home','Home'],['map','Map'],['lists','Board'],['calendar','Calendar'],['settings','More'],['rules','Rules'],['scenes','Scenes'],['cameras','Cameras'],['activity','Activity'],['devices','Devices'],['family','Family'],['waste','Waste'],['privacy','Privacy'],['hubs','Hubs'],['energy','Energy'],['appSettings','App Settings']].map(([id, l]) => (
                <button key={id} className="chip" onClick={() => nav(id)}>{l}</button>
              ))}
            </div>
          </section>
        </div>
      )}
    </div>
  );
}

function Root() {
  const { user, logout } = useAuth();
  if (!user) return <LoginScreen />;
  return <App user={user} onLogout={logout} />;
}

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