// outreach-flow.jsx — right-pane multi-channel outreach for one contact.
// Sub-tabs per communication channel (auto-tailored from the contact's handles).
// Email reuses the full Gmail composer (real send); every other channel is a
// channel-aware draft you edit → copy → log. Only email sends from the app.
const { useState: useStateFl, useEffect: useEffectFl } = React;
const RSfl = window.RaiseShell;

function flTimeShort(ts){
  if(!ts) return '';
  const d = new Date(ts); let h = d.getHours(); const m = d.getMinutes();
  const ap = h>=12?'pm':'am'; h = h%12||12;
  return h+':'+(m<10?'0':'')+m+ap;
}
function flWhen(s){
  if(s.status==='sent') return 'sent '+flTimeShort(s.sentAt);
  return s.offset===0 ? 'Today' : 'in '+s.offset+' days';
}

// ── manual channel editor (LinkedIn / Text / WeChat / Call) ──────────
function FlowManualEditor({ pid, step, c }){
  const OX = window.OX;
  const meta = OX.ch(step.ch);
  const [showAlt, setShowAlt] = useStateFl(false);
  const [copied, setCopied] = useStateFl(false);
  const sent = step.status==='sent';

  const setBody = (v)=> OX.Store.patchFlowStep(pid, step.id, { body:v });
  const copy = ()=>{
    try{ navigator.clipboard.writeText(step.body||''); }catch(e){}
    setCopied(true); setTimeout(()=>setCopied(false), 1600);
    RSfl.toast('Copied — paste into '+meta.label);
  };
  const toggleLog = ()=> OX.Store.logFlowStep(pid, step.id, !sent);
  const reset = ()=>{ const g = OX.genDraft(c, 0, step.ch); OX.Store.patchFlowStep(pid, step.id, { body:g.body||'', alt:g.alt||'' }); RSfl.toast('Reset to engine draft'); };

  // ── Dynamic AI "Help me write" for this touch (voice + sequence + intel) ──
  const aiDynamic = !!(window.RaiseAI && window.RaiseAI.isDynamic());
  const [aiOpen, setAiOpen] = useStateFl(false);
  const [aiPrompt, setAiPrompt] = useStateFl('');
  const [aiBusy, setAiBusy] = useStateFl(false);
  const [aiResult, setAiResult] = useStateFl(null);
  const aiGenerate = async ()=>{
    if(!window.RaiseAI) return;
    setAiBusy(true);
    try{
      const ctx = { channel: step.ch, stepIntent: step.label || '', instruction: aiPrompt.trim(),
        recipient: (c&&c.name)||'', relationship: (c&&(c.warmth||c.relationship))||'' };
      // freshest profile from the live cache: raw LinkedIn intel + the purpose-built outreach brief
      const LDf = window.RaiseLiveData;
      const full = (LDf && LDf._cache) ? LDf._cache.find(x=>x.id===pid) : null;
      const intel = (c && (c.intel || c.profile)) || (full && full.intel); if(intel) ctx.intel = intel;
      const brief = (c && c.intelBrief) || (full && full.intelBrief); if(brief) ctx.brief = brief;
      const fn = (c && c.firstName) || (full && full.firstName); if(fn) ctx.firstName = String(fn).trim();
      // give touch (touch 2): feed the APPROVED toolbox give so the model uses it, never invents one
      if(/give/i.test(step.label || '')){
        const LD = window.RaiseLiveData;
        try{ if(LD && LD.gives && !LD._givesOk && LD.loadGives) await LD.loadGives(); }catch(e){}
        const g = (LD && LD.approvedGiveFor) ? LD.approvedGiveFor((c && (c.icp || c.icpKey))) : null;
        if(g) ctx.give = { title:g.title, source:g.source, url:g.url, hook:g.hook };
        else RSfl.toast('No approved give yet — approve one in the Toolbox so it won’t invent content');
      }
      const out = await window.RaiseAI.rewrite(step.body||'', { task:'rewrite_outreach', context: ctx });
      setAiResult(out);
    }catch(e){ const m=e.message||'error'; RSfl.toast('Rewrite failed — '+(m==='llm_not_configured'?'add OpenRouter key':m==='provider_error'?'check OpenRouter credit':m==='unauthorized'?'sign in again':m)); }
    setAiBusy(false);
  };
  const aiInsert = ()=>{ if(aiResult==null) return; OX.Store.patchFlowStep(pid, step.id, { body: aiResult }); setAiOpen(false); setAiResult(null); setAiPrompt(''); RSfl.toast('Rewritten draft inserted'); };
  const aiClose = ()=>{ setAiOpen(false); setAiResult(null); };

  return (
    <div className="fl-editor">
      <div className="fl-lab">{step.ch==='call' ? 'Talk track' : (step.ch==='wechat' ? 'Message · 中文' : 'Message')}</div>
      <textarea className="fl-body" value={step.body||''} onChange={e=>setBody(e.target.value)} rows={step.ch==='call'?8:7} spellCheck={false} />

      {step.ch==='wechat' && step.alt && (
        <div className="fl-alt">
          <button className="linkbtn" onClick={()=>setShowAlt(s=>!s)}>{showAlt?'Hide English':'Show English reference →'}</button>
          {showAlt && <div className="fl-altbox">{step.alt}</div>}
        </div>
      )}

      {aiDynamic && aiOpen && (
        <div style={{margin:'8px 0', border:'1px solid var(--line,#e6dfd4)', borderRadius:10, background:'var(--surface-2,#faf7f1)', padding:'8px 10px'}}>
          <div style={{display:'flex',alignItems:'center',gap:8}}>
            <span>✨</span>
            <input value={aiPrompt} onChange={e=>setAiPrompt(e.target.value)} onKeyDown={e=>{ if(e.key==='Enter'){ e.preventDefault(); aiGenerate(); } }}
              placeholder={'Optional shaping (e.g. warmer, shorter) — empty = rewrite to my voice for '+meta.label}
              style={{flex:1,border:'none',outline:'none',background:'transparent',fontSize:13,color:'inherit'}} />
            <button className="btn sm" onClick={aiClose}>Cancel</button>
            <button className="btn sm primary" disabled={aiBusy} onClick={aiGenerate}>{aiBusy?'Writing…':(aiResult!=null?'Regenerate':'Rewrite')}</button>
          </div>
          {aiResult!=null && (
            <div style={{marginTop:8}}>
              <div style={{fontSize:11,color:'var(--ink-3)',marginBottom:4}}>Preview · {meta.label} · {step.label||'this touch'} · review before inserting</div>
              <div style={{whiteSpace:'pre-wrap',background:'#fff',border:'1px solid var(--line,#f0ebe3)',borderRadius:8,padding:'8px 10px',fontSize:13,lineHeight:1.5,maxHeight:200,overflow:'auto'}}>{aiResult}</div>
              <div style={{display:'flex',gap:8,marginTop:8}}>
                <button className="btn sm primary" onClick={aiInsert}>Insert</button>
                <button className="btn sm" disabled={aiBusy} onClick={aiGenerate}>Regenerate</button>
                <button className="btn sm" onClick={aiClose}>Discard</button>
              </div>
            </div>
          )}
        </div>
      )}

      <div className="fl-actions">
        {step.ch!=='call' && (
          <button className="btn sm" onClick={copy}>{copied ? '✓ Copied' : 'Copy to '+meta.label}</button>
        )}
        <button className={'btn sm'+(sent?'':' primary')} onClick={toggleLog}>
          {sent ? '✓ Logged — undo' : (step.ch==='call' ? 'Log call' : 'Log sent')}
        </button>
        {aiDynamic && <button className="linkbtn" onClick={()=>setAiOpen(o=>!o)}>{aiOpen?'✨ Close':'✨ Help me write'}</button>}
        <button className="linkbtn ic" onClick={reset}><window.Ico n="refresh" size={12} /> Reset draft</button>
        <span className="fl-deliver">{meta.manual ? 'Manual — copy then log' : meta.deliver}</span>
      </div>
    </div>
  );
}

// ── the pane: channel sub-tabs for one contact ──────────────────────
function OXFlowPane({ cid, onComplete }){
  const OX = window.OX, R = window.RAISE;
  const [,bump] = useStateFl(0);
  useEffectFl(()=> OX.Store.subscribe(()=>bump(x=>x+1)), []);

  const c = R.contactById(cid);
  const flow = OX.Store.flow(cid, c);
  const steps = (flow && flow.steps) || [];
  const firstPendingCh = ()=> (steps.find(s=>s.status!=='sent') || steps[0] || {}).ch;

  const [active, setActive] = useStateFl(firstPendingCh);
  useEffectFl(()=>{ setActive(firstPendingCh()); }, [cid]);

  const doneAll = steps.length>0 && steps.every(s=>s.status==='sent');
  useEffectFl(()=>{ if(doneAll && onComplete) onComplete(); }, [doneAll]);

  if(!c) return <div className="fl-empty">Contact not found.</div>;
  if(!steps.length) return <div className="fl-empty">No channels available for this contact.</div>;

  const activeStep = steps.find(s=>s.ch===active) || steps[0];
  const emailStep = steps.find(s=>s.ch==='email');
  const loggedN = steps.filter(s=>s.status==='sent').length;

  return (
    <div className="flowpane">
      <div className="fl-head">
        <RSfl.Avatar name={c.name} anchor={c.anchor} />
        <div className="fl-who">
          <div className="fl-nm">{c.name}{c.firm && <span className="fl-firm"> · {c.firm}</span>}</div>
          <div className="fl-sub">{loggedN} of {steps.length} logged · auto-tailored sequence</div>
        </div>
        <button className="btn sm ic" onClick={()=>{ OX.Store.rebuildFlow(cid, c); RSfl.toast('Sequence rebuilt'); }}><window.Ico n="refresh" size={13} /> Rebuild</button>
      </div>

      <div className="fl-tabs" role="tablist">
        {steps.map(s=>{
          const m = OX.ch(s.ch), on = active===s.ch, sent = s.status==='sent';
          return (
            <button key={s.ch} role="tab" className={'fl-tab'+(on?' on':'')} onClick={()=>setActive(s.ch)}
              style={on ? { borderColor:m.color, color:m.color } : {}}>
              <span className="fl-tab-g" style={{ background: on?m.color:m.tint, color: on?'#fff':m.color }}>{m.glyph}</span>
              {m.short}
              {sent ? <span className="fl-tab-ck">✓</span> : <span className="fl-tab-dot" />}
            </button>
          );
        })}
      </div>

      <div className="fl-meta">
        <span className="fl-meta-lbl">{activeStep.label}</span>
        <span className="fl-meta-when"> · {flWhen(activeStep)}</span>
      </div>

      <div className="fl-bodywrap">
        {/* email composer stays mounted (preserves edits) — shown only on the Email tab */}
        {emailStep && (
          <div style={{ display: active==='email' ? 'block' : 'none' }}>
            <window.OXComposePane cid={cid} lockContact
              queueCtx={{ stepLabel: emailStep.label, channel:'email' }}
              onSent={(action)=>{ if(action==='sent' || action==='scheduled'){ OX.Store.logFlowStep(cid, emailStep.id, true); } }} />
          </div>
        )}
        {active!=='email' && <FlowManualEditor pid={cid} step={activeStep} c={c} />}
      </div>
    </div>
  );
}

window.OXFlowPane = OXFlowPane;
