// Main analytics app — shell + router

const { useState: uS, useEffect: uE } = React;
const D = window.ANALYTICS_DATA;

// Zet een periode-sleutel om naar een datumbereik {start, end, label}
// Klant + domein switcher voor staff
function ClientDomainSwitcher({ user, activeClient, setActiveClient, activeDomain, setActiveDomain }) {
  const API = window.SER_ANALYTICS_API || '';
  const [clients, setClients] = React.useState([]);
  const [open, setOpen] = React.useState(false);

  React.useEffect(() => {
    if (user?.kind !== 'staff') return;
    fetch(`${API}/api/admin/clients`, {
      headers: { Authorization: `Bearer ${localStorage.getItem('ser-analytics-token')}` }
    }).then(r => r.json())
      .then(d => {
        const list = d.clients || [];
        setClients(list);
        if (list.length && !activeClient) {
          setActiveClient(list[0]);
          const domains = list[0].domains || [];
          if (domains.length) setActiveDomain(domains[0].id);
        }
      }).catch(() => {});
  }, [user?.kind]);

  if (user?.kind !== 'staff' || clients.length === 0) return null;

  const current = clients.find(c => c.id === activeClient?.id) || clients[0];
  const domains = current?.domains || [];
  const currentDomain = domains.find(d => d.id === activeDomain) || domains[0];

  return (
    <div style={{position:'relative'}}>
      <button onClick={() => setOpen(o => !o)} style={{
        display:'flex', alignItems:'center', gap:6, padding:'5px 10px',
        background:'var(--ink-50)', border:'1px solid var(--ink-200)', borderRadius:7,
        fontSize:12, fontWeight:600, color:'var(--ink-700)', cursor:'pointer', whiteSpace:'nowrap', maxWidth:200,
      }}>
        <div style={{width:18, height:18, borderRadius:4, background:'linear-gradient(135deg,var(--ser-navy),#7c5cff)', color:'white', display:'grid', placeItems:'center', fontSize:9, fontWeight:800, flexShrink:0}}>
          {current?.name?.slice(0,2).toUpperCase() || '??'}
        </div>
        <span style={{overflow:'hidden', textOverflow:'ellipsis'}}>{currentDomain?.label || current?.name || 'Klant'}</span>
        <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" style={{flexShrink:0}}><path d="M6 9l6 6 6-6"/></svg>
      </button>

      {open && (
        <>
          <div style={{position:'fixed',inset:0,zIndex:49}} onClick={() => setOpen(false)}/>
          <div style={{
            position:'absolute', top:'calc(100% + 6px)', left:0, zIndex:50,
            background:'white', border:'1px solid var(--ink-200)', borderRadius:10,
            boxShadow:'var(--shadow-lg)', minWidth:240, maxHeight:380, overflowY:'auto',
          }}>
            {clients.map(c => (
              <div key={c.id}>
                <div style={{padding:'8px 14px 4px', fontSize:10, fontWeight:700, color:'var(--ink-500)', textTransform:'uppercase', letterSpacing:'0.06em', background:'var(--ink-25)', borderBottom:'1px solid var(--ink-100)'}}>
                  {c.name}
                </div>
                {(c.domains?.length ? c.domains : [{ id: c.id, label: c.domain || c.name, domain: c.domain }]).map(d => (
                  <button key={d.id} onClick={() => {
                    setActiveClient(c);
                    setActiveDomain(d.id);
                    setOpen(false);
                  }} style={{
                    display:'flex', alignItems:'center', gap:10, width:'100%', padding:'9px 14px',
                    border:'none', textAlign:'left', cursor:'pointer',
                    background: activeClient?.id === c.id && activeDomain === d.id ? 'var(--ink-25)' : 'transparent',
                    borderLeft: `3px solid ${activeClient?.id === c.id && activeDomain === d.id ? 'var(--ser-teal)' : 'transparent'}`,
                  }}>
                    <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/></svg>
                    <div>
                      <div style={{fontSize:12, fontWeight:600, color:'var(--ink-900)'}}>{d.label || d.domain}</div>
                      <div style={{fontSize:10, color:'var(--ink-400)', fontFamily:'var(--font-mono)'}}>{d.domain}</div>
                    </div>
                    {activeClient?.id === c.id && activeDomain === d.id && (
                      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="var(--ser-teal)" strokeWidth="2.5" strokeLinecap="round" style={{marginLeft:'auto'}}><path d="M20 6L9 17l-5-5"/></svg>
                    )}
                  </button>
                ))}
              </div>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

window.resolvePeriod = function(period) {
  const now = new Date();
  const y = now.getFullYear(), m = now.getMonth();
  const fmt = d => d.toISOString().split('T')[0];
  const map = {
    '7d':          { start: fmt(new Date(now - 7*864e5)),   end: fmt(now), label: '7 dagen' },
    '30d':         { start: fmt(new Date(now - 30*864e5)),  end: fmt(now), label: '30 dagen' },
    '90d':         { start: fmt(new Date(now - 90*864e5)),  end: fmt(now), label: '90 dagen' },
    '365d':        { start: fmt(new Date(now - 365*864e5)), end: fmt(now), label: '365 dagen' },
    'this_month':  { start: fmt(new Date(y, m, 1)),         end: fmt(now), label: 'Deze maand' },
    'last_month':  { start: fmt(new Date(y, m-1, 1)),       end: fmt(new Date(y, m, 0)), label: 'Vorige maand' },
    'this_quarter':{ start: fmt(new Date(y, Math.floor(m/3)*3, 1)), end: fmt(now), label: 'Dit kwartaal' },
    'last_quarter':{ start: fmt(new Date(y, Math.floor(m/3)*3-3, 1)), end: fmt(new Date(y, Math.floor(m/3)*3, 0)), label: 'Vorig kwartaal' },
    'this_year':   { start: fmt(new Date(y, 0, 1)),         end: fmt(now), label: 'Dit jaar' },
    'last_year':   { start: fmt(new Date(y-1, 0, 1)),       end: fmt(new Date(y-1, 11, 31)), label: 'Vorig jaar' },
  };
  return map[period] || map['30d'];
};

function BetaBadge({ label = 'BETA', tooltip = 'Dit is een experimentele berekening. Gebruik als richtlijn, niet als absolute waarheid.' }) {
  const [show, setShow] = React.useState(false);
  return (
    <span style={{position:'relative', display:'inline-flex'}}
      onMouseEnter={() => setShow(true)} onMouseLeave={() => setShow(false)}>
      <span style={{
        padding:'1px 6px', borderRadius:4, fontSize:9, fontWeight:800,
        background:'rgba(245,165,35,0.15)', color:'#b37800',
        border:'1px solid rgba(245,165,35,0.3)', letterSpacing:'0.06em',
        cursor:'help', textTransform:'uppercase',
      }}>{label}</span>
      {show && (
        <span style={{
          position:'absolute', bottom:'calc(100% + 6px)', left:'50%', transform:'translateX(-50%)',
          background:'var(--ink-900)', color:'white', borderRadius:6, padding:'8px 12px',
          fontSize:11, whiteSpace:'nowrap', zIndex:100, maxWidth:260, whiteSpace:'normal',
          lineHeight:1.5, boxShadow:'var(--shadow-lg)',
        }}>{tooltip}</span>
      )}
    </span>
  );
}
window.BetaBadge = BetaBadge;

function PeriodPicker({ period, setPeriod, compare, setCompare }) {
  const [open, setOpen] = React.useState(false);
  const periods = [
    ['7d',          '7 dagen'],
    ['30d',         '30 dagen'],
    ['90d',         '90 dagen'],
    ['this_month',  'Deze maand'],
    ['last_month',  'Vorige maand'],
    ['this_quarter','Dit kwartaal'],
    ['last_quarter','Vorig kwartaal'],
    ['this_year',   'Dit jaar'],
    ['last_year',   'Vorig jaar'],
    ['365d',        'Laatste 365 dagen'],
  ];
  const compares = [['yoy','vs. vorig jaar'],['qoq','vs. vorig kwartaal'],['mom','vs. vorige maand'],['none','geen vergelijking']];
  const currentPeriod = periods.find(p => p[0] === period)?.[1] || '30 dagen';
  const currentCompare = compares.find(c => c[0] === compare)?.[1] || 'vs. vorig jaar';

  return (
    <div style={{position:'relative'}}>
      <button onClick={() => setOpen(o => !o)} style={{
        display:'flex', alignItems:'center', gap:6, padding:'6px 12px',
        background:'var(--ink-50)', border:'1px solid var(--ink-200)', borderRadius:8,
        fontSize:12, fontWeight:600, color:'var(--ink-700)', cursor:'pointer',
        whiteSpace:'nowrap',
      }}>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
        {currentPeriod} · {currentCompare}
        <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M6 9l6 6 6-6"/></svg>
      </button>

      {open && (
        <>
          <div style={{position:'fixed',inset:0,zIndex:49}} onClick={() => setOpen(false)}/>
          <div style={{
            position:'absolute', top:'calc(100% + 6px)', right:0, zIndex:50,
            background:'white', border:'1px solid var(--ink-200)', borderRadius:10,
            boxShadow:'var(--shadow-lg)', padding:14, minWidth:220,
          }}>
            <div style={{fontSize:11, fontWeight:700, color:'var(--ink-500)', textTransform:'uppercase', letterSpacing:'0.08em', marginBottom:8}}>Periode</div>
            {periods.map(([v,l]) => (
              <button key={v} onClick={() => setPeriod(v)} style={{
                display:'block', width:'100%', textAlign:'left', padding:'7px 10px',
                border:'none', borderRadius:6, cursor:'pointer', fontSize:13,
                background: period===v ? 'var(--ser-navy)' : 'transparent',
                color: period===v ? 'white' : 'var(--ink-700)',
              }}>{l}</button>
            ))}
            <div style={{fontSize:11, fontWeight:700, color:'var(--ink-500)', textTransform:'uppercase', letterSpacing:'0.08em', margin:'12px 0 8px'}}>Vergelijken</div>
            {compares.map(([v,l]) => (
              <button key={v} onClick={() => setCompare(v)} style={{
                display:'block', width:'100%', textAlign:'left', padding:'7px 10px',
                border:'none', borderRadius:6, cursor:'pointer', fontSize:13,
                background: compare===v ? 'var(--ser-navy)' : 'transparent',
                color: compare===v ? 'white' : 'var(--ink-700)',
              }}>{l}</button>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

function App() {
  const [user, setUser] = uS(null);
  const [activeDash, setActiveDash] = uS('overview');
  const [activeDomain, setActiveDomain] = uS(null);
  const [activeClient, setActiveClient] = uS(null); // voor staff: actieve klant
  const [period, setPeriod] = uS('this_month');
  const [compare, setCompare] = uS('yoy'); // 'yoy' | 'mom' | 'none'
  const [tweaksOpen, setTweaksOpen] = uS(false);
  const [railOpen, setRailOpen] = uS(false); // mobile drawer
  const [sessionLoading, setSessionLoading] = uS(true);
  const [tweaks, setTweaks] = uS(/*EDITMODE-BEGIN*/{
    "showAiInsights": true,
    "density": "comfy",
    "accent": "violet"
  }/*EDITMODE-END*/);

  uE(() => {
    const onMsg = (e) => {
      // Accepteer alleen berichten van dezelfde origin of bekende parent
      const t = e?.data?.type;
      if (t === '__activate_edit_mode') setTweaksOpen(true);
      else if (t === '__deactivate_edit_mode') setTweaksOpen(false);
    };
    window.addEventListener('message', onMsg);
    window.parent.postMessage({type: '__edit_mode_available'}, window.location.origin || '*');
    return () => window.removeEventListener('message', onMsg);
  }, []);

  // Verwerk OAuth token uit URL na Google redirect
  uE(() => {
    const params = new URLSearchParams(window.location.search);
    const token = params.get('token');
    const authError = params.get('auth_error');
    if (token) {
      localStorage.setItem('ser-analytics-token', token);
      const API = window.SER_ANALYTICS_API || 'https://ser-analytics-production.up.railway.app';
      fetch(`${API}/api/me`, { headers: { Authorization: `Bearer ${token}` } })
        .then(r => r.json())
        .then(u => { setUser({ kind: u.kind, email: u.email, name: u.name, picture: u.picture, token }); setSessionLoading(false); })
        .catch(() => { setUser({ kind: 'staff', name: 'SER Medewerker', token }); setSessionLoading(false); });
      window.history.replaceState({}, '', window.location.pathname);
    } else if (authError) {
      window.history.replaceState({}, '', window.location.pathname);
    }
    // Herstel sessie uit localStorage
    const saved = localStorage.getItem('ser-analytics-token');
    if (saved && !token) {
      const API = window.SER_ANALYTICS_API || 'https://ser-analytics-production.up.railway.app';
      fetch(`${API}/api/me`, { headers: { Authorization: `Bearer ${saved}` } })
        .then(r => r.json())
        .then(u => { setUser({ kind: u.kind, email: u.email, name: u.name, picture: u.picture, token: saved }); setSessionLoading(false); })
        .catch(() => { localStorage.removeItem('ser-analytics-token'); setSessionLoading(false); });
    }
    // Als er geen saved token is, ook loading stoppen
    if (!saved && !token) setSessionLoading(false);
  }, []);

  // Close mobile rail on dash change
  uE(() => { setRailOpen(false); }, [activeDash]);

  if (sessionLoading) return (
    <div style={{display:'flex',alignItems:'center',justifyContent:'center',height:'100vh',background:'#0a0a2e'}}>
      <div style={{color:'rgba(255,255,255,0.6)',fontSize:14,fontFamily:'var(--font-sans)'}}>Laden…</div>
    </div>
  );
  if (!user) return <AnalyticsLogin onLogin={(u) => { window.SER_CACHE?.clear(); setUser(u); }}/>;

  return (
    <div className={`app-shell ${railOpen ? 'rail-open' : ''}`} data-density={tweaks.density} data-accent={tweaks.accent}>
      {railOpen && <div className="rail-backdrop" onClick={() => setRailOpen(false)}/>}
      <Rail active={activeDash} onSelect={(id) => { setActiveDash(id); setRailOpen(false); }} user={user} onClose={() => setRailOpen(false)} period={period} setPeriod={setPeriod} compare={compare} setCompare={setCompare} activeDomain={activeDomain} setActiveDomain={setActiveDomain} isStaff={user?.kind === 'staff' || user?.email?.endsWith('@searchengineresults.nl')}/>
      <div className="main-col">
        <Topbar activeDash={activeDash} period={period} setPeriod={setPeriod} compare={compare} setCompare={setCompare} user={user} activeDomain={activeDomain} setActiveDomain={setActiveDomain} activeClient={activeClient} setActiveClient={setActiveClient} onLogout={() => { localStorage.removeItem('ser-analytics-token'); window.SER_CACHE?.clear(); setUser(null); }} onMenu={() => setRailOpen(true)}/>
        <PageHead activeDash={activeDash}/>
        <main className="dash-area">
          <Router activeDash={activeDash} period={period} compare={compare} onNavigate={setActiveDash} user={user} isStaff={user?.kind === 'staff' || user?.email?.endsWith('@searchengineresults.nl')}/>
        </main>
      </div>
      {tweaksOpen && <TweaksPanel tweaks={tweaks} setTweaks={(k, v) => {
        const next = typeof k === 'object' ? {...tweaks, ...k} : {...tweaks, [k]: v};
        setTweaks(next);
        window.parent.postMessage({type:'__edit_mode_set_keys', edits: next}, window.location.origin || '*');
      }} onClose={() => { setTweaksOpen(false); window.parent.postMessage({type:'__edit_mode_dismissed'}, window.location.origin || '*'); }}/>}
    </div>
  );
}

function DomainSwitcher({ activeDomain, onSelect, clientId }) {
  const [domains, setDomains] = React.useState([]);
  React.useEffect(() => {
    if (!clientId) return;
    const API = window.SER_ANALYTICS_API || '';
    fetch(`${API}/api/admin/clients/${clientId}/domains`, {
      headers: { Authorization: `Bearer ${localStorage.getItem('ser-analytics-token')}` }
    }).then(r => r.json())
      .then(d => {
        setDomains(d.domains || []);
        if (d.domains?.length && !activeDomain) onSelect(d.domains[0].id);
      }).catch(() => {});
  }, [clientId]);

  if (domains.length <= 1) return null;

  return (
    <div className="rail-section" style={{borderBottom:'1px solid rgba(255,255,255,0.08)', paddingBottom:14}}>
      <div className="lbl">Domein</div>
      {domains.map(d => (
        <button key={d.id} className={`rail-item ${activeDomain === d.id ? 'active' : ''}`} onClick={() => onSelect(d.id)}>
          <svg className="ico" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20M12 2a15 15 0 0 0 0 20"/></svg>
          <span>{d.label || d.domain}</span>
          {d.country && <span style={{fontSize:10, opacity:0.6, marginLeft:'auto'}}>{d.country}</span>}
        </button>
      ))}
    </div>
  );
}

function Rail({ active, onSelect, user, onClose, period, setPeriod, compare, setCompare, activeDomain, setActiveDomain, isStaff }) {
  const client = D.ANALYTICS_CLIENTS[0];
  return (
    <aside className="rail">
      <div className="rail-brand">
        <img src="assets/logo-white.svg" alt="SER" style={{height:28, width:'auto', display:'block', flexShrink:0}} />
        <div style={{minWidth:0}}>
          <div className="sub" style={{marginTop:2}}>Analytics Platform</div>
        </div>
        <span className="badge">v1</span>
        <button className="rail-close" onClick={onClose} aria-label="Sluit menu">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M18 6L6 18M6 6l12 12"/></svg>
        </button>
      </div>

      {user?.kind === 'client' && (
        <DomainSwitcher activeDomain={activeDomain} onSelect={setActiveDomain} clientId={user?.clientId} />
      )}

      <div className="rail-section">
        <div className="lbl">Dashboards</div>
        {D.DASHBOARDS.filter(d => !(d.staffOnly && user?.kind !== 'staff')).map(d => (
          <button key={d.id} className={`rail-item ${active === d.id ? 'active' : ''}`} onClick={() => onSelect(d.id)}>
            <span className="ico">{D.Icons[d.icon]}</span>
            <span>{d.label}</span>
            {d.flagship ? <span className="pill flag">★</span> : d.status === 'beta' ? <span className="pill beta">β</span> : null}
          </button>
        ))}
      </div>

      {isStaff && (
        <div className="rail-section">
          <div className="lbl">Beheer</div>
          {D.ADMIN_SECTIONS.map(s => (
            <button key={s.id} className={`rail-item ${active === s.id ? 'active' : ''}`} onClick={() => onSelect(s.id)}>
              <span className="ico">{D.Icons[s.icon] || D.Icons.home}</span>
              <span>{s.label}</span>
            </button>
          ))}
        </div>
      )}

      {client && (
        <div className="rail-foot">
          <div className="client">
            {/* SER logo × klant favicon */}
            <div style={{display:'flex', alignItems:'center', gap:6}}>
              <img src="assets/logo-white.svg" alt="SER" style={{height:18, width:'auto', opacity:0.7}} />
              {client.domain && (
                <>
                  <span style={{color:'rgba(255,255,255,0.3)', fontSize:12}}>×</span>
                  <img
                    src={`https://www.google.com/s2/favicons?domain=${client.domain}&sz=32`}
                    alt={client.name}
                    style={{width:18, height:18, borderRadius:3, objectFit:'contain', background:'white', padding:1}}
                    onError={e => e.target.style.display='none'}
                  />
                </>
              )}
            </div>
            <div style={{minWidth:0}}>
              <div className="nm">{client.name}</div>
              <div className="sub">{client.domain || client.sub}</div>
            </div>
          </div>
        </div>
      )}
    </aside>
  );
}

function DomainSwitcherTopbar({ activeDomain, setActiveDomain, user }) {
  const [domains, setDomains] = React.useState([]);
  const [open, setOpen] = React.useState(false);

  React.useEffect(() => {
    if (!user) return;
    const API = window.SER_ANALYTICS_API || '';
    const clientId = user.kind === 'client' ? user.clientId : null;
    if (!clientId) return;
    fetch(`${API}/api/admin/clients/${clientId}/domains`, {
      headers: { Authorization: `Bearer ${localStorage.getItem('ser-analytics-token')}` }
    }).then(r => r.json())
      .then(d => setDomains(d.domains || []))
      .catch(() => {});
  }, [user?.clientId]);

  if (domains.length <= 1) return null;

  const active = domains.find(d => d.id === activeDomain) || domains[0];

  return (
    <div style={{position:'relative'}}>
      <button onClick={() => setOpen(o => !o)} style={{
        display:'flex', alignItems:'center', gap:6, padding:'5px 10px',
        background:'var(--ink-50)', border:'1px solid var(--ink-200)', borderRadius:7,
        fontSize:12, fontWeight:600, color:'var(--ink-700)', cursor:'pointer', whiteSpace:'nowrap',
      }}>
        <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/></svg>
        {active?.label || active?.domain || 'Domein'}
        <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M6 9l6 6 6-6"/></svg>
      </button>
      {open && (
        <>
          <div style={{position:'fixed',inset:0,zIndex:49}} onClick={() => setOpen(false)}/>
          <div style={{position:'absolute', top:'calc(100% + 6px)', left:0, zIndex:50, background:'white', border:'1px solid var(--ink-200)', borderRadius:9, boxShadow:'var(--shadow-lg)', minWidth:180, overflow:'hidden'}}>
            {domains.map(d => (
              <button key={d.id} onClick={() => { setActiveDomain(d.id); setOpen(false); }} style={{
                display:'flex', alignItems:'center', gap:10, width:'100%', padding:'10px 14px',
                border:'none', background: activeDomain===d.id ? 'var(--ink-25)' : 'transparent',
                cursor:'pointer', textAlign:'left',
                borderLeft: `3px solid ${activeDomain===d.id ? 'var(--ser-teal)' : 'transparent'}`,
              }}>
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/></svg>
                <div>
                  <div style={{fontSize:12, fontWeight:600, color:'var(--ink-900)'}}>{d.label || d.domain}</div>
                  <div style={{fontSize:10, color:'var(--ink-400)'}}>{d.country || d.domain}</div>
                </div>
                {activeDomain===d.id && <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--ser-teal)" strokeWidth="2.5" strokeLinecap="round"><path d="M20 6L9 17l-5-5"/></svg>}
              </button>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

function Topbar({ activeDash, period, setPeriod, compare, setCompare, user, activeDomain, setActiveDomain, activeClient, setActiveClient, onLogout, onMenu }) {
  const dash = D.DASHBOARDS.find(d => d.id === activeDash) || D.ADMIN_SECTIONS?.find(s => s.id === activeDash);
  return (
    <header className="topbar">
      <button className="topbar-menu" onClick={onMenu} aria-label="Open navigatiemenu">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
      </button>
      <div className="crumbs">
        <span>Analytics</span>
        <span>›</span>
        <span className="cur">{dash?.label || 'Analytics'}</span>
      </div>

      <div className="spacer"></div>

      {/* Volgorde: platform-switch | domein-picker | periode-picker */}

      <div className="mod-switch" title="Wissel tussen platforms">
        <a href="https://tools.searchengineresults.nl"><span className="d tools"></span>Tools</a>
        <a className="active"><span className="d analytics"></span>Analytics</a>
      </div>

      {/* Staff: klant + domein switcher */}
      <ClientDomainSwitcher
        user={user}
        activeClient={activeClient}
        setActiveClient={setActiveClient}
        activeDomain={activeDomain}
        setActiveDomain={setActiveDomain}
      />

      {/* Client: domein switcher (meerdere domeinen) */}
      {user?.kind === 'client' && activeDomain && (
        <DomainSwitcherTopbar
          activeDomain={activeDomain}
          setActiveDomain={setActiveDomain}
          user={user}
        />
      )}

      <PeriodPicker period={period} setPeriod={setPeriod} compare={compare} setCompare={setCompare} />

      <button onClick={onLogout} className="av" title="Uitloggen" aria-label="Uitloggen">
        {user?.picture
          ? <img src={user.picture} alt={user.name} style={{width:28,height:28,borderRadius:'50%',objectFit:'cover'}} />
          : (user?.name || '??').split(' ').map(w => w[0]).slice(0,2).join('').toUpperCase()
        }
      </button>
    </header>
  );
}

function PageHead({ activeDash }) {
  const D = window.ANALYTICS_DATA;
  const dash = D.DASHBOARDS.find(d => d.id === activeDash);
  const meta = {
    overview: {eyebrow:`Hub · ${new Date().toLocaleDateString('nl-NL', {day:'numeric',month:'long',year:'numeric'})}`, desc:'Eén plek voor alle dashboards. AI-samenvatting van de afgelopen 90 dagen.'},
    revenue: {eyebrow:'★ Vlaggenschip · live · 12 min geleden bijgewerkt', desc:'Niet alleen wat er gebeurde — maar waarom, en wat eraan te doen is.'},
    campaigns: {eyebrow:'Beta · 7 actieve campagnes', desc:'Live monitoring van alle campagnes met automatische anomalie-detectie.'},
    competition: {eyebrow:'Beta · NL bloemen-markt', desc:'Share-of-voice, prijsmonitoring en SERP-positie ten opzichte van top-5.'},
    funnel: {eyebrow:'Beta', desc:'Volledige funnel met device-, kanaal- en cohortbreakdown.'},
    cohort: {eyebrow:'Beta', desc:'Retentie en LTV per acquisitie-cohort.'},
    ai: {eyebrow:'AI · LLM-aanbevelingen · gerangschikt op impact/effort', desc:'Concrete, doe-vandaag acties met geschatte impact en effort.'},
    briefing: {eyebrow:'Beta · briefing-stijl', desc:'Een-pagina narratief — voor de board, niet voor de marketeer.'},
    strategy: {eyebrow:'Beta · strategie-laag', desc:'Niet alleen cijfers — past de uitvoering bij wat we beloven? Brand, BCG, SWOT, alignment.'},
    cases: {eyebrow:'AI · klikbare cases', desc:'Concrete business cases met stappenplan, ROI en next steps.'},
  }[activeDash] || {eyebrow:'', desc:''};

  return (
    <div className="page-head">
      <div className="left">
        <div className="eyebrow">
          <span style={{width:6, height:6, borderRadius:'50%', background:'#7c5cff', boxShadow:'0 0 0 4px rgba(124,92,255,0.18)'}}></span>
          {meta.eyebrow}
        </div>
        <h1>{dash?.label || 'Analytics'}</h1>
        <div className="desc">{meta.desc}</div>
      </div>
      <div className="right">
        <button>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>
          Exporteren
        </button>
        <button>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="M8.6 13.5l6.8 4M15.4 6.5l-6.8 4"/></svg>
          Delen
        </button>
        <button className="primary">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><path d="M12 2l2 6 6 2-6 2-2 6-2-6-6-2 6-2z"/></svg>
          Vraag AI
        </button>
      </div>
    </div>
  );
}

function Router({ activeDash, period, compare, onNavigate, user, isStaff }) {
  switch (activeDash) {
    case 'overview':    return <window.OverviewDashboard onNavigate={onNavigate}/>;
    case 'revenue':     return <window.RevenueDashboard period={period} compare={compare}/>;
    case 'cases':       return <window.BusinessCasesDashboard/>;
    case 'strategy':    return <window.StrategyDashboard period={period} compare={compare}/>;
    case 'campaigns':   return <window.CampaignsDashboard/>;
    case 'competition': return <window.CompetitionDashboard/>;
    case 'funnel':      return <window.FunnelDashboard/>;
    case 'cohort':      return <window.CohortDashboard/>;
    case 'ai':          return <window.AiDashboard/>;
    case 'briefing':    return <window.BriefingDashboard/>;
    case 'admin-klanten':
      return isStaff ? <window.AdminKlantenDashboard/> : <div style={{textAlign:'center',padding:48}}>Geen toegang</div>;
    case 'admin-users':
      if (!isStaff) return <div style={{textAlign:'center',padding:48,color:'var(--ink-400)'}}>Geen toegang</div>;
      return <window.AdminUsersDashboard/>;
    case 'admin-docs': return isStaff ? <window.AdminDocsDashboard/> : <div style={{textAlign:'center',padding:48,color:'var(--ink-400)'}}>Geen toegang</div>;

    default: return <div>Niet gevonden.</div>;
  }
}

function TweaksPanel({ tweaks, setTweaks, onClose }) {
  return (
    <div style={{position:'fixed', right:20, bottom:20, width:300, background:'white', border:'1px solid var(--ink-200)', borderRadius:12, boxShadow:'var(--shadow-lg)', padding:18, zIndex:1000}}>
      <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:14}}>
        <div style={{fontSize:13, fontWeight:700, color:'var(--ink-900)'}}>Tweaks</div>
        <button onClick={onClose} style={{background:'transparent', border:'none', color:'var(--ink-500)', cursor:'pointer', fontSize:18}}>×</button>
      </div>
      <div style={{fontSize:12, fontWeight:600, color:'var(--ink-500)', marginBottom:6}}>AI-insights tonen</div>
      <button onClick={() => setTweaks('showAiInsights', !tweaks.showAiInsights)} style={{padding:'6px 12px', borderRadius:6, border:'1px solid var(--ink-200)', background: tweaks.showAiInsights ? 'var(--ser-navy)' : 'white', color: tweaks.showAiInsights ? 'white' : 'var(--ink-700)', fontSize:12, fontWeight:600, cursor:'pointer', width:'100%'}}>{tweaks.showAiInsights ? 'Aan' : 'Uit'}</button>
      <div style={{fontSize:12, fontWeight:600, color:'var(--ink-500)', margin:'14px 0 6px'}}>Density</div>
      <div style={{display:'flex', gap:4}}>
        {['compact','comfy','spacious'].map(d => (
          <button key={d} onClick={() => setTweaks('density', d)} style={{flex:1, padding:'6px', borderRadius:6, border:'1px solid var(--ink-200)', background: tweaks.density === d ? 'var(--ser-navy)' : 'white', color: tweaks.density === d ? 'white' : 'var(--ink-700)', fontSize:11, fontWeight:600, cursor:'pointer', textTransform:'capitalize'}}>{d}</button>
        ))}
      </div>
    </div>
  );
}

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

// ── Data cache helpers ─────────────────────────────────────────────────────
// Dashboard-data wordt maximaal 1x per dag opgehaald en gecached in localStorage.
// Bij login wordt de cache altijd geleegd zodat verse data wordt opgehaald.

window.SER_CACHE = {
  get(key) {
    try {
      const entry = JSON.parse(localStorage.getItem(`ser_cache_${key}`) || 'null');
      if (!entry) return null;
      const age = Date.now() - entry.ts;
      if (age > 86400000) { localStorage.removeItem(`ser_cache_${key}`); return null; } // ouder dan 24u
      return entry.data;
    } catch { return null; }
  },
  set(key, data) {
    try { localStorage.setItem(`ser_cache_${key}`, JSON.stringify({ ts: Date.now(), data })); } catch {}
  },
  clear() {
    Object.keys(localStorage).filter(k => k.startsWith('ser_cache_')).forEach(k => localStorage.removeItem(k));
  },
};
