// Editorial Studio · TUEPAC-original drafting. Topic brief -> AI draft -> edit -> publish.
// Uses window.claude.complete when available; deterministic scripted fallback otherwise.

const SECTIONS = window.TAGS || ['Business','Politics','Culture'];

const SEED_PIECES = [];

function stageMeta(s){
  if(s==='published') return ['live','LIVE'];
  if(s==='review')    return ['warn','IN REVIEW'];
  if(s==='scheduled') return ['info','SCHEDULED'];
  return ['muted','DRAFT'];
}
const STUDIO_LS = 'tuepac_studio_pieces';
function loadPieces(){ try{ return JSON.parse(localStorage.getItem(STUDIO_LS))||SEED_PIECES; }catch(e){ return SEED_PIECES; } }
function persistPieces(list){ try{ localStorage.setItem(STUDIO_LS, JSON.stringify(list)); }catch(e){ try{ localStorage.setItem(STUDIO_LS, JSON.stringify(list.map(p=>({...p, img:null})))); }catch(e2){} } }
function fmtSched(iso){
  if(!iso) return 'SCHEDULED';
  const d = new Date(iso);
  if(isNaN(d)) return 'SCHEDULED';
  return d.toLocaleString('en-US',{month:'short',day:'numeric',hour:'numeric',minute:'2-digit'}).toUpperCase();
}

function studioInp(h){
  const base = {width:'100%',padding:'8px 10px',border:'1px solid var(--rule-line)',background:'var(--bg)',fontSize:13,outline:'none',resize:'vertical',display:'block',fontFamily:'var(--sans)'};
  if(h) base.minHeight = h;
  return base;
}

function EditorialStudio({setRoute}){
  const [pieces, setPiecesRaw] = React.useState(loadPieces);
  const setPieces = list=>{ setPiecesRaw(list); persistPieces(list); };
  const [editingId, setEditingId] = React.useState(null);
  const [view, setView]     = React.useState('brief');
  const [llmOn, setLlmOn]   = React.useState(typeof window!=='undefined' && window.claude && typeof window.claude.complete==='function');

  const [topic, setTopic]   = React.useState('');
  const [desk, setDesk]     = React.useState(SECTIONS[0]);
  const [city, setCity]     = React.useState('');
  const [tone, setTone]     = React.useState('Reported');
  const [length, setLength] = React.useState('Standard');
  const [notes, setNotes]   = React.useState('');
  const [outlineFirst, setOutlineFirst] = React.useState(true);

  const [headline, setHeadline] = React.useState('');
  const [dek, setDek]           = React.useState('');
  const [outline, setOutline]   = React.useState([]);
  const [body, setBody]         = React.useState('');
  const [slug, setSlug]         = React.useState('');
  const [meta, setMeta]         = React.useState('');
  const [rights, setRights]     = React.useState('Original');
  const [kicker, setKicker]     = React.useState('');
  const [byline, setByline]     = React.useState(((window.AUTHORS||[])[0]||{}).name || 'TUEPAC Editorial');
  const [pubName, setPubName]   = React.useState(((window.PUBLICATIONS||[])[0]||{}).name || 'TUEPAC Originals');
  const [img, setImg]           = React.useState(null);
  const [focal, setFocal]       = React.useState({x:50,y:50});
  const [caption, setCaption]   = React.useState('');
  const [lead, setLead]         = React.useState(false);
  const [savedNote, setSavedNote] = React.useState(false);
  const [sponsor, setSponsor]   = React.useState('');
  const [cites, setCites]       = React.useState([]);
  const [genNote, setGenNote]   = React.useState('');
  const [genErr, setGenErr]     = React.useState('');

  const [when, setWhen]   = React.useState('now');
  const [schedAt, setSchedAt] = React.useState('');
  const [toNL, setToNL]   = React.useState(true);
  const [nlPick, setNlPick] = React.useState('TUEPAC Daily · Network');

  const words = window.bodyWords ? window.bodyWords(body) : 0;

  function reset(){
    setTopic(''); setNotes(''); setHeadline(''); setDek(''); setOutline([]); setBody('');
    setSlug(''); setMeta(''); setRights('Original'); setSponsor(''); setCites([]);
    setKicker(''); setImg(null); setFocal({x:50,y:50}); setCaption(''); setLead(false); setSavedNote(false);
    setGenNote(''); setGenErr(''); setEditingId(null); setWhen('now'); setSchedAt(''); setView('brief');
  }

  function openPiece(p){
    setEditingId(p.id);
    setTopic(p.topic||''); setDesk(p.desk||SECTIONS[0]); setCity(p.city||''); setTone(p.tone||'Reported'); setNotes(p.notes||'');
    setHeadline(p.headline||''); setDek(p.dek||''); setOutline(p.outline||[]); setBody(p.body||'');
    setSlug(p.slug||''); setMeta(p.meta||''); setRights(p.rights||'Original'); setSponsor(p.sponsor||''); setCites(p.cites||[]);
    setKicker(p.kicker||''); setByline(p.byline||'TUEPAC Editorial'); setPubName(p.pub||'TUEPAC Originals');
    setImg(p.img||null); setFocal(p.focal||{x:50,y:50}); setCaption(p.caption||''); setLead(!!p.lead);
    setWhen(p.schedAt?'schedule':'now'); setSchedAt(p.schedAt||'');
    setGenNote(''); setGenErr(''); setSavedNote(false);
    setView('draft');
  }

  function suggestCites(){
    return (window.PUBLISHERS || []).slice(0,3).map(p=>p.id);
  }

  async function generate(){
    if(!topic.trim()) return;
    setView('generating'); setGenErr('');
    const paras = length==='Brief' ? '3-4' : length==='Feature' ? '7-9' : '5-6';
    const prompt = `You are a senior editor at TUEPAC, The United Economic Professional Advancement Coalition, a national network of Black-owned publishers and independent writers. Voice: institutional, factual, community-grounded, not promotional.
Write a ${tone.toLowerCase()} ${length.toLowerCase()} piece on the ${desk} topic.
TOPIC / ANGLE: ${topic}
${city.trim()?'LOCATION FOCUS: '+city.trim():''}
${notes.trim()?'EDITOR NOTES: '+notes.trim():''}
Return ONLY valid minified JSON, no markdown, with keys:
"headline" (<=14 words, specific, no clickbait),
"dek" (one sentence summary),
"outline" (array of ${outlineFirst?'4-6':'3-4'} short section labels),
"body" (array of ${paras} paragraph strings, plain text),
"slug" (lowercase-hyphenated),
"meta" (<=155 char SEO description).`;

    let parsed = null;
    if(llmOn){
      try{
        const raw = await window.claude.complete(prompt);
        const clean = String(raw).replace(/```json|```/g,'').trim();
        const s = clean.indexOf('{'), e = clean.lastIndexOf('}');
        parsed = JSON.parse(clean.slice(s, e+1));
        if(!parsed.headline || !parsed.body) throw new Error('thin');
        setGenNote('Drafted with Claude · review required before publish');
      }catch(err){
        parsed = null;
        setGenErr('Live model unavailable · used scripted draft. '+(err.message||''));
      }
    }
    if(!parsed) parsed = scriptedDraft({topic,desk,city,tone,length,notes});

    const dd = window.deDash || (s=>s);
    setHeadline(dd(parsed.headline||''));
    setKicker(dd(parsed.kicker || (tone==='Opinion'?'OPINION':tone==='Explainer'?'EXPLAINER':'')));
    setDek(dd(parsed.dek||''));
    setOutline(Array.isArray(parsed.outline)?parsed.outline:[]);
    setBody((Array.isArray(parsed.body)?parsed.body:[String(parsed.body||'')]).map(x=>'<p>'+dd(x)+'</p>').join(''));
    setSlug(parsed.slug || (parsed.headline||'untitled').toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'').slice(0,60));
    setMeta(parsed.meta || parsed.dek || '');
    setCites(suggestCites());
    if(!llmOn) setGenNote('Scripted draft · live model not detected in this environment');
    setView('draft');
  }

  function makePiece(stage){
    const id = editingId || ('OR-' + (212 + pieces.filter(p=>p.id.startsWith('OR-2')).length));
    return { id, stage, desk, city, tone, topic, notes, headline, dek, outline, body, slug, meta, rights, sponsor, cites,
      byline, pub:pubName, kicker, img, focal, caption,
      schedAt: stage==='scheduled'?schedAt:null,
      lead: stage!=='draft' && lead, editor: (window.OPERATOR?window.OPERATOR.initials:'MW'),
      updated: new Date().toLocaleString('en-US',{month:'short',day:'numeric'}), words, source: llmOn?'ai':'staff' };
  }
  function upsert(piece){
    const exists = pieces.some(x=>x.id===piece.id);
    const rest = (exists ? pieces.map(x=>x.id===piece.id?piece:x) : [piece, ...pieces]).map(x=>piece.lead && x.id!==piece.id ? {...x,lead:false} : x);
    setPieces(rest);
  }
  function finalize(){
    const stage = when==='now' ? 'published' : 'scheduled';
    upsert(makePiece(stage));
    setView('done');
  }
  function saveDraft(){
    const piece = makePiece('draft');
    upsert(piece);
    setEditingId(piece.id);
    setSavedNote(true); setTimeout(()=>setSavedNote(false), 3000);
  }
  function removePiece(id){
    setPieces(pieces.filter(x=>x.id!==id));
    if(editingId===id) reset();
  }

  return (
    <AdminShell route="studio" setRoute={setRoute} title="Editorial studio" breadcrumb="CONTENT · TUEPAC ORIGINALS"
      actions={<>
        <span className="pill muted" style={{marginRight:2}}>
          <span className="d" style={{background:llmOn?'#1f8a5b':'var(--gold-2)'}}></span>{llmOn?'AI ASSIST ON':'SCRIPTED MODE'}
        </span>
        <button className="btn gh" onClick={()=>setLlmOn(v=>!v)}>{llmOn?'Use scripted':'Use AI'}</button>
        <button className="btn g" onClick={()=>{reset();}}>+ New original</button>
      </>}>

      <div className="split-4" style={{marginBottom:18}}>
        <Stat n={String(pieces.length)} l="Pieces in studio" d="originals only"/>
        <Stat n={String(pieces.filter(p=>p.stage==='scheduled').length)} l="In queue · scheduled" d="timed releases"/>
        <Stat n={String(pieces.filter(p=>p.stage==='review'||p.stage==='draft').length)} l="Drafts · in progress" d="saved in studio" up={false}/>
        <Stat n={String(pieces.filter(p=>p.stage==='published').length)} l="Originals live" d="published"/>
      </div>

      <div className="lay2" style={{display:'grid',gridTemplateColumns:'300px 1fr',gap:18,alignItems:'flex-start'}}>
        <Card title="Originals" meta={`${pieces.length}`}>
          <div style={{display:'flex',flexDirection:'column'}}>
            {!pieces.length && <div className="mono" style={{padding:'14px 0',fontSize:9.5,letterSpacing:'.1em',color:'var(--mute)'}}>NO PIECES YET · DRAFTS AND SCHEDULED STORIES QUEUE HERE</div>}
            {[...pieces].sort((a,b)=>{
              const r = {scheduled:0, draft:1, review:1, published:2};
              if(r[a.stage]!==r[b.stage]) return r[a.stage]-r[b.stage];
              if(a.stage==='scheduled' && b.stage==='scheduled') return String(a.schedAt||'').localeCompare(String(b.schedAt||''));
              return 0;
            }).map(p=>{
              const [k,lbl] = stageMeta(p.stage);
              const isOpen = editingId===p.id;
              return (
                <div key={p.id} style={{padding:'10px 0',borderBottom:'1px solid var(--rule-line)',display:'flex',flexDirection:'column',gap:5,background:isOpen?'var(--canvas)':'transparent',margin:isOpen?'0 -8px':'0',paddingLeft:isOpen?8:0,paddingRight:isOpen?8:0}}>
                  <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',gap:8}}>
                    <span className="mono" style={{fontSize:9.5,color:'var(--mute)',letterSpacing:'.06em'}}>{p.id} · {p.desk.toUpperCase()}</span>
                    <span style={{display:'flex',gap:4}}>{p.lead && <Pill k="bad">LEAD</Pill>}<Pill k={k}>{p.stage==='scheduled'?fmtSched(p.schedAt):lbl}</Pill></span>
                  </div>
                  <div className="serif" style={{fontSize:14.5,fontWeight:700,lineHeight:1.18,letterSpacing:'-.005em',textWrap:'pretty'}}>{p.headline}</div>
                  <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',gap:8}}>
                    <span className="mono" style={{fontSize:9.5,color:'var(--mute)',letterSpacing:'.04em'}}>{p.source==='ai'?'\u2726 AI ':'\u270e '}{p.editor} · {p.words}w · {p.updated}</span>
                    <span style={{display:'flex',gap:6}}>
                      {p.stage!=='published' && <button className="btn gh s" onClick={()=>openPiece(p)} style={{padding:'2px 8px',fontSize:10}}>{isOpen?'Editing…':'Open'}</button>}
                      {p.stage!=='published' && <button className="btn gh s" onClick={()=>removePiece(p.id)} style={{padding:'2px 8px',fontSize:10,color:'var(--mute)'}}>×</button>}
                    </span>
                  </div>
                </div>
              );
            })}
          </div>
        </Card>

        <div>
          <StudioRail view={view}/>
          {view==='brief' && (
            <Card title="Story brief" meta="define the assignment"
              actions={<button className="btn k" onClick={generate} disabled={!topic.trim()} style={{opacity:topic.trim()?1:.4}}>{outlineFirst?'Generate outline + draft →':'Generate draft →'}</button>}>
              <div className="eyebrow" style={{marginBottom:6}}>TOPIC / ANGLE</div>
              <textarea value={topic} onChange={e=>setTopic(e.target.value)} placeholder="e.g. What the new CDFI lending rules actually change for Black-owned small businesses · eligibility, timeline, and who decides"
                style={studioInp(64)}/>
              <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:14,marginTop:14}}>
                <div>
                  <div className="eyebrow" style={{marginBottom:6}}>TOPIC</div>
                  <select value={desk} onChange={e=>setDesk(e.target.value)} style={studioInp()}>{SECTIONS.map(d=><option key={d}>{d}</option>)}</select>
                </div>
                <div>
                  <div className="eyebrow" style={{marginBottom:6}}>LOCATION FOCUS <span style={{color:'var(--mute)',letterSpacing:'.04em',textTransform:'none'}}>· optional</span></div>
                  <input value={city} onChange={e=>setCity(e.target.value)} placeholder="e.g. Atlanta · National" style={studioInp()}/>
                </div>
              </div>
              <div style={{display:'flex',gap:24,marginTop:14,flexWrap:'wrap'}}>
                <div>
                  <div className="eyebrow" style={{marginBottom:6}}>TREATMENT</div>
                  <Seg value={tone} onChange={setTone} options={['Reported','Analysis','Opinion','Explainer']}/>
                </div>
                <div>
                  <div className="eyebrow" style={{marginBottom:6}}>LENGTH</div>
                  <Seg value={length} onChange={setLength} options={['Brief','Standard','Feature']}/>
                </div>
              </div>
              <div className="eyebrow" style={{margin:'14px 0 6px'}}>SOURCE NOTES / FACTS TO INCLUDE <span style={{color:'var(--mute)',letterSpacing:'.04em',textTransform:'none'}}>· optional</span></div>
              <textarea value={notes} onChange={e=>setNotes(e.target.value)} placeholder="Paste figures, quotes, links, or publisher reports the writer should ground the piece in."
                style={studioInp(56)}/>
              <label style={{display:'flex',alignItems:'center',gap:8,marginTop:14,cursor:'default',fontSize:12}}>
                <input type="checkbox" checked={outlineFirst} onChange={e=>setOutlineFirst(e.target.checked)}/>
                Build a section outline before the full draft
              </label>
              <div style={{marginTop:14,padding:'10px 12px',background:'var(--paper)',border:'1px solid var(--rule-line)',fontSize:11.5,color:'var(--ink-2)',lineHeight:1.5}}>
                <span className="mono" style={{fontSize:9,letterSpacing:'.14em',color:'var(--mute)'}}>EDITORIAL POLICY</span><br/>
                AI drafts are <b>internal assists only</b>. Nothing publishes without an editor's review · every original carries a human byline, disclosure, and the TUEPAC standards check.
              </div>
            </Card>
          )}

          {view==='generating' && (
            <Card title="Drafting" meta={llmOn?'claude-haiku':'scripted'}>
              <div style={{padding:'30px 0',textAlign:'center'}}>
                <div className="mono" style={{fontSize:10.5,letterSpacing:'.18em',color:'var(--mute)',textTransform:'uppercase'}}>{llmOn?'Generating draft from your brief…':'Composing scripted draft…'}</div>
                <div style={{marginTop:18,display:'flex',flexDirection:'column',gap:8,maxWidth:520,marginInline:'auto'}}>
                  {[88,72,94,64,80].map((w,i)=><div key={i} style={{height:9,width:w+'%',background:'linear-gradient(90deg,var(--rule-line),var(--canvas))',animation:`stpulse 1.1s ${i*0.12}s ease-in-out infinite`}}/>) }
                </div>
              </div>
            </Card>
          )}

          {view==='draft' && (
            <window.DraftEditor {...{headline,setHeadline,dek,setDek,body,setBody,slug,setSlug,meta,setMeta,
              rights,setRights,sponsor,setSponsor,cites,setCites,desk,setDesk,city,tone,words,genNote,genErr,llmOn,
              pubName,setPubName,
              kicker,setKicker,byline,setByline,img,setImg,focal,setFocal,caption,setCaption,savedNote,
              onSaveDraft:saveDraft,onRegen:generate,onBack:()=>setView('brief'),onNext:()=>setView('publish')}}/>
          )}

          {view==='publish' && (
            <PublishPanel {...{headline,dek,kicker,byline,pubName,desk,city,rights,sponsor,slug,words,cites,when,setWhen,schedAt,setSchedAt,toNL,setToNL,nlPick,setNlPick,
              lead,setLead,img,focal,caption,
              onBack:()=>setView('draft'),onPublish:finalize}}/>
          )}

          {view==='done' && (
            <Card title="Published" meta={when==='now'?'live now':'scheduled'}>
              <div style={{padding:'18px 0 8px',display:'flex',gap:16,alignItems:'flex-start'}}>
                <div style={{width:44,height:44,flex:'0 0 auto',background:'var(--green)',color:'var(--ivory)',display:'flex',alignItems:'center',justifyContent:'center',fontSize:22,fontWeight:700}}>✓</div>
                <div>
                  <div className="serif" style={{fontSize:22,fontWeight:700,letterSpacing:'-.01em',lineHeight:1.12,textWrap:'pretty'}}>{headline}</div>
                  <div className="mono" style={{fontSize:10.5,color:'var(--mute)',letterSpacing:'.06em',marginTop:8}}>
                    {when==='now'?'PUBLISHED · LIVE NOW':'SCHEDULED · '+fmtSched(schedAt)} · {desk.toUpperCase()}{city.trim()?' · '+city.trim().toUpperCase():''} · {pubName.toUpperCase()} · {rights.toUpperCase()}
                  </div>
                  {toNL && <div className="mono" style={{fontSize:10.5,color:'var(--green)',letterSpacing:'.06em',marginTop:5}}>✓ QUEUED FOR “{nlPick}”</div>}
                  <div style={{display:'flex',gap:8,marginTop:16}}>
                    <button className="btn g" onClick={reset}>+ Draft another</button>
                    <button className="btn gh" onClick={()=>setRoute('desk')}>Open content desk →</button>
                  </div>
                </div>
              </div>
            </Card>
          )}
        </div>
      </div>

      <style>{`@keyframes stpulse{0%,100%{opacity:.45}50%{opacity:1}}`}</style>
    </AdminShell>
  );
}

function StudioRail({view}){
  const steps = [['brief','Brief'],['generating','Generate'],['draft','Draft & edit'],['publish','Publish']];
  const order = ['brief','generating','draft','publish','done'];
  const cur = order.indexOf(view);
  return (
    <div style={{display:'flex',alignItems:'center',gap:0,marginBottom:14}}>
      {steps.map(([k,lbl],i)=>{
        const idx = order.indexOf(k);
        const active = view===k || (view==='done'&&k==='publish');
        const done = idx < cur;
        return (
          <React.Fragment key={k}>
            <div style={{display:'flex',alignItems:'center',gap:7}}>
              <span style={{width:20,height:20,display:'flex',alignItems:'center',justifyContent:'center',fontFamily:'var(--mono)',fontSize:10,fontWeight:600,
                background:active?'var(--black)':done?'var(--green)':'var(--bg)',color:active||done?'var(--ivory)':'var(--mute)',border:'1px solid '+(active?'var(--black)':done?'var(--green)':'var(--rule-line)')}}>{done?'✓':i+1}</span>
              <span className="mono" style={{fontSize:10,letterSpacing:'.1em',textTransform:'uppercase',color:active?'var(--ink)':'var(--mute)',fontWeight:active?600:400}}>{lbl}</span>
            </div>
            {i<steps.length-1 && <div style={{flex:'0 0 28px',height:1,background:'var(--rule-line)',margin:'0 10px'}}/>}
          </React.Fragment>
        );
      })}
    </div>
  );
}

function PublishPanel(p){
  const nls = (window.NEWSLETTERS||[]).map(n=>n.name);
  return (
    <Card title="Review & publish" meta="final check"
      actions={<>
        <button className="btn gh" onClick={p.onBack}>← Back to draft</button>
        <button className="btn g" onClick={p.onPublish} disabled={p.when==='schedule'&&!p.schedAt} style={{opacity:(p.when==='schedule'&&!p.schedAt)?.4:1}}>{p.when==='now'?'Publish now':'Schedule'} →</button>
      </>}>
      <div className="lay2" style={{display:'grid',gridTemplateColumns:'1fr 240px',gap:20,alignItems:'flex-start'}}>
        <div>
          {p.img && <div style={{aspectRatio:'16/9',overflow:'hidden',marginBottom:12}}><img src={p.img.src} alt="" style={{width:'100%',height:'100%',objectFit:'cover',objectPosition:p.focal.x+'% '+p.focal.y+'%'}}/></div>}
          <div className="mono" style={{fontSize:9.5,letterSpacing:'.14em',color:'var(--mute)'}}>{(p.kicker||'TUEPAC ORIGINAL').toUpperCase()} · {p.desk.toUpperCase()}{String(p.city||'').trim()?' · '+p.city.trim().toUpperCase():''}</div>
          <div className="serif" style={{fontSize:28,fontWeight:700,letterSpacing:'-.012em',lineHeight:1.05,margin:'8px 0 8px',textWrap:'pretty'}}>{p.headline}</div>
          <div className="serif" style={{fontSize:15,fontStyle:'italic',color:'var(--ink-2)',lineHeight:1.4,textWrap:'pretty'}}>{p.dek}</div>
          <div className="mono" style={{fontSize:10,color:'var(--mute)',letterSpacing:'.08em',marginTop:6}}>BY {String(p.byline||'').toUpperCase()} · {String(p.pubName||'').toUpperCase()}{p.caption?' · IMAGE CAPTIONED':''}</div>
          <div style={{display:'flex',gap:8,marginTop:14,flexWrap:'wrap'}}>
            <Pill k="k">{p.rights==='Sponsored'?'SPONSORED · '+(p.sponsor||'sponsor'):'ORIGINAL'}</Pill>
            <Pill k="muted">{p.words} WORDS</Pill>
            <Pill k="muted">/{(window.slugify||((s)=>String(s).toLowerCase()))(p.desk)}/{p.slug}</Pill>
            {p.cites.map(id=>{const pub=window.PUB_BY_ID[id]; if(!pub) return null; return <Pill key={id} k="info">CITES {pub.short}</Pill>;})}
          </div>
          <div style={{marginTop:16,paddingTop:14,borderTop:'1px solid var(--rule-line)'}}>
            <div className="eyebrow" style={{marginBottom:8}}>STANDARDS CHECK</div>
            {[['Human editor assigned','ok'],['Byline + disclosure set','ok'],['Hero image set', p.img?'ok':'warn'],['Publication + topic set', p.pubName?'ok':'warn'],['No unverified claims flagged','ok'],['Canonical + slug set','ok']].map(([k,c])=>(
              <div key={k} style={{display:'grid',gridTemplateColumns:'auto 1fr',gap:8,padding:'3px 0',alignItems:'center'}}>
                <span style={{width:14,textAlign:'center',color:c==='ok'?'var(--green)':'var(--gold-2)',fontSize:12}}>{c==='ok'?'✓':'!'}</span>
                <span style={{fontSize:12}}>{k}</span>
              </div>
            ))}
          </div>
        </div>
        <div style={{display:'flex',flexDirection:'column',gap:12}}>
          <div>
            <div className="eyebrow" style={{marginBottom:6}}>TIMING</div>
            <Seg value={p.when} onChange={p.setWhen} options={['now','schedule']}/>
            {p.when==='schedule' && (
              <div style={{marginTop:8}}>
                <input type="datetime-local" value={p.schedAt} onChange={e=>p.setSchedAt(e.target.value)} style={studioInp()}/>
                <div className="mono" style={{fontSize:9,letterSpacing:'.08em',color:'var(--mute)',marginTop:5}}>{p.schedAt?('GOES LIVE '+fmtSched(p.schedAt)):'PICK A DATE AND TIME'}</div>
              </div>
            )}
          </div>
          <label style={{display:'flex',alignItems:'center',gap:8,fontSize:12,cursor:'default',fontWeight:700}}>
            <input type="checkbox" checked={p.lead} onChange={e=>p.setLead(e.target.checked)}/>
            Set as lead story (homepage hero)
          </label>
          {p.lead && <div className="mono" style={{fontSize:9,letterSpacing:'.08em',color:'var(--gold-2)',marginTop:-6}}>ONLY ONE LEAD AT A TIME · THE CURRENT LEAD IS DEMOTED</div>}
          <label style={{display:'flex',alignItems:'center',gap:8,fontSize:12,cursor:'default'}}>
            <input type="checkbox" checked={p.toNL} onChange={e=>p.setToNL(e.target.checked)}/>
            Add to a newsletter
          </label>
          {p.toNL && (
            <select value={p.nlPick} onChange={e=>p.setNlPick(e.target.value)} style={studioInp()}>{nls.map(n=><option key={n}>{n}</option>)}</select>
          )}
          <div style={{padding:'10px 12px',background:'var(--paper)',border:'1px solid var(--rule-line)',fontSize:11,color:'var(--ink-2)',lineHeight:1.5}}>
            Publishing posts this original to the public site under <b>{p.pubName}</b> in the {p.desk} topic{String(p.city||'').trim()?', tagged '+p.city.trim():''}.
          </div>
        </div>
      </div>
    </Card>
  );
}

function scriptedDraft({topic,desk,city,tone,length,notes}){
  const t = topic.trim().replace(/\.$/,'');
  const loc = String(city||'').trim();
  const cityTag = loc? `in ${loc}` : 'across the network';
  const lead = tone==='Opinion'
    ? `The debate over ${stLc(t)} ${cityTag} is really a debate about who gets counted when the money moves.`
    : tone==='Explainer'
    ? `Here is a plain-language look at ${stLc(t)}: what it is, who it touches ${cityTag}, and what happens next.`
    : `A closer look at ${stLc(t)} shows a story that is bigger ${cityTag} than the headline numbers suggest.`;
  const paras = [
    lead,
    `${loc||'Community'} organizers and Black-owned outlets have tracked this for months, and the through-line is access: who is at the table, who sees the filing first, and who is left to read about it after the vote.`,
    notes.trim()? `Records and reporting provided to TUEPAC, ${stTrim(notes,180)}, sharpen the picture and point to the next decision point.` : `TUEPAC's ${desk.toLowerCase()} desk is requesting the underlying records to confirm the figures before they harden into conventional wisdom.`,
    `For readers, the practical question is simple: does this change what a family, a small business, or a congregation can actually do this year? Early signs suggest the answer depends on follow-through, not announcements.`,
    `What to watch: the timeline, the eligibility rules, and whether the institutions involved report results in public, the kind of accountability the Black press ${cityTag} has always supplied.`,
  ];
  if(length==='Feature'){
    paras.splice(3,0,`Context matters here. The pattern ${cityTag} echoes earlier rounds, when promises outpaced delivery and community outlets were the ones that kept the receipts.`);
    paras.push(`TUEPAC will update this original as publishers and writers in the network file their own reporting and as the named institutions respond.`);
  }
  if(length==='Brief') paras.length = 3;
  return {
    kicker: tone==='Opinion'?'Opinion':tone==='Explainer'?'Explainer':tone==='Analysis'?'Analysis':desk,
    headline: stCap(tone==='Opinion'?`${stCap(stLc(t))}: the question we keep dodging`:`${stCap(stLc(t))}, explained${loc?' for '+loc:''}`),
    dek: `${stCap(tone.toLowerCase())} from the TUEPAC ${desk} desk on ${stLc(t)} ${cityTag}.`,
    outline: ['The lede','Why it matters','What the records show','Who it touches','What to watch'].slice(0,length==='Brief'?3:5),
    body: paras,
    slug: t.toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'').slice(0,60),
    meta: `TUEPAC ${desk} desk: ${stTrim(t,110)}, reported ${cityTag} with credit to the Black-owned publishers and writers covering it.`,
  };
}
function stLc(s){ return s.charAt(0).toLowerCase()+s.slice(1); }
function stCap(s){ return s.charAt(0).toUpperCase()+s.slice(1); }
function stTrim(s,n){ s=s.replace(/\s+/g,' ').trim(); return s.length>n?s.slice(0,n)+'…':s; }

window.EditorialStudio = EditorialStudio;
