// Lead detail — conversation + Tommy draft + stage controls, wired to /leads/{id}
// and the tommy approve/reject/coach endpoints.

const STAGE_OPTIONS = [
  'NEW LEAD', 'FIRST TOUCH', 'INTERESTED',
  'FOLLOW UP', 'DAY PASS SCHEDULED', 'NEEDS_RESCHEDULE', 'SHOWED',
  'JOINED', 'MEMBER', 'DEAD', 'NO SHOW',
];

function LeadDetailView({ contactId, onNavigate, user }) {
  const [lead, setLead] = React.useState(null);
  const [approval, setApproval] = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [draftText, setDraftText] = React.useState('');
  const [typed, setTyped] = React.useState('');
  const [sending, setSending] = React.useState(false);
  const [stageEdit, setStageEdit] = React.useState(false);
  const scrollRef = React.useRef(null);

  async function reload() {
    setLoading(true);
    try {
      const [l, appr] = await Promise.all([
        api.get(`/api/v2/leads/${encodeURIComponent(contactId)}`),
        api.get('/api/v2/tommy/pending-approvals'),
      ]);
      const adapted = adaptLead(l);
      adapted.messages = l.messages || [];
      setLead(adapted);
      cacheContacts([adapted]);
      const mine = (appr?.approvals || []).find(a => a.contact_id === contactId);
      setApproval(mine || null);
      setDraftText(mine?.tommy_draft || '');
      // Mark this thread read.
      api.post('/api/v2/tommy/mark-read', { contact_id: contactId }).catch(() => {});
    } catch (e) {
      setLead(null);
    } finally {
      setLoading(false);
    }
  }

  React.useEffect(() => { reload(); /* eslint-disable-next-line */ }, [contactId]);

  React.useEffect(() => {
    function onEv(e) {
      const d = e.detail || {};
      if (!d) return;
      if (d.contact_id === contactId || d.event_type === 'tommy_sent' || d.event_type === 'sms_inbound') {
        reload();
      }
    }
    window.addEventListener('raw:event', onEv);
    return () => window.removeEventListener('raw:event', onEv);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [contactId]);

  React.useEffect(() => {
    scrollRef.current?.scrollTo({top: scrollRef.current.scrollHeight});
  }, [lead?.messages?.length, approval?.id]);

  async function approve() {
    if (!approval) return;
    try {
      await api.post('/api/v2/tommy/approve', { approval_id: approval.id, message: draftText });
      await reload();
    } catch (e) {
      if (isQuietHoursError(e) && confirm(quietHoursPrompt(e, 'approve and send'))) {
        try {
          await api.post('/api/v2/tommy/approve', {
            approval_id: approval.id, message: draftText, override_quiet_hours: true,
          });
          await reload();
          return;
        } catch (e2) { alert(friendlyApiError(e2, 'Approve failed')); return; }
      }
      alert(friendlyApiError(e, 'Approve failed'));
    }
  }
  async function reject() {
    if (!approval) return;
    try {
      await api.post('/api/v2/tommy/reject', { approval_id: approval.id });
      await reload();
    } catch (e) { alert(friendlyApiError(e, 'Reject failed')); }
  }
  async function coach() {
    if (!approval) return;
    const note = prompt('What extra context should Tommy use?');
    if (!note) return;
    try {
      await api.post('/api/v2/tommy/coach', { approval_id: approval.id, context_note: note });
      await reload();
    } catch (e) { alert(friendlyApiError(e, 'Coach failed')); }
  }
  async function dismiss() {
    if (!approval) return;
    try {
      await api.post('/api/v2/tommy/dismiss', { approval_id: approval.id });
      await reload();
    } catch (e) { alert(friendlyApiError(e, 'Dismiss failed')); }
  }
  async function sendManual() {
    if (!typed.trim()) return;
    setSending(true);
    const text = typed.trim();
    try {
      await api.post(`/api/v2/leads/${encodeURIComponent(contactId)}/message`, { message: text });
      setTyped('');
      await reload();
    } catch (e) {
      if (isQuietHoursError(e) && confirm(quietHoursPrompt(e, 'send this SMS'))) {
        try {
          await api.post(`/api/v2/leads/${encodeURIComponent(contactId)}/message`, {
            message: text, override_quiet_hours: true,
          });
          setTyped('');
          await reload();
        } catch (e2) { alert(friendlyApiError(e2, 'Send failed')); }
      } else {
        alert(friendlyApiError(e, 'Send failed'));
      }
    }
    finally { setSending(false); }
  }
  async function promptTommy() {
    try {
      await api.post(`/api/v2/leads/${encodeURIComponent(contactId)}/prompt-tommy`, {});
      setTimeout(reload, 800);
    } catch (e) { alert(friendlyApiError(e, 'Prompt failed')); }
  }
  async function changeStage(next) {
    try {
      await api.patch(`/api/v2/leads/${encodeURIComponent(contactId)}/stage`, { stage: next });
      setStageEdit(false);
      await reload();
    } catch (e) { alert(friendlyApiError(e, 'Stage change failed')); }
  }
  async function toggleHot() {
    if (!lead) return;
    const next = !lead.hot;
    try {
      await api.patch(`/api/v2/leads/${encodeURIComponent(contactId)}`, { hot: next });
      await reload();
    } catch (e) { alert(friendlyApiError(e, 'Failed to toggle hot')); }
  }

  if (loading && !lead) {
    return <div className="app-main"><div className="empty">Loading…</div></div>;
  }
  if (!lead) {
    return <div className="app-main">
      <div style={{marginBottom:16}}>
        <button className="btn ghost sm" onClick={() => onNavigate({view:'leads'})}>← All leads</button>
      </div>
      <div className="empty">Lead not found.</div>
    </div>;
  }

  const c = lead;
  const msgs = (c.messages || []).map(m => {
    const from = m.direction === 'inbound' ? 'them' : 'tommy';
    // sender_label comes from the backend (derived from GHL userId/source
    // when available, falls back to the [MANUAL] prefix for db rows).
    // Default to "Tommy · AI" so older API responses still render.
    const senderLabel = m.sender_label || 'Tommy · AI';
    return { from, body: m.message, sent_at: m.sent_at, sender_label: senderLabel };
  });

  const stageRaw = c.stage_raw || c.stage;
  return (
    <div className="app-main">
      <div style={{marginBottom:16, display:'flex', alignItems:'center', gap:10}}>
        <button className="btn ghost sm" onClick={() => onNavigate({view:'leads'})}>← All leads</button>
        <span className="kicker">Contact · {c.id}</span>
        <button
          type="button"
          onClick={toggleHot}
          title={c.hot ? 'Unmark as hot lead' : 'Mark as hot lead'}
          style={{
            marginLeft:6,
            height:22,
            padding:'0 10px',
            border:'none',
            borderRadius:11,
            fontFamily:'var(--mono)',
            fontSize:11,
            letterSpacing:'0.04em',
            cursor:'pointer',
            display:'inline-flex', alignItems:'center', gap:6,
            background: c.hot ? 'var(--warn-soft)' : 'var(--bone-2)',
            color:    c.hot ? 'var(--warn)'      : 'var(--muted-2)',
            transition: 'background 0.15s, color 0.15s',
          }}
        >
          <span style={{
            width:6, height:6, borderRadius:'50%',
            background: c.hot ? 'var(--warn)' : 'var(--muted-2)',
            opacity: c.hot ? 1 : 0.6,
          }} />
          {c.hot ? 'hot' : 'not hot'}
        </button>
        {c.is_member && (
          <span className="chip" style={{background:'var(--bone-3)', color:'var(--ink)'}}>
            <span className="dot" />member
          </span>
        )}
      </div>

      <div className="lead-detail">
        {/* conversation pane */}
        <div className="lead-conv">
          <div className="conv-hd">
            <div className="l">
              <span className="avatar xl" style={{background:'var(--bone-3)', color:'var(--ink)'}}>
                {initialsOf(c.name)}
              </span>
              <div className="name-blk">
                <div className="n">{c.name}</div>
                <div className="ph">{c.phone || '—'}{c.source ? ' · via ' + c.source : ''}</div>
              </div>
              <div style={{marginLeft:10, position:'relative'}}>
                <span
                  className={'chip stage-' + c.stage}
                  onClick={() => setStageEdit(v => !v)}
                  style={{cursor:'pointer'}}
                ><span className="dot" />{stageRaw}</span>
                {stageRaw === 'NEEDS_RESCHEDULE' && c.needs_reschedule_entered_at && (
                  <span className="chip reschedule-wait" style={{marginLeft:6}}>
                    Waiting {daysSince(c.needs_reschedule_entered_at)}d
                  </span>
                )}
                {stageEdit && (
                  <div style={{
                    position:'absolute', top:'calc(100% + 6px)', left:0, zIndex:10,
                    background:'#FBF9F3', border:'1px solid var(--line)',
                    borderRadius:'var(--radius)', boxShadow:'0 12px 28px -12px rgba(14,14,12,0.3)',
                    padding:6, minWidth:180,
                  }}>
                    {STAGE_OPTIONS.map(s => (
                      <div key={s}
                        onClick={() => changeStage(s)}
                        style={{padding:'7px 12px', fontSize:13, cursor:'pointer', borderRadius:4,
                          background: s === stageRaw ? 'var(--bone-2)' : 'transparent'}}>
                        {s.toLowerCase()}
                      </div>
                    ))}
                  </div>
                )}
              </div>
            </div>
            <div className="actions">
              <button className="btn sm" onClick={() => setStageEdit(v => !v)}>Change stage</button>
              <button className="btn sm" onClick={promptTommy}>Prompt Tommy</button>
            </div>
          </div>

          <div className="conv-scroll" ref={scrollRef}>
            {msgs.length === 0 && <div className="empty">No messages yet.</div>}
            {msgs.map((m, i) => (
              <div key={i} className={'msg ' + m.from}>
                {m.from !== 'them' && (
                  <div className="msg-from">{m.sender_label}</div>
                )}
                <div>{m.body}</div>
                <div className="msg-t">{fmtAgoFrom(m.sent_at)}</div>
              </div>
            ))}
          </div>

          {approval && (
            <div className="draft-box">
              <div className="draft-lbl">
                — Tommy draft
                <span className="tag">needs approval</span>
                <span style={{marginLeft:'auto', color:'var(--muted-2)'}}>
                  {approval.hold_reason || approval.status}
                </span>
              </div>
              <textarea
                className="draft-text"
                value={draftText}
                onChange={e => setDraftText(e.target.value)}
                rows="3"
                style={{resize:'vertical', width:'100%', fontFamily:'var(--sans)', color:'var(--ink)', outline:'none'}}
              />
              <div className="draft-actions">
                <span className="meta">Route: GHL conversations → SMS · logs to tommy_learning</span>
                <button className="btn sm" onClick={coach}>Coach</button>
                <button className="btn sm" onClick={dismiss} title="Dismiss without replying or training">Dismiss</button>
                <button className="btn sm" onClick={reject}>Reject</button>
                <button className="btn sm primary" onClick={approve} disabled={approval.status === 'context_requested'}>Approve &amp; send</button>
              </div>
            </div>
          )}

          {!approval && (
            <div className="draft-box">
              <div className="draft-lbl">— Reply as {(user?.name || 'Staff').split(' ')[0]}</div>
              <textarea
                value={typed}
                onChange={e => setTyped(e.target.value)}
                placeholder="Type a message…"
                rows="2"
                style={{
                  resize:'vertical', width:'100%',
                  background:'var(--bone)', border:'1px solid var(--line)',
                  borderRadius:4, padding:'10px 14px',
                  fontFamily:'var(--sans)', fontSize:14, color:'var(--ink)', outline:'none',
                }}
              />
              <div className="draft-actions">
                <span className="meta">Sends via GHL → contact SMS</span>
                <button className="btn sm" onClick={promptTommy}>Prompt Tommy</button>
                <button className="btn sm primary" onClick={sendManual} disabled={sending || !typed.trim()}>
                  {sending ? 'Sending…' : 'Send SMS'}
                </button>
              </div>
            </div>
          )}
        </div>

        {/* side panel */}
        <div className="lead-side">
          <div className="side-card">
            <div className="sc-hd">— Contact</div>
            <div className="sc-bd">
              <div className="kv"><span className="k">Stage</span><span className="v"><span className={'chip stage-' + c.stage}><span className="dot" />{stageRaw}</span></span></div>
              <div className="kv"><span className="k">Source</span><span className="v">{c.source || '—'}</span></div>
              <div className="kv"><span className="k">Phone</span><span className="v" style={{fontFamily:'var(--mono)', fontSize:12}}>{c.phone || '—'}</span></div>
              <div className="kv"><span className="k">Email</span><span className="v" style={{fontFamily:'var(--mono)', fontSize:12}}>{c.email || '—'}</span></div>
              <div className="kv"><span className="k">Tags</span><span className="v">
                <div style={{display:'flex', flexWrap:'wrap', gap:4}}>
                  {(c.tags || []).length === 0 && <span style={{color:'var(--muted-2)'}}>—</span>}
                  {(c.tags || []).map(t => (
                    <span key={t} className="chip" style={{height:18, padding:'0 6px', fontSize:10}}>{String(t)}</span>
                  ))}
                </div>
              </span></div>
              <div className="kv"><span className="k">Hot</span><span className="v">{c.hot ? 'yes' : 'no'}</span></div>
              <div className="kv"><span className="k">Last</span><span className="v">{fmtAgoFrom(c.updated_at)}</span></div>
            </div>
          </div>

          {c.scheduled_label && (
            <div className="side-card">
              <div className="sc-hd">— Next appointment</div>
              <div className="sc-bd">
                <div style={{fontWeight:600, fontSize:18, letterSpacing:'-0.01em'}}>{c.scheduled_label}</div>
                <div style={{color:'var(--muted)', fontSize:13, marginTop:4}}>{c.interest || 'Day pass'}</div>
              </div>
            </div>
          )}

          <div className="side-card">
            <div className="sc-hd">— Tommy</div>
            <div className="sc-bd" style={{fontSize:13, color:'var(--muted)', lineHeight:1.55}}>
              <div style={{color:'var(--ink)', marginBottom:6}}>
                {(c.messages || []).length} messages · {c.tommy_contacted ? 'Tommy has contacted' : 'not yet contacted'}
              </div>
              Few-shot matches from <span style={{fontFamily:'var(--mono)', fontSize:11}}>tommy_learned_responses</span> injected when drafting replies.
              <div style={{marginTop:10, fontFamily:'var(--mono)', fontSize:11, color:'var(--muted-2)', letterSpacing:'0.04em'}}>
                pending: {approval ? 'yes · ' + approval.status : 'no'}
              </div>
            </div>
          </div>

          <div className="side-card">
            <div className="sc-hd">— System</div>
            <div className="sc-bd" style={{fontFamily:'var(--mono)', fontSize:11, color:'var(--muted)', lineHeight:1.7, letterSpacing:'0.04em'}}>
              <div>GHL ID · <span style={{color:'var(--ink)'}}>{c.id}</span></div>
              <div>Created · <span style={{color:'var(--ink)'}}>{c.created_at ? fmtShortDay(c.created_at) : '—'}</span></div>
              <div>Age · <span style={{color:'var(--ink)'}}>{c.age_days}d</span></div>
              <div>Member · <span style={{color:'var(--ink)'}}>{c.is_member ? 'yes' : 'no'}</span></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { LeadDetailView });
