// app.jsx — shell: sidebar (projects) + topbar (tabs) + views + modals + tweaks
const { useState: useA, useEffect: useAE } = React;

const TWEAK_DEFAULTS = {
  "accent": "#EC6F9E",
  "bg": "#FFF3F7",
  "radius": 26,
  "density": "cozy"
};

// expose current identity so EntryModal can read it
window.getCurrentIdentity = () => localStorage.getItem('our-little-ledger.who');

function App() {
  const S = useStore().get();
  const { who, setWho, clearWho } = useIdentity();
  const [tab, setTab] = useA('dashboard');
  const [modal, setModal] = useA(null);
  const [mobileNavOpen, setMobileNavOpen] = useA(false);
  const [toastMsg, setToastMsg] = useA('');
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [syncState, setSyncState] = useA(() => Sync.getStatus());

  const project = Store.activeProject();
  const currentOwner = S.owners.find(o => o.id === who);

  const toast = (m) => { setToastMsg(m); clearTimeout(window.__t); window.__t = setTimeout(() => setToastMsg(''), 2200); };

  useAE(() => { setEntryOpener((e) => setModal({ kind: 'entry', data: e })); }, []);
  useAE(() => Sync.onStatus((status, detail) => setSyncState({ status, detail })), []);

  useAE(() => {
    if (!mobileNavOpen) return;
    const closeOnEscape = (e) => e.key === 'Escape' && setMobileNavOpen(false);
    window.addEventListener('keydown', closeOnEscape);
    return () => window.removeEventListener('keydown', closeOnEscape);
  }, [mobileNavOpen]);

  // apply tweaks to :root
  useAE(() => {
    const r = document.documentElement.style;
    r.setProperty('--accent', t.accent);
    r.setProperty('--accent-soft', tint(t.accent, 0.30));
    r.setProperty('--accent-wash', tint(t.accent, 0.13));
    r.setProperty('--rose', t.accent);
    r.setProperty('--rose-deep', shade(t.accent, -16));
    r.setProperty('--bg', t.bg);
    r.setProperty('--bg-2', shade(t.bg, -4));
    r.setProperty('--r-lg', t.radius + 'px');
    r.setProperty('--r-md', (t.radius * 0.66) + 'px');
    document.body.style.setProperty('--pad', t.density === 'compact' ? '10px' : t.density === 'airy' ? '17px' : '13px');
  }, [t]);

  if (Sync.isOn() && ['auth-required', 'unauthorized', 'connecting'].includes(syncState.status)) {
    return <SignInScreen status={syncState.status} detail={syncState.detail} onSignIn={() => Sync.signIn()} />;
  }

  // show identity picker if not chosen yet
  if (!who) {
    return <WelcomeScreen onChoose={(id) => { setWho(id); toast('Welcome ' + (S.owners.find(o=>o.id===id)?.name || '') + ' 💕'); }} />;
  }

  if (!project) {
    return <div style={{ display:'grid', placeItems:'center', height:'100vh' }}>
      <Empty icon={<Icon name="flower" size={40} color="var(--rose)" />} title="No pages yet"
        sub="Create your first page to start your little ledger together."
        action={<button className="btn btn-primary" onClick={() => setModal({kind:'project'})}>＋ New page</button>} />
    </div>;
  }

  return (
    <div className="app">
      {/* ============ SIDEBAR ============ */}
      <aside id="mobile-navigation" className={`side ${mobileNavOpen ? 'mobile-open' : ''}`} aria-label="Ledger navigation">
        <div className="brand">
          <div className="brand-mark">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M12 20s-6.5-4-6.5-8.6C5.5 8.5 7.3 7 9.2 7c1.5 0 2.4 1 2.8 1.8C12.4 8 13.3 7 14.8 7c1.9 0 3.7 1.5 3.7 4.4C18.5 16 12 20 12 20z"/>
            </svg>
          </div>
          <div className="brand-name">Our Little<br/>Ledger<small>View &amp; Mimi 💕</small></div>
          <button className="mobile-side-close" onClick={() => setMobileNavOpen(false)} aria-label="Close navigation">
            <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18"/></svg>
          </button>
        </div>

        {/* current identity */}
        {currentOwner && (
          <div style={{ margin:'0 4px 8px', padding:'10px 12px', borderRadius:'var(--r-md)', background:'var(--surface)', boxShadow:'var(--sh-sm)', display:'flex', alignItems:'center', gap:10 }}>
            <Avatar owner={currentOwner} size={30} />
            <div style={{ flex:1 }}>
              <div style={{ fontFamily:'var(--font-ui)', fontWeight:700, fontSize:13.5, color: shade(currentOwner.color,-24) }}>{currentOwner.name}</div>
              <div style={{ fontSize:11, fontWeight:600, color:'var(--ink-faint)' }}>That's you 💕</div>
            </div>
            <button onClick={clearWho} title="Switch user"
              style={{ fontFamily:'var(--font-ui)', fontSize:11, fontWeight:700, color:'var(--ink-faint)', padding:'4px 8px', borderRadius:8, transition:'.15s' }}
              onMouseEnter={e=>e.target.style.color='var(--rose)'} onMouseLeave={e=>e.target.style.color='var(--ink-faint)'}>
              Switch
            </button>
          </div>
        )}

        <div className="side-label">Pages
          <button onClick={() => { setModal({kind:'project'}); setMobileNavOpen(false); }} title="New page">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"><path d="M12 5v14M5 12h14"/></svg>
          </button>
        </div>
        <div className="proj-list">
          {S.projects.map(p => (
            <ProjRow key={p.id} p={p} active={p.id===project.id}
              onSelect={() => { Store.setActive(p.id); setTab('dashboard'); setMobileNavOpen(false); }}
              onEdit={() => { setModal({kind:'project', data:p}); setMobileNavOpen(false); }} />
          ))}
        </div>

        <div className="side-foot">
          <button className="side-btn" onClick={() => { setModal({kind:'config'}); setMobileNavOpen(false); }}>
            <svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="3"/><path d="M12 3v2M12 19v2M3 12h2M19 12h2M5.6 5.6l1.4 1.4M17 17l1.4 1.4M18.4 5.6L17 7M7 17l-1.4 1.4"/></svg>
            Config — types &amp; currencies
          </button>
          <button className="side-btn" onClick={() => { setModal({kind:'data'}); setMobileNavOpen(false); }}>
            <svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 7v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9l-3-3H6a2 2 0 0 0-2 2z"/><path d="M12 11v5M9.5 13.5L12 16l2.5-2.5"/></svg>
            Save &amp; share
          </button>
          <SyncStatusChip />
        </div>
      </aside>

      {mobileNavOpen && <button className="mobile-side-scrim" onClick={() => setMobileNavOpen(false)} aria-label="Close navigation" />}

      {/* ============ MAIN ============ */}
      <main className="main">
        <div className="topbar">
          <div className="topbar-inner">
            <button className="mobile-menu-btn" onClick={() => setMobileNavOpen(true)}
              aria-label="Open navigation" aria-controls="mobile-navigation" aria-expanded={mobileNavOpen}>
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.3" strokeLinecap="round"><path d="M4 7h16M4 12h16M4 17h16"/></svg>
            </button>
            <div className="proj-title"><div className="proj-emoji">{project.emoji}</div> {project.name}</div>
            <div className="spacer" />
            <div className="tabs">
              <button className={`tab ${tab==='dashboard'?'active':''}`} onClick={() => setTab('dashboard')}>Dashboard</button>
              <button className={`tab ${tab==='entries'?'active':''}`} onClick={() => setTab('entries')}>Entries</button>
            </div>
          </div>
        </div>
        <div className="main-inner">
          {tab === 'dashboard'
            ? <Dashboard project={project} onAdd={() => setModal({kind:'entry'})} toast={toast} />
            : <EntriesView project={project} onAdd={() => setModal({kind:'entry'})} toast={toast} />}
        </div>

        {/* floating add */}
        <button className="btn btn-primary" onClick={() => setModal({kind:'entry'})}
          style={{ position:'fixed', right:34, bottom:30, zIndex:30, boxShadow:'var(--sh-lg)', padding:'14px 22px', fontSize:15 }}>
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.6" strokeLinecap="round"><path d="M12 5v14M5 12h14"/></svg>
          New entry
        </button>
      </main>

      {/* ============ MODALS ============ */}
      {modal?.kind === 'entry'   && <EntryModal project={project} entry={modal.data} defaultOwner={who} onClose={() => setModal(null)} toast={toast} />}
      {modal?.kind === 'project' && <ProjectModal project={modal.data} onClose={() => setModal(null)} toast={toast} />}
      {modal?.kind === 'config'  && <ConfigModal onClose={() => setModal(null)} toast={toast} />}
      {modal?.kind === 'data'    && <DataModal onClose={() => setModal(null)} toast={toast} />}

      <Toast msg={toastMsg} />

      {/* ============ TWEAKS ============ */}
      <TweaksPanel>
        <TweakSection label="Theme" />
        <TweakColor label="Accent" value={t.accent} onChange={v => setTweak('accent', v)}
          options={['#EC6F9E','#D9568A','#C79BE0','#E0883F','#5BA88A','#5683C4']} />
        <TweakColor label="Background" value={t.bg} onChange={v => setTweak('bg', v)}
          options={['#FFF3F7','#FDEFF9','#FFF6F0','#FBF5FF','#FFFFFF']} />
        <TweakSection label="Shape" />
        <TweakSlider label="Roundness" value={t.radius} min={12} max={34} unit="px" onChange={v => setTweak('radius', v)} />
        <TweakRadio label="Density" value={t.density} options={['compact','cozy','airy']} onChange={v => setTweak('density', v)} />
      </TweaksPanel>
    </div>
  );
}

/* small sync status chip in sidebar footer */
/* sidebar project row with hover ⋯ menu */
function ProjRow({ p, active, onSelect, onEdit }) {
  const [hover, setHover] = React.useState(false);
  const [menuOpen, setMenuOpen] = React.useState(false);

  function del(e) {
    e.stopPropagation();
    setMenuOpen(false);
    if (confirm(`Delete "${p.name}" and all its entries? This can't be undone.`)) {
      Store.deleteProject(p.id);
    }
  }
  function edit(e) {
    e.stopPropagation();
    setMenuOpen(false);
    onEdit();
  }

  return (
    <div style={{ position: 'relative' }}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => { setHover(false); setMenuOpen(false); }}>
      <button className={`proj ${active ? 'active' : ''}`} onClick={onSelect} style={{ width:'100%' }}>
        <div className="proj-emoji">{p.emoji}</div>
        <div className="proj-meta">
          <div className="proj-name">{p.name}</div>
          <div className="proj-sub">{p.entries.length} {p.entries.length===1?'entry':'entries'}</div>
        </div>
        {/* ⋯ button — shows on hover */}
        {hover && (
          <button onClick={e => { e.stopPropagation(); setMenuOpen(v => !v); }}
            style={{ width:26, height:26, borderRadius:8, display:'grid', placeItems:'center',
              background: menuOpen ? 'var(--pink-wash)' : 'transparent',
              color:'var(--ink-soft)', flexShrink:0, transition:'.15s', marginLeft:2 }}
            onMouseEnter={e => e.currentTarget.style.background='var(--pink-wash)'}
            onMouseLeave={e => e.currentTarget.style.background = menuOpen ? 'var(--pink-wash)' : 'transparent'}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><circle cx="5" cy="12" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="19" cy="12" r="2"/></svg>
          </button>
        )}
      </button>

      {/* dropdown menu */}
      {menuOpen && (
        <div style={{ position:'absolute', right:8, top:'calc(100% - 2px)', zIndex:50,
          background:'#fff', borderRadius:14, boxShadow:'var(--sh-lg)', padding:5,
          minWidth:140, animation:'pop .18s var(--ease)' }}
          onMouseLeave={() => { setMenuOpen(false); setHover(false); }}>
          <button onClick={edit} style={{ width:'100%', display:'flex', alignItems:'center', gap:9,
            padding:'9px 12px', borderRadius:10, fontFamily:'var(--font-ui)', fontWeight:600,
            fontSize:13.5, color:'var(--ink)', transition:'.13s', textAlign:'left' }}
            onMouseEnter={e=>e.currentTarget.style.background='var(--pink-wash)'}
            onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 20h9M16.5 3.5a2 2 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
            Edit page
          </button>
          <button onClick={del} style={{ width:'100%', display:'flex', alignItems:'center', gap:9,
            padding:'9px 12px', borderRadius:10, fontFamily:'var(--font-ui)', fontWeight:600,
            fontSize:13.5, color:'#E06363', transition:'.13s', textAlign:'left' }}
            onMouseEnter={e=>e.currentTarget.style.background='#FEEAEA'}
            onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 7h16M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2M6 7l1 13a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1l1-13"/></svg>
            Delete page
          </button>
        </div>
      )}
    </div>
  );
}

function SyncStatusChip() {
  const [st, setSt] = React.useState(window.Sync ? Sync.getStatus() : { status: 'off' });
  React.useEffect(() => window.Sync ? Sync.onStatus((status, detail) => setSt({ status, detail })) : undefined, []);
  const dot = { off:'#B5A3AD', connecting:'#E0A93F', live:'#3FA277', error:'#E06363' }[st.status] || '#B5A3AD';
  const label = { off:'Sync off', connecting:'Connecting…', live:'Live sync ✨', error:'Sync error' }[st.status];
  return (
    <div style={{ display:'flex', alignItems:'center', gap:8, padding:'8px 12px', borderRadius:'var(--r-md)', background:'var(--surface-soft)', margin:'4px 0' }}>
      <span style={{ width:9, height:9, borderRadius:'50%', background:dot, boxShadow:`0 0 0 3px ${tint(dot,0.20)}`, flexShrink:0 }} />
      <span style={{ fontFamily:'var(--font-ui)', fontWeight:600, fontSize:12.5, color:'var(--ink-soft)' }}>{label}</span>
    </div>
  );
}

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