// Admin shell · one persistent nav: collapsible grouped rail, topbar
// (drop-in, health, send-mode, identity), ⌘K palette, breadcrumb.

window.ADMIN_NAV = [
  { label:'OVERVIEW', items:[
    { k:'01', id:'dash',   label:'Dashboard',        badge:null },
  ]},
  { label:'NETWORK', items:[
    { k:'02', id:'onb',    label:'Pipeline',         badge:null },
    { k:'03', id:'pubcrm', label:'Publishers',       badge:null },
    { k:'04', id:'creators', label:'Creators',       badge:null },
    { k:'05', id:'biz',    label:'Business hub',     badge:null },
    { k:'05', id:'growers', label:'Growers network',  badge:null },
    { k:'06', id:'inbox',  label:'Submissions',      badge:null },
  ]},
  { label:'CONTENT', items:[
    { k:'07', id:'desk',   label:'Content desk',     badge:null },
    { k:'08', id:'studio', label:'Editorial studio', badge:'AI' },
    { k:'09', id:'coverage', label:'Coverage desk',  badge:null },
  ]},
  { label:'COMMERCE', items:[
    { k:'10', id:'ads',    label:'Ad operations',    badge:null },
    { k:'11', id:'synd',   label:'Syndication',      badge:null },
    { k:'12', id:'rev',    label:'Revenue ledger',   badge:null },
  ]},
  { label:'SETTINGS', items:[
    { k:'13', id:'team',   label:'Team & access',    badge:null },
  ]},
];

// merged sections: tab strips + nav-highlight aliases (deep-link slugs stay valid)
window.ADMIN_TABS = (()=>{
  const pubs = [ {id:'pubcrm', label:'Roster'}, {id:'pubintel', label:'Intel & scoring'} ];
  const pipe = [ {id:'onb', label:'Onboarding'}, {id:'acq', label:'Acquisition targets'} ];
  const desk = [ {id:'desk', label:'Approvals'}, {id:'reqs', label:'Requests'}, {id:'spot', label:'Spotlight'}, {id:'video', label:'Videos'}, {id:'pods', label:'Podcasts'}, {id:'nl', label:'Newsletter'} ];
  return { pubcrm:pubs, pubintel:pubs, onb:pipe, acq:pipe, desk, reqs:desk, spot:desk, video:desk, pods:desk, nl:desk };
})();
window.NAV_ALIAS = { pubintel:'pubcrm', acq:'onb', reqs:'desk', spot:'desk', video:'desk', pods:'desk', nl:'desk' };
window.ADMIN_PAL_EXTRA = [
  { k:'03', id:'pubintel', label:'Publisher intel', grp:'NETWORK' },
  { k:'02', id:'acq',      label:'Acquisition targets', grp:'NETWORK' },
  { k:'07', id:'reqs',     label:'Article requests', grp:'CONTENT' },
  { k:'07', id:'spot',     label:'Spotlight desk', grp:'CONTENT' },
  { k:'07', id:'video',    label:'Video desk', grp:'CONTENT' },
  { k:'07', id:'pods',     label:'Podcast desk', grp:'CONTENT' },
  { k:'07', id:'nl',       label:'Newsletter desk', grp:'CONTENT' },
];

// Nav groups always start open so every section (incl. the Studio) is findable on load.
function loadFold(){ return {}; }

// SAMPLE mode: every list holds exactly one record so you can see how it populates
const SAMPLE_KEYS = ['PUBLISHERS','PUBLISHERS_EXT','ADMIN_SIGNALS','CONTACTS','REQUESTS','CAMPAIGNS','LEDGER','ACQ','CREATORS','CONTENT_QUEUE','NEWSLETTERS','NL_DRAFT','REPUB_ITEMS','BACKLINKS','PAID_LINK_INVENTORY','PARTNER_LEADS','WRITER_ACTIVITY','WIRE_TRENDS','COVERAGE_PACKAGES','SPOT_NOMS'];
const FULL_DATA = {};
function applySample(on){
  SAMPLE_KEYS.forEach(k=>{
    if(!Array.isArray(window[k])) return;
    if(!(k in FULL_DATA)) FULL_DATA[k] = window[k];
    window[k] = on ? FULL_DATA[k].slice(0,1) : FULL_DATA[k];
  });
}

function AdminShell({route, setRoute, children, title, breadcrumb, actions}){
  const sess = window.getAdminSession ? window.getAdminSession() : null;
  const role = sess ? sess.role : 'owner';
  const [fold, setFold] = React.useState(loadFold);
  const [pal, setPal]   = React.useState(false);
  const [drawer, setDrawer] = React.useState(false);
  const [sim, setSim] = React.useState(sessionStorage.getItem('tuepac_sim')||'sample');
  function pickSim(v){ sessionStorage.setItem('tuepac_sim', v); if(v==='sample'||sim==='sample'){ location.reload(); } else { setSim(v); } }

  React.useEffect(()=>{
    const k = e=>{ if((e.metaKey||e.ctrlKey) && e.key.toLowerCase()==='k'){ e.preventDefault(); setPal(p=>!p); } };
    window.addEventListener('keydown', k);
    return ()=>window.removeEventListener('keydown', k);
  }, []);
  React.useEffect(()=>{ setDrawer(false); }, [route]);

  function toggleFold(label){
    setFold(prev=>({...prev, [label]: !prev[label]}));
  }
  const groups = window.ADMIN_NAV
    .map(g=>({...g, items: g.items.filter(it=>!window.roleAllows || window.roleAllows(role, it.id))}))
    .filter(g=>g.items.length);
  const CP = window.CommandPalette;
  const readOnly = role==='viewer';
  const navId = (window.NAV_ALIAS||{})[route] || route;
  const tabs = ((window.ADMIN_TABS||{})[route]||[]).filter(t=>!window.roleAllows || window.roleAllows(role, t.id));

  return (
    <div className="adm-shell">
      <aside className={'adm-side'+(drawer?' open':'')}>
        <div className="brand">
          <div className="mark">TUEPAC</div>
          <div className="sub">CONSOLE</div>
        </div>

        {groups.map(g=>{
          const closed = !!fold[g.label] && !g.items.some(it=>it.id===navId);
          return (
            <React.Fragment key={g.label}>
              <button className="grp-btn" onClick={()=>toggleFold(g.label)}>
                <span className="grp">{g.label}</span>
                <span className="chev">{closed?'+':'–'}</span>
              </button>
              {!closed && (
                <nav className="nav">
                  {g.items.map(it=>(
                    <button key={it.id} className={navId===it.id?'active':''} onClick={()=>setRoute(it.id)}>
                      <span style={{display:'flex',alignItems:'center',gap:8,minWidth:0}}>
                        <span className="mono" style={{fontSize:9,color:'#6f86a6',letterSpacing:'.08em'}}>{it.k}</span>
                        <span style={{whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{it.label}</span>
                      </span>
                      {it.badge && <span className={'badge'+(it.red?' red':'')}>{it.badge}</span>}
                    </button>
                  ))}
                </nav>
              )}
            </React.Fragment>
          );
        })}

        <div className="foot">
          <div>⌘K jumps anywhere</div>
          <div className="sim">
            <span>VIEW</span>
            {['sample','live','loading','empty','down'].map(v=>(
              <button key={v} className={sim===v?'on':''} onClick={()=>pickSim(v)}>{v}</button>
            ))}
          </div>
          <div style={{marginTop:8}}>
            <a href="TUEPAC Network.html" style={{color:'var(--gold)',borderBottom:'1px solid rgba(179,25,66,.5)',paddingBottom:1}}>← public site</a>
          </div>
        </div>
      </aside>
      {drawer && <div className="drawer-veil" onClick={()=>setDrawer(false)}></div>}

      <main>
        <Topbar onMenu={()=>setDrawer(d=>!d)} onPalette={()=>setPal(true)} setRoute={setRoute}/>
        <div className={'adm-canvas'+(readOnly?' ro':'')}>
          {readOnly && <div className="ro-note mono">VIEWER · READ-ONLY · ACTIONS ARE DISABLED FOR YOUR ROLE</div>}
          <PageHeader title={title} breadcrumb={breadcrumb} actions={sim==='live'?actions:null}/>
          {tabs.length>1 && (
            <div className="sec-tabs">
              {tabs.map(t=>(
                <button key={t.id} className={t.id===route?'on':''} onClick={()=>setRoute(t.id)}>{t.label}</button>
              ))}
            </div>
          )}
          {sim==='loading' ? <LoadingState/> : sim==='down' ? <ApiDownState/> : sim==='empty' ? <EmptyState title={title}/> : children}
        </div>
      </main>

      {CP && <CP open={pal} onClose={()=>setPal(false)} go={setRoute}/>}
    </div>
  );
}

function Topbar({onMenu, onPalette, setRoute}){
  const sess = window.getAdminSession ? window.getAdminSession() : null;
  const [menu, setMenu] = React.useState(false);
  const [live, setLive] = React.useState(localStorage.getItem('tuepac_live_sending')==='1');
  React.useEffect(()=>{
    const f = ()=>setLive(localStorage.getItem('tuepac_live_sending')==='1');
    window.addEventListener('tuepac-live', f);
    return ()=>window.removeEventListener('tuepac-live', f);
  }, []);
  React.useEffect(()=>{
    if(!menu) return;
    const close = ()=>setMenu(false);
    window.addEventListener('click', close);
    return ()=>window.removeEventListener('click', close);
  }, [menu]);

  return (
    <div className="adm-top">
      <button className="burger" onClick={onMenu} aria-label="menu">☰</button>
      <div className="adm-search" onClick={onPalette}>
        <span className="mono" style={{fontSize:9.5,color:'var(--mute)',letterSpacing:'.14em'}}>QUICK · DROP-IN</span>
        <input placeholder="paste email, URL, handle… or jump to a section"/>
        <span className="k">⌘</span><span className="k">K</span>
      </div>
      <div className="adm-quick">
        <span className="dot"></span>
        <span>API · LIVE</span>
        <span style={{color:'var(--rule-line)'}}>·</span>
        <span className="mono" style={{color:live?'var(--red)':'var(--gold-2)',fontWeight:600,letterSpacing:'.1em'}}>{live?'SEND · LIVE':'SEND · DRY-RUN'}</span>
        <span style={{color:'var(--rule-line)'}}>·</span>
        <a>{(window.PUBLISHERS||[]).length} PUBS</a>
      </div>
      <div style={{position:'relative'}}>
        <button className="adm-me" onClick={e=>{e.stopPropagation();setMenu(m=>!m);}}>
          <span className="mono" style={{fontSize:10,color:'var(--mute)',letterSpacing:'.08em'}}>{(sess?sess.role:'op').toUpperCase()}</span>
          <span>{sess?sess.name:' · '}</span>
          <span className="av">{sess?sess.initials:'··'}</span>
        </button>
        {menu && (
          <div className="me-menu" onClick={e=>e.stopPropagation()}>
            <div className="who">
              <div style={{fontSize:13,fontWeight:600}}>{sess?sess.name:' · '}</div>
              <div className="mono" style={{fontSize:9.5,color:'var(--mute)',letterSpacing:'.06em'}}>{sess?sess.email.toUpperCase():''}</div>
              <div style={{marginTop:6}}><Pill k="g">{sess?sess.role:''}</Pill></div>
            </div>
            {sess && sess.role==='owner' && <button onClick={()=>{setMenu(false);setRoute('team');}}>Manage team</button>}
            <a href="TUEPAC Network.html">Public site ↗</a>
            <button className="out" onClick={()=>window.clearAdminSession && window.clearAdminSession()}>Sign out</button>
          </div>
        )}
      </div>
    </div>
  );
}

function PageHeader({title, breadcrumb, actions}){
  return (
    <div className="ph">
      <div>
        <div className="breadcrumb">{breadcrumb}</div>
        <h1>{title}</h1>
      </div>
      <div className="right">{actions}</div>
    </div>
  );
}

// ----- shared widgets -----

function Stat({n,l,d,up}){
  return (
    <div className="stat">
      <div className="lbl">{l}</div>
      <div className="n">{n}</div>
      {d && <div className={'d '+(up===true?'up':up===false?'dn':'')}>{up===true?'▲ ':up===false?'▼ ':''}{d}</div>}
    </div>
  );
}

function Card({title, meta, actions, children, style={}}){
  return (
    <div className="card" style={style}>
      {(title||actions) && (
        <div className="hd">
          <div style={{display:'flex',alignItems:'baseline',gap:10}}>
            {title && <h3>{title}</h3>}
            {meta && <span className="meta">{meta}</span>}
          </div>
          {actions && <div style={{display:'flex',gap:6}}>{actions}</div>}
        </div>
      )}
      <div className="bd">{children}</div>
    </div>
  );
}

function Pill({k='muted', children}){
  return <span className={'pill '+k}><span className="d" style={{background:'currentColor'}}></span>{children}</span>;
}

function Score({n, max=100, tone}){
  const t = tone || (n>=80?'var(--green)':n>=65?'var(--navy)':n>=50?'var(--gold-2)':'var(--red)');
  return (
    <span className="scr">
      <span>{n}</span>
      <span className="bar"><i style={{width:`${(n/max)*100}%`,background:t}}/></span>
    </span>
  );
}

function Sparkbars({data, color='var(--navy)'}){
  const max = Math.max(...data);
  return (
    <div className="bars">
      {data.map((v,i)=><i key={i} style={{height:`${(v/max)*100}%`,background:color,opacity:.4+0.6*(v/max)}}/>)}
    </div>
  );
}

function Seg({value, onChange, options}){
  return (
    <div className="seg">
      {options.map(o=>(
        <button key={o} className={o===value?'on':''} onClick={()=>onChange(o)}>{o}</button>
      ))}
    </div>
  );
}

// ----- designed section states (loading / empty / API unreachable) -----

function LoadingState(){
  return (
    <div aria-busy="true">
      <div className="split-4" style={{marginBottom:18}}>
        {[0,1,2,3].map(i=><div key={i} className="stat"><div className="sk" style={{width:'55%',height:9}}></div><div className="sk" style={{width:'40%',height:26,marginTop:10}}></div><div className="sk" style={{width:'70%',height:8,marginTop:9}}></div></div>)}
      </div>
      <div className="card">
        <div className="hd"><div className="sk" style={{width:140,height:14}}></div><div className="sk" style={{width:70,height:10}}></div></div>
        <div className="bd">
          {[0,1,2,3,4,5].map(i=>(
            <div key={i} style={{display:'grid',gridTemplateColumns:'2fr 1fr 1fr 1fr',gap:14,padding:'11px 0',borderBottom:i===5?'none':'1px solid var(--rule-line)'}}>
              <div className="sk" style={{height:11,width:`${70-i*4}%`}}></div><div className="sk" style={{height:11,width:'60%'}}></div><div className="sk" style={{height:11,width:'45%'}}></div><div className="sk" style={{height:11,width:'55%'}}></div>
            </div>
          ))}
        </div>
      </div>
      <div className="mono" style={{marginTop:14,fontSize:9.5,letterSpacing:'.16em',color:'var(--mute)',textTransform:'uppercase'}}>Loading from /api/admin…</div>
    </div>
  );
}

function ApiDownState(){
  return (
    <div className="state-card">
      <div className="mono" style={{fontSize:10,letterSpacing:'.18em',color:'var(--red)',fontWeight:600}}>● API UNREACHABLE</div>
      <h2 className="serif" style={{fontSize:26,fontWeight:700,margin:'12px 0 8px',letterSpacing:'-.01em'}}>The console can't reach the network.</h2>
      <p style={{fontSize:13,color:'var(--mute)',maxWidth:'46ch',margin:'0 auto',lineHeight:1.55}}>Nothing was lost · this view will restore itself when the connection returns. Your session is still valid.</p>
      <div style={{display:'flex',gap:8,justifyContent:'center',marginTop:20}}>
        <button className="btn n s">Retry now</button>
        <button className="btn gh s">View status page ↗</button>
      </div>
      <div className="mono" style={{marginTop:18,fontSize:9,letterSpacing:'.14em',color:'var(--mute-2)',textTransform:'uppercase'}}>Last successful sync · 2 min ago · retrying every 15s</div>
    </div>
  );
}

function EmptyState({title}){
  return (
    <div className="state-card">
      <div className="mono" style={{fontSize:10,letterSpacing:'.18em',color:'var(--navy)',fontWeight:600}}>NOTHING HERE YET</div>
      <h2 className="serif" style={{fontSize:26,fontWeight:700,margin:'12px 0 8px',letterSpacing:'-.01em'}}>{title} starts empty.</h2>
      <p style={{fontSize:13,color:'var(--mute)',maxWidth:'46ch',margin:'0 auto',lineHeight:1.55}}>Seed the first record with the quick drop-in above · paste an email, URL, or handle and the engine takes it from there.</p>
      <div style={{display:'flex',gap:8,justifyContent:'center',marginTop:20}}>
        <button className="btn n s">+ Add the first one</button>
        <button className="btn gh s">Import CSV</button>
      </div>
    </div>
  );
}

function Empty({t='Nothing here yet.'}){
  return <div style={{padding:'40px 0',textAlign:'center',color:'var(--mute)',fontFamily:'var(--mono)',fontSize:10.5,letterSpacing:'.14em',textTransform:'uppercase'}}>{t}</div>;
}

window.AdminShell = AdminShell;
window.applySample = applySample;
window.Stat = Stat;
window.Card = Card;
window.Pill = Pill;
window.Score = Score;
window.Sparkbars = Sparkbars;
window.Seg = Seg;
window.Empty = Empty;
