// outreach-sequences.jsx — WS2: dynamic, editable, branching sequence builder.
// Every touch routes on the contact's RESPONSE; the goal is always "get on a call".
const { useState: useStateSeq, useEffect: useEffectSeq, useRef: useRefSeq } = React;
const RSseq = window.RaiseShell;

// ── shared bits (exported for composer + vault) ───────────────────
function ChTag({ id, withLabel }){
  const c = window.OX.ch(id);
  return (
    <span className="chx" style={{ color:c.color, background:c.tint }}>
      <span className="gx" style={{ background:c.color }}>{c.glyph}</span>{withLabel?c.label:c.short}
    </span>
  );
}

function ChannelPicker({ value, onPick }){
  const [open, setOpen] = useStateSeq(false);
  const OX = window.OX;
  return (
    <div className="chpick-wrap">
      <button type="button" onClick={(e)=>{ e.stopPropagation(); setOpen(o=>!o); }} title="Change channel" style={{border:'none',background:'none',padding:0,cursor:'pointer'}}>
        <ChTag id={value} />
      </button>
      {open && (
        <>
          <div className="combo-back" onClick={()=>setOpen(false)} />
          <div className="chpick-menu" onClick={e=>e.stopPropagation()}>
            {OX.CH_ORDER.map(cid=>(
              <button key={cid} onClick={()=>{ onPick(cid); setOpen(false); }}>
                <ChTag id={cid} withLabel /> {value===cid && <span style={{marginLeft:'auto',color:'var(--green)'}}>✓</span>}
              </button>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

function RouteSelect({ value, options, onChange }){
  const OX = window.OX;
  const node = OX.NODES[value] || OX.NODES.next;
  return (
    <span className="routesel" style={{ color:node.color }}>
      <select value={value} onChange={e=>onChange(e.target.value)}
        style={{ color:node.color, background: node.color+'1c' }}>
        {options.map(o=> <option key={o} value={o} style={{color:'var(--ink)',background:'var(--surface)'}}>{OX.NODES[o].label}</option>)}
      </select>
    </span>
  );
}

// ── shared library picker (used by sequence steps + today's queue) ──
function ScriptPicker({ onPick, onClose, title }){
  const S = window.OX.Store;
  const [,bump] = useStateSeq(0);
  useEffectSeq(()=> S.subscribe(()=>bump(x=>x+1)), []);
  const scripts = S.scripts();
  return (
    <>
      <div className="combo-back" onClick={onClose} />
      <div className="scriptpick-menu" onClick={e=>e.stopPropagation()}>
        <div className="spk-hd">{title||'Pull from library'}</div>
        <div className="spk-list scroll">
          {scripts.map(s=>(
            <button key={s.id} className="spk-opt" onClick={()=>{ onPick(s); onClose(); }}>
              <span className="spk-cat">{s.cat}</span>
              <span className="spk-nm">{s.name}<small>{s.use||s.blurb||''}</small></span>
            </button>
          ))}
          {scripts.length===0 && <div className="muted" style={{padding:12,fontSize:12}}>No saved scripts yet — add one in Outreach › Scripts.</div>}
        </div>
      </div>
    </>
  );
}

// ── the editable message script attached to a single step ────────
function StepScript({ seq, step }){
  const OX = window.OX, S = OX.Store;
  const sc = step.script || null;
  const [picking, setPicking] = useStateSeq(false);
  const [open, setOpen] = useStateSeq(false);
  const write  = ()=>{ S.patchStep(seq.id, step.id, { script:{ name:'Custom script', body:'' } }); setOpen(true); };
  const pull   = (s)=>{ S.patchStep(seq.id, step.id, { script:{ id:s.id, name:s.name, body: OX.scriptText(s, null) } }); setOpen(true); };
  const clear  = ()=>{ S.patchStep(seq.id, step.id, { script:null }); };
  const setBody= (body)=>{ S.patchStep(seq.id, step.id, { script:{ ...(step.script||{}), body } }); };

  if(!sc){
    return (
      <div className="stepscript empty">
        <span className="sscr-k">Script</span>
        <span className="sscr-none">No message attached</span>
        <div className="sscr-acts">
          <button className="sscr-btn" onClick={write}>✎ Write</button>
          <div className="chpick-wrap">
            <button className="sscr-btn" onClick={()=>setPicking(true)}>ⓧ Pull from library</button>
            {picking && <ScriptPicker onPick={pull} onClose={()=>setPicking(false)} />}
          </div>
        </div>
      </div>
    );
  }
  return (
    <div className="stepscript">
      <div className="sscr-top">
        <span className="sscr-k">Script</span>
        <span className="sscr-name">{sc.id && <span className="sscr-lib">ⓧ library</span>}{sc.name||'Custom script'}</span>
        <div className="sscr-acts">
          <button className="sscr-btn" onClick={()=>setOpen(o=>!o)}>{open?'Collapse':'Edit'}</button>
          <div className="chpick-wrap">
            <button className="sscr-btn" onClick={()=>setPicking(true)}>Replace</button>
            {picking && <ScriptPicker onPick={pull} onClose={()=>setPicking(false)} />}
          </div>
          <button className="sscr-btn del" onClick={clear} title="Detach script">Clear</button>
        </div>
      </div>
      {open && (
        <textarea className="sscr-body" defaultValue={sc.body} placeholder="Write the message for this touch… use {first}, {firm}, {commonality}…"
          onBlur={e=>setBody(e.target.value)} />
      )}
      {!open && <div className="sscr-preview">{(sc.body||'').slice(0,120)||'Empty — click Edit to write it.'}{(sc.body||'').length>120?'…':''}</div>}
    </div>
  );
}

// ── one step in the spine ─────────────────────────────────────────
function SeqStep({ seq, step, idx, total }){
  const OX = window.OX, S = OX.Store;
  const c = OX.ch(step.ch);
  const [editing, setEditing] = useStateSeq(false);
  const perf = OX.stepPerf(step);
  const rules = OX.ruleChips(step);
  const commit = (label)=>{ S.patchStep(seq.id, step.id, { label }); setEditing(false); };
  return (
    <div className={'seqstep'+(idx===total-1?' last':'')}>
      <div className="rail">
        <div className="knob" style={{ background:c.color }}>{idx+1}</div>
        <div className="line" />
      </div>
      <div className={'stepcard'+(editing?' editing':'')}>
        <div className="sc-top">
          <ChannelPicker value={step.ch} onPick={(ch)=>S.patchStep(seq.id, step.id, { ch })} />
          {idx>0 && (
            <span className="sc-wait" title="Days after previous touch">
              wait <input type="number" min="0" max="120" value={step.wait}
                onChange={e=>S.patchStep(seq.id, step.id, { wait: Math.max(0,+e.target.value||0) })}
                style={{width:30,border:'none',background:'none',font:'inherit',color:'var(--ink)',textAlign:'right'}} />d
            </span>
          )}
          {idx===0 && <span className="sc-wait">Day 0</span>}
          {editing
            ? <input autoFocus className="efinp" defaultValue={step.label} style={{flex:1}}
                onBlur={e=>commit(e.target.value)} onKeyDown={e=>{ if(e.key==='Enter') commit(e.target.value); if(e.key==='Escape') setEditing(false); }} />
            : <div className="sc-label" onClick={()=>setEditing(true)} title="Click to edit">{step.label}</div>}
          <div className="stepperf">
            <div className="sp"><div className="v">{perf.primary}</div><div className="k">{perf.primaryK}</div></div>
            {perf.secondaryK && <div className="sp"><div className="v">{perf.secondary}</div><div className="k">{perf.secondaryK}</div></div>}
          </div>
          <div className="sc-tools">
            <button className="sc-tool" title="Move up" disabled={idx===0} onClick={()=>S.moveStep(seq.id, step.id, -1)}>↑</button>
            <button className="sc-tool" title="Move down" disabled={idx===total-1} onClick={()=>S.moveStep(seq.id, step.id, 1)}>↓</button>
            <button className="sc-tool del" title="Delete step" onClick={()=>S.removeStep(seq.id, step.id)}>✕</button>
          </div>
        </div>
        {rules.length>0 && (
          <div className="steprules">
            {rules.map((r,i)=> <span key={i} className={'rulechip'+(/Exits/.test(r)?' exit':/Skips/.test(r)?' skip':'')}>{r}</span>)}
          </div>
        )}
        <div className="branches">
          <div className="brow">
            <span className="bcond"><span className="bdot" style={{background:'var(--green)'}} /><b>If they reply</b></span>
            <span className="barrow">→</span>
            <RouteSelect value={step.reply} options={OX.REPLY_TARGETS} onChange={v=>S.patchStep(seq.id, step.id, { reply:v })} />
          </div>
          <div className="brow">
            <span className="bcond"><span className="bdot" style={{background:'var(--ink-3)'}} /><b>No reply</b> <small>in {step.wait||0}d</small></span>
            <span className="barrow">→</span>
            <RouteSelect value={step.none} options={OX.NONE_TARGETS} onChange={v=>S.patchStep(seq.id, step.id, { none:v })} />
          </div>
        </div>
        <StepScript seq={seq} step={step} />
      </div>
    </div>
  );
}

// ── the sequence canvas (right pane) ──────────────────────────────
function SeqCanvas({ seq, onRuntime, onEnroll }){
  const OX = window.OX, S = OX.Store, R = window.RAISE;
  const enrolled = OX.contactsFor(seq.id);
  const days = seq.steps.reduce((a,s,i)=> a + (i===0?0:(s.wait||0)), 0);
  const awaiting = enrolled.filter(c=> OX.enrollStatus(c).key==='await');
  const renaming = useRefSeq(null);
  return (
    <div className="seqcanvas scroll">
      <div className="seqcanvas-hd">
        <div className="stag2">{seq.id}</div>
        <div style={{flex:1,minWidth:0}}>
          <div className="stitle">
            <input defaultValue={seq.name} key={seq.id+seq.name} ref={renaming}
              onBlur={e=>S.patchSeq(seq.id,{name:e.target.value})}
              onKeyDown={e=>e.key==='Enter'&&e.target.blur()}
              style={{font:'inherit',fontWeight:600,fontSize:17,border:'none',background:'none',color:'var(--ink)',width:'100%',padding:0}} />
          </div>
          <div className="ssub">{seq.icp} · {seq.tone}</div>
        </div>
        <button className="btn primary sm" onClick={()=>onEnroll(null)}>＋ Enroll a contact</button>
        <button className="btn sm" onClick={()=>{ if(confirm('Reset all sequences to the seeded templates?')) S.reset(); }}>Reset</button>
      </div>

      <div className="ox-goal" style={{marginTop:14}}>
        <span className="gt">◎</span>
        <span><b>Goal:</b> {seq.goal}. Every branch routes toward this — a booked call exits the sequence as a win.</span>
      </div>

      <div className="enroll-crit">
        <span className="ec-k">Auto-enrolls</span>
        <span className="mono">{seq.enrollCriteria || '—'}</span>
      </div>

      {awaiting.length>0 && (
        <div className="approve-nudge">
          <span>✎ <b>{awaiting.length} draft{awaiting.length>1?'s':''}</b> awaiting your review on this sequence.</span>
          <button className="an-go" onClick={()=>onRuntime(awaiting[0])}>Review →</button>
        </div>
      )}

      <div className="seq-stat">
        <div className="ss"><div className="ssk">Enrolled</div><div className="ssv">{enrolled.length}</div></div>
        <div className="ss"><div className="ssk">Reply rate</div><div className="ssv">{seq.replyRate}<span style={{fontSize:12,color:'var(--ink-3)'}}>%</span></div></div>
        <div className="ss meet"><div className="ssk">Meetings</div><div className="ssv">{seq.meetings}</div></div>
        <div className="ss"><div className="ssk">Avg reply</div><div className="ssv">{seq.avgReply}<span style={{fontSize:12,color:'var(--ink-3)'}}>d</span></div></div>
        <div className="ss"><div className="ssk">Span</div><div className="ssv">{days}<span style={{fontSize:12,color:'var(--ink-3)'}}>d</span></div></div>
      </div>

      <div className="spine">
        {seq.steps.map((st,i)=>(
          <SeqStep key={st.id} seq={seq} step={st} idx={i} total={seq.steps.length} />
        ))}
        <button className="addstep" onClick={()=>S.addStep(seq.id)}>＋ Add a touch</button>

        <div style={{paddingLeft:48,display:'flex',flexDirection:'column',gap:9}}>
          <div className="endnode goal">
            <span className="en-ic">✓</span>
            <div><div className="en-t">Call booked — goal reached</div><div className="en-s">Contact exits the sequence. Logged to the timeline; first-call agenda queued in Today’s Focus.</div></div>
          </div>
          <div className="endnode off">
            <span className="en-ic">≈</span>
            <div><div className="en-t">No reply after the last touch → Nurture</div><div className="en-s">A pass is a “not now.” Drops into the Nurture track — 3–4 light value touches a year.</div></div>
          </div>
        </div>
      </div>

      {enrolled.length>0 && (
        <div className="enrolled-strip">
          <div className="enr-h">Enrolled · {enrolled.length} <span style={{fontWeight:400,textTransform:'none',letterSpacing:0}}>· click a contact for the runtime view</span></div>
          <div className="enr-grid">
            {enrolled.map(c=>{
              const stt = OX.enrollStatus(c);
              const m = /(\d+)\s*of\s*(\d+)/i.exec(c.step||'');
              const pct = m ? Math.round(+m[1]/+m[2]*100) : 100;
              return (
                <button key={c.id} className={'enr-row '+stt.key} onClick={()=>onRuntime(c)}>
                  <RSseq.Avatar name={c.name} anchor={c.anchor} />
                  <div className="erm">
                    <div className="ern">{c.name}</div>
                    <div className="ers">{c.step || c.firm}</div>
                  </div>
                  <span className="enr-prog track"><i style={{width:pct+'%',background:stt.color}} /></span>
                  <span className="erstat" style={{color:stt.color}}><span className="erdot" style={{background:stt.color}} />{stt.label}</span>
                </button>
              );
            })}
          </div>
        </div>
      )}
    </div>
  );
}

// ── left list + canvas ────────────────────────────────────────────
function OXSequences(){
  const OX = window.OX;
  const seqs = (function(){ const [,f]=useStateSeq(0); useEffectSeq(()=>OX.Store.subscribe(()=>f(x=>x+1)),[]); return OX.Store.seqs(); })();
  const [selId, setSelId] = useStateSeq(seqs[0]?.id);
  const [sortBy, setSortBy] = useStateSeq('reply');
  const [runtime, setRuntime] = useStateSeq(null);   // contact for runtime view
  const [enroll, setEnroll] = useStateSeq(false);     // enrollment modal open
  const sel = seqs.find(s=>s.id===selId) || seqs[0];
  const ordered = seqs.slice().sort((a,b)=> sortBy==='meetings' ? b.meetings-a.meetings : sortBy==='reply' ? b.replyRate-a.replyRate : 0);
  return (
    <div className="panes">
      <div className="pane" style={{width:316,flex:'none'}}>
        <div className="pane-hd">Sequences <button className="btn ghost sm" onClick={()=>{ const id=OX.Store.addSeq(); setSelId(id); }}>＋ New</button></div>
        <div style={{display:'flex',gap:6,padding:'10px 18px 0',alignItems:'center'}}>
          <span style={{fontSize:11,color:'var(--ink-3)'}}>Sort</span>
          <div className="mode-seg" style={{flex:'none'}}>
            <button className={sortBy==='reply'?'on':''} onClick={()=>setSortBy('reply')}>Reply %</button>
            <button className={sortBy==='meetings'?'on':''} onClick={()=>setSortBy('meetings')}>Meetings</button>
          </div>
        </div>
        <div className="pane-body scroll">
          {ordered.map(s=>{
            const chans = [...new Set(s.steps.map(st=>st.ch))];
            return (
              <div key={s.id} className={'seqcard'+(sel.id===s.id?' on':'')} onClick={()=>setSelId(s.id)}>
                <div className="sh">
                  <div className="stag">{s.id}</div>
                  <div style={{flex:1,minWidth:0}}><div className="sn">{s.name}</div><div className="si">{s.icp}</div></div>
                </div>
                <div style={{display:'flex',gap:4,marginTop:9,flexWrap:'wrap'}}>
                  {chans.map(cid=> <ChTag key={cid} id={cid} />)}
                </div>
                <div className="smeta">
                  <span>{s.steps.length} steps</span>
                  <span>{OX.contactsFor(s.id).length} live</span>
                  <span>{s.replyRate}% reply</span>
                  <span style={{color:'var(--green)'}}>{s.meetings} mtgs</span>
                </div>
              </div>
            );
          })}
        </div>
      </div>
      <div className="pane" style={{flex:1}}>
        {sel && <SeqCanvas seq={sel} onRuntime={setRuntime} onEnroll={()=>setEnroll(true)} />}
      </div>
      {runtime && <window.OXRuntime contact={runtime} onClose={()=>setRuntime(null)} />}
      {enroll && <window.OXEnroll preselect={null} onClose={()=>setEnroll(false)} />}
    </div>
  );
}

window.OXSequences = OXSequences;
window.OXBits = { ChTag, ChannelPicker, RouteSelect };
window.OXScriptPicker = ScriptPicker;
