// outreach-sender.jsx — the Email Sender: a real compose-and-send surface.
// Honors the product rule (AI never auto-sends): the engine writes the draft,
// Austin reviews and presses Send. Sends + scheduled sends land in the Outbox.
const { useState: useStateSnd, useEffect: useEffectSnd, useRef: useRefSnd, useMemo: useMemoSnd } = React;
const RSsnd = window.RaiseShell;

// strip the plain "Austin" sign-off → full signature block
function withSignature(body){
  const sig = window.OX.Store.signature();
  return body.replace(/\n+Austin\s*$/, '\n\n'+sig);   // idempotent: once replaced there's no trailing "Austin"
}
function seedDraft(c, painIdx=0){
  const g = window.OX.genDraft(c, painIdx, 'email');
  const body = withSignature(g.body);
  return { subject: g.subject, body };
}

// ── account (From) selector ───────────────────────────────────────
function AccountMenu({ value, onChange }){
  const [open, setOpen] = useStateSnd(false);
  const OX = window.OX;
  const cur = OX.ACCOUNTS.find(a=>a.id===value) || OX.ACCOUNTS[0];
  return (
    <div className="snd-acct">
      <button className="snd-acct-btn" onClick={()=>setOpen(o=>!o)}>
        <span className="snd-acct-dot" />
        <span className="snd-acct-em">{cur.email}</span>
        <svg viewBox="0 0 12 12" width="11" height="11" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M2.5 4.5L6 8l3.5-3.5"/></svg>
      </button>
      {open && (
        <>
          <div className="combo-back" onClick={()=>setOpen(false)} />
          <div className="snd-acct-menu" onClick={e=>e.stopPropagation()}>
            {OX.ACCOUNTS.map(a=>(
              <button key={a.id} className={'snd-acct-opt'+(a.id===value?' on':'')} onClick={()=>{ onChange(a.id); setOpen(false); }}>
                <span className="snd-acct-dot" />
                <span className="snd-acct-meta"><b>{a.email}</b><small>{a.label} · {a.kind}</small></span>
                {a.id===value && <span className="snd-acct-ck">✓</span>}
              </button>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

// ── recipient (chip + editable address) ───────────────────────────
function ToChip({ c, email, onEmail }){
  const [edit, setEdit] = useStateSnd(false);
  if(edit) return (
    <input className="snd-email-edit" autoFocus defaultValue={email}
      onBlur={e=>{ onEmail(e.target.value.trim()); setEdit(false); }}
      onKeyDown={e=>{ if(e.key==='Enter'){ onEmail(e.target.value.trim()); setEdit(false); } }} />
  );
  return (
    <button className="snd-tochip" onClick={()=>setEdit(true)} title="Edit address">
      <span className={'snd-tochip-av mono'+(c.anchor?' anchor':'')}>{RSsnd.initials(c.name)}</span>
      <span className="snd-tochip-nm">{c.name}</span>
      <span className="snd-tochip-em">{email}</span>
    </button>
  );
}

// comma / enter separated address field → chips
function AddrField({ label, list, onChange }){
  const [txt, setTxt] = useStateSnd('');
  const commit = (raw)=>{ const v=(raw||'').replace(/[,;]+$/,'').trim(); if(v && !list.includes(v)) onChange([...list, v]); setTxt(''); };
  return (
    <div className="snd-row">
      <span className="snd-rk">{label}</span>
      <div className="snd-addrwrap">
        {list.map(a=>(
          <span key={a} className="snd-cc-chip">{a}<button onClick={()=>onChange(list.filter(x=>x!==a))}>✕</button></span>
        ))}
        <input className="snd-addr-inp" value={txt} placeholder={list.length?'':'name@firm.com'}
          onChange={e=>setTxt(e.target.value)} onBlur={()=>commit(txt)}
          onKeyDown={e=>{ if(e.key==='Enter'||e.key===','){ e.preventDefault(); commit(txt); } else if(e.key==='Backspace'&&!txt&&list.length){ onChange(list.slice(0,-1)); } }} />
      </div>
    </div>
  );
}

// ── schedule-send popover ─────────────────────────────────────────
function ScheduleMenu({ onPick, onClose }){
  const opts = ['In 1 hour','This evening · 6:00 PM','Tomorrow · 8:00 AM','Tue · 9:00 AM','Thu · 7:30 AM'];
  return (
    <>
      <div className="combo-back" onClick={onClose} />
      <div className="snd-sched-menu" onClick={e=>e.stopPropagation()}>
        <div className="snd-sched-hd">Schedule send</div>
        {opts.map(o=> <button key={o} className="snd-sched-opt" onClick={()=>{ onPick(o); onClose(); }}>{o}</button>)}
        <div className="snd-sched-foot">Lands in Gmail at the chosen time — you can cancel from the Outbox before it sends.</div>
      </div>
    </>
  );
}

// ── recipient context card (top of the rail) ──────────────────────
function RecipientCard({ c }){
  const OX = window.OX, R = window.RAISE;
  const st = OX.enrollStatus(c);
  return (
    <div className="snd-reccard">
      <div className="snd-rec-top">
        <RSsnd.Avatar name={c.name} anchor={c.anchor} />
        <div style={{minWidth:0,flex:1}}>
          <button className="snd-rec-nm" onClick={()=>window.RaiseStore.openPerson(c.id)}>{c.name}</button>
          <div className="snd-rec-firm">{c.firm} · {c.geo}</div>
        </div>
      </div>
      <div className="snd-rec-stats">
        <div className="snd-rec-stat"><span className="k">Fit</span><b>{c.fit==null?'—':c.fit+'/10'}</b></div>
        <div className="snd-rec-stat"><span className="k">Interest</span><b>{c.interest==null?'—':c.interest+'/10'}</b></div>
        <div className="snd-rec-stat"><span className="k">Warmth</span><b>{c.warmth||'—'}</b></div>
        <div className="snd-rec-stat"><span className="k">Last touch</span><b>{c.lastTouch?c.lastTouch+' ago':'—'}</b></div>
      </div>
      <div className="snd-rec-seq">
        <span className="snd-rec-dot" style={{background:st.color}} />
        <span style={{flex:1,minWidth:0}}>{c.seq && c.seq!=='—' ? c.seq+' · '+(c.step||'') : 'No active sequence'}</span>
      </div>
    </div>
  );
}

// ── Outbox rail: scheduled first, then sent / drafts ──────────────
function OutboxRail({ outbox }){
  const OX = window.OX, R = window.RAISE;
  const [now, setNow] = useStateSnd(Date.now());
  useEffectSnd(()=>{ const id=setInterval(()=>setNow(Date.now()), 4000); return ()=>clearInterval(id); }, []);
  const fmt = (at)=> new Date(at).toLocaleTimeString('en-US',{hour:'numeric',minute:'2-digit'});
  const ago = (t)=>{ const s=Math.max(0,Math.round((now-t)/1000)); if(s<45) return 'just now'; const m=Math.round(s/60); if(m<60) return m+'m ago'; return Math.round(m/60)+'h ago'; };
  const undoWin = (OX.Store.emailSettings().undoWindow||10)*1000;
  const scheduled = outbox.filter(o=>o.status==='scheduled');
  const rest = outbox.filter(o=>o.status!=='scheduled');
  const sentItems = rest.filter(o=>o.status==='sent');
  const openedCount = sentItems.filter(o=> o.openPlan!=null && o.openPlan.some(t=>t<=now)).length;
  const sentNow = (o)=>{ const ct=R.contactById(o.pid); OX.Store.patchOutbox(o.id,{ status:'sent', when:null, at:Date.now(), openPlan: o.track? OX.planOpens(ct,true) : null }); RSsnd.toast('Sent now to '+o.toName); };
  const cancel = (o)=>{ OX.Store.removeOutbox(o.id); RSsnd.toast('Scheduled send canceled'); };
  const undo = (o)=>{ OX.Store.removeOutbox(o.id); RSsnd.toast('Send undone — back to a draft state'); };
  const Item = ({ o })=>{
    const acct = OX.ACCOUNTS.find(a=>a.id===o.accountId);
    const tracked = o.status==='sent' && o.openPlan!=null;
    const opens = tracked ? o.openPlan.filter(t=> t<=now).length : 0;
    const lastOpen = opens>0 ? o.openPlan[opens-1] : null;
    const canUndo = o.status==='sent' && (now-o.at) < undoWin;
    return (
      <div className={'ob-item '+o.status+(opens>0?' opened':'')}>
        <span className={'ob-av mono'} title={o.toName}>{RSsnd.initials(o.toName)}</span>
        <div className="ob-meta">
          <div className="ob-top"><span className="ob-to">{o.toName}</span>
            <span className={'ob-stat '+o.status}>{o.status==='sent'?fmt(o.at):o.status==='scheduled'?'scheduled':'draft'}</span>
          </div>
          <div className="ob-subj">{o.subject||'(no subject)'}</div>
          <div className="ob-sub2">
            <span className="ob-acctdot" title={acct&&acct.email} />
            {o.status==='scheduled' ? <span className="ob-when">{o.when}</span> : <span className="ob-em">{o.toEmail}</span>}
            {o.logTouch && o.status==='sent' && <span className="ob-logged">touch logged</span>}
            {o.attachments && o.attachments.length>0 && <span className="ob-clip">📎 {o.attachments.length}</span>}
          </div>
          {o.status==='sent' && !canUndo && (
            tracked
              ? (opens>0
                  ? <div className="ob-open opened"><span className="ob-eye">●</span>Opened {ago(lastOpen)}{opens>1 && <span className="ob-opencount">· {opens}×</span>}</div>
                  : <div className="ob-open pending"><span className="ob-eye">○</span>Not opened yet</div>)
              : <div className="ob-open off">Tracking off</div>
          )}
          {o.status==='scheduled' && (
            <div className="ob-acts">
              <button className="ob-act" onClick={()=>sentNow(o)}>Send now</button>
              <button className="ob-act danger" onClick={()=>cancel(o)}>Cancel</button>
            </div>
          )}
          {canUndo && (
            <div className="ob-acts">
              <button className="ob-act danger" onClick={()=>undo(o)}>Undo send · {Math.max(1,Math.ceil((undoWin-(now-o.at))/1000))}s</button>
            </div>
          )}
        </div>
      </div>
    );
  };
  return (
    <div className="snd-outbox scroll">
      <div className="snd-ob-hd">
        <span>Outbox · today</span>
        <span className="snd-ob-count">{outbox.length}</span>
      </div>
      {sentItems.length>0 && <div className="snd-ob-opensum">{openedCount} of {sentItems.length} sent {openedCount===1?'has':'have'} opened</div>}
      {outbox.length===0 && (
        <div className="snd-ob-empty">Nothing sent yet today. Drafts you send or schedule show up here — with a window to cancel before they leave.</div>
      )}
      {scheduled.length>0 && <div className="snd-ob-sec">Scheduled · {scheduled.length}</div>}
      {scheduled.map(o=> <Item key={o.id} o={o} />)}
      {rest.length>0 && scheduled.length>0 && <div className="snd-ob-sec">Sent</div>}
      {rest.map(o=> <Item key={o.id} o={o} />)}
    </div>
  );
}

// ═══ Compose pane — the reusable email window (standalone tab + split-view console) ═══
function ComposePane({ cid, setCid, lockContact, painIdx=0, setPainIdx, queueCtx, onSent }){
  const OX = window.OX, R = window.RAISE;
  const c = R.contactById(cid);
  const ES = OX.Store.emailSettings();
  const [acct, setAcct] = useStateSnd(ES.fromDefault || 'fund');
  const [toEmail, setToEmail] = useStateSnd(()=>OX.emailFor(c));
  const [cc, setCc] = useStateSnd([]);
  const [bcc, setBcc] = useStateSnd([]);
  const [showCc, setShowCc] = useStateSnd(false);
  const seed = seedDraft(c, painIdx);
  const [subject, setSubject] = useStateSnd(seed.subject);
  const [body, setBody] = useStateSnd(seed.body);
  const [attach, setAttach] = useStateSnd([]);
  const [logTouch, setLogTouch] = useStateSnd(ES.logTouch);
  const [track, setTrack] = useStateSnd(ES.trackOpens);
  const [picking, setPicking] = useStateSnd(false);
  const [scheduling, setScheduling] = useStateSnd(false);
  const pains = OX.painsFor(c);

  // reseed when the recipient or chosen pain changes
  useEffectSnd(()=>{
    const s = seedDraft(c, painIdx);
    setToEmail(OX.emailFor(c)); setSubject(s.subject); setBody(s.body);
    setCc([]); setBcc([]); setAttach([]); setShowCc(false);
  }, [cid, painIdx]);

  const words = (body||'').trim().split(/\s+/).filter(Boolean).length;
  const score = OX.scoreDraft(c, painIdx, 'email', { subject, body, words });
  const regen = ()=>{ const s = seedDraft(c, painIdx); setSubject(s.subject); setBody(s.body); RSsnd.toast('Regenerated from '+OX.firstName(c.name)+'’s intel'); };
  const insertScript = (sv)=>{ const t = OX.scriptText(sv, c); setBody(b=> b.replace(/\n\nAustin[\s\S]*$/, '') + '\n\n' + t + '\n\n' + OX.Store.signature()); RSsnd.toast('Inserted “'+sv.name+'”'); };

  const buildRec = (status, when)=>{
    const es = OX.Store.emailSettings();
    const bccAll = es.autoBcc && es.autoBccAddr ? [...bcc, es.autoBccAddr] : [...bcc];
    const rec = {
      pid: cid, accountId: acct, account: (OX.ACCOUNTS.find(a=>a.id===acct)||{}).email,
      toName: c.name, toEmail, cc:[...cc], bcc: bccAll,
      subject, preview: body.replace(/\s+/g,' ').slice(0,120),
      attachments: attach.map(id=> (OX.ATTACHMENTS.find(a=>a.id===id)||{}).name).filter(Boolean),
      rubric: score.passed+'/'+score.of, status, when: when||null, logTouch, track,
    };
    if(status==='sent') rec.openPlan = OX.planOpens(c, track);
    return rec;
  };
  const send = ()=>{
    const rec=OX.Store.pushOutbox(buildRec('sent'));
    RSsnd.celebrate(window.innerWidth*0.6, 150, false);
    // real-time send through Gmail when Google is connected; falls back to local-only log otherwise
    if(window.RaiseGoogle){
      const es=OX.Store.emailSettings();
      const bccAll=(es.autoBcc && es.autoBccAddr)?[...bcc, es.autoBccAddr]:[...bcc];
      window.RaiseGoogle.sendEmail({ to: toEmail, cc: cc.join(', '), bcc: bccAll.join(', '), subject, body })
        .then(()=> RSsnd.toast('Sent via Gmail to '+OX.firstName(c.name)))
        .catch(err=> RSsnd.toast(
          err.message==='paused' ? 'Safe mode — logged, not sent. Turn Live on in Settings to send for real.'
          : err.message==='not_connected' ? 'Logged — connect Google in Settings to send for real'
          : 'Gmail send failed: '+err.message));
    } else { RSsnd.toast('Sent to '+OX.firstName(c.name)); }
    onSent && onSent('sent', rec, c);
  };
  const schedule = (when)=>{ const rec=OX.Store.pushOutbox(buildRec('scheduled', when)); RSsnd.toast('Scheduled — '+when); onSent && onSent('scheduled', rec, c); };
  const saveDraft = ()=>{ const rec=OX.Store.pushOutbox(buildRec('draft')); RSsnd.toast('Saved to Gmail Drafts'); onSent && onSent('draft', rec, c); };

  const acctMeta = OX.ACCOUNTS.find(a=>a.id===acct)||OX.ACCOUNTS[0];
  const chMeta = queueCtx && queueCtx.channel ? OX.ch(queueCtx.channel) : null;

  return (
    <div className="mailwin">
      <div className="mailwin-hd">
        <div style={{minWidth:0,flex:1}}>
          <span className="mw-title">{lockContact ? c.name : 'New message'}</span>
          {queueCtx && queueCtx.stepLabel && (
            <div className="mw-ctx">
              {chMeta && <span className="mw-chdot" style={{background:chMeta.color}}>{chMeta.glyph}</span>}
              <span className="mw-ctxlbl">{queueCtx.stepLabel}</span>
              {chMeta && chMeta.id!=='email' && <span className="mw-chwarn">{chMeta.label} step — drafting as email</span>}
            </div>
          )}
        </div>
        <div className="mw-from">
          <span className="mw-fromk">From</span>
          <AccountMenu value={acct} onChange={setAcct} />
        </div>
      </div>

      <div className="snd-row to">
        <span className="snd-rk">To</span>
        <div className="snd-towrap">
          {!lockContact && setCid && <RSsnd.PersonCombo value={cid} onChange={setCid} allowSelf={false} />}
          <ToChip c={c} email={toEmail} onEmail={setToEmail} />
        </div>
        {!showCc && <button className="snd-ccbtn" onClick={()=>setShowCc(true)}>Cc / Bcc</button>}
      </div>

      {showCc && <AddrField label="Cc" list={cc} onChange={setCc} />}
      {showCc && <AddrField label="Bcc" list={bcc} onChange={setBcc} />}

      <div className="snd-row subj">
        <span className="snd-rk">Subject</span>
        <input className="snd-subj-inp" value={subject} onChange={e=>setSubject(e.target.value)} placeholder="Subject" />
        <span className="snd-engine-tag">engine draft</span>
      </div>

      {setPainIdx && pains.length>1 && (
        <div className="snd-pains">
          <span className="snd-pl">Leads with</span>
          {pains.map((p,i)=>(
            <button key={i} className={'snd-painchip'+(painIdx===i?' on':'')} onClick={()=>setPainIdx(i)}>{p}</button>
          ))}
        </div>
      )}

      <textarea className="snd-body" value={body} onChange={e=>setBody(e.target.value)} spellCheck={false} />

      <div className="snd-attach">
        {OX.ATTACHMENTS.map(a=>{ const on=attach.includes(a.id);
          return (
            <button key={a.id} className={'snd-att-chip'+(on?' on':'')} onClick={()=>setAttach(on?attach.filter(x=>x!==a.id):[...attach,a.id])}>
              <span className="att-ic">{on?'📎':'＋'}</span>{a.name}<small>{a.size}</small>
            </button>
          ); })}
      </div>

      <div className="snd-foot">
        <div className="snd-sendsplit">
          <button className="snd-send" onClick={send}>Send</button>
          <button className="snd-send-caret" onClick={()=>setScheduling(true)}>▾</button>
          {scheduling && <ScheduleMenu onPick={schedule} onClose={()=>setScheduling(false)} />}
        </div>
        <div className="chpick-wrap">
          <button className="snd-tool" onClick={()=>setPicking(true)} title="Insert a saved script">⤵ Script</button>
          {picking && <window.OXScriptPicker onPick={insertScript} onClose={()=>setPicking(false)} title="Insert a saved script" />}
        </div>
        <button className="snd-tool" onClick={regen} title="Rewrite from the engine">↻ Regenerate</button>
        <button className="snd-tool" onClick={saveDraft} title="Hand off to Gmail Drafts">Save to Drafts</button>

        <label className="snd-logtouch" title="Log this as a touch on the contact's timeline">
          <input type="checkbox" checked={logTouch} onChange={e=>setLogTouch(e.target.checked)} />
          <span>Log touch</span>
        </label>
        <label className="snd-logtouch" title="Embed a tracking pixel — opens show in the Outbox. Default in Settings › Email.">
          <input type="checkbox" checked={track} onChange={e=>setTrack(e.target.checked)} />
          <span>Track opens</span>
        </label>

        <div className="snd-meta-right">
          <span className={'snd-rubric'+(score.passed>=8?' good':score.passed>=6?' ok':' low')}
            title="10-point cold-email rubric">{score.passed}/{score.of} rubric</span>
          <span className="snd-wc">{words}w</span>
        </div>
      </div>
      <div className="snd-rule">
        <span className="snd-rule-dot" style={{background:acctMeta.id==='fund'?'var(--primary)':'var(--green)'}} />
        Sending as <b>{acctMeta.email}</b> — you press Send; the engine never sends on its own.
      </div>
    </div>
  );
}

// ═══ standalone sender (kept for reuse; Today's split-view console is the main home) ═══
function OXSender(){
  const OX = window.OX, R = window.RAISE;
  const [,bump] = useStateSnd(0);
  useEffectSnd(()=> OX.Store.subscribe(()=>bump(x=>x+1)), []);
  const outreachList = useMemoSnd(()=> R.contacts.filter(c=> ['outreach','meeting','dataroom'].includes(c.stage)), []);
  const [cid, setCid] = useStateSnd(()=>{
    const f = localStorage.getItem('raiseos.outreach.composeFor');
    if(f && R.contactById(f)){ localStorage.removeItem('raiseos.outreach.composeFor'); return f; }
    return (outreachList[0]||R.contacts[0]).id;
  });
  const advance = ()=>{ const idx=outreachList.findIndex(x=>x.id===cid); const next=outreachList[idx+1]||outreachList[0]; if(next&&next.id!==cid) setCid(next.id); };
  return (
    <div className="sender">
      <div className="snd-main scroll">
        <ComposePane cid={cid} setCid={setCid} onSent={(a)=>{ if(a==='sent'||a==='scheduled') advance(); }} />
      </div>
      <div className="snd-rail">
        <RecipientCard c={R.contactById(cid)} />
        <OutboxRail outbox={OX.Store.outbox()} />
      </div>
    </div>
  );
}

window.OXSender = OXSender;
window.OXComposePane = ComposePane;
window.OXRecipientCard = RecipientCard;
window.OXOutboxRail = OutboxRail;
