// Tommy inbox — pending approvals, sent history, intent breakdown.
// Wired to /tommy/pending-approvals, /tommy/messages, /tommy/stats.

function TommyStatPill({ label, value, sub }) {
  return (
    <div style={{
      flex:1, padding:'14px 16px',
      border:'1px solid var(--line)', borderRadius:'var(--radius)',
      background:'#FBF9F3',
    }}>
      <div className="kicker" style={{marginBottom:8}}>{label}</div>
      <div style={{fontWeight:700, fontSize:28, letterSpacing:'-0.03em', lineHeight:1, fontVariantNumeric:'tabular-nums'}}>{value}</div>
      <div style={{fontSize:12, color:'var(--muted)', marginTop:6}}>{sub}</div>
    </div>
  );
}

function TommyView({ onNavigate }) {
  const [tab, setTab] = React.useState('pending');

  const [topicFilter, setTopicFilter] = React.useState('');
  const [trainingSearch, setTrainingSearch] = React.useState('');
  const [debouncedTrainingSearch, setDebouncedTrainingSearch] = React.useState('');
  React.useEffect(() => {
    const t = setTimeout(() => setDebouncedTrainingSearch(trainingSearch.trim()), 250);
    return () => clearTimeout(t);
  }, [trainingSearch]);

  const stats = useAsync(() => api.get('/api/v2/tommy/stats'), []);
  const approvals = useAsync(() => api.get('/api/v2/tommy/pending-approvals'), []);
  const history = useAsync(() => api.get('/api/v2/tommy/messages?limit=100'), [tab === 'history']);
  const config = useAsync(() => api.get('/api/v2/system/tommy-config'), []);
  const training = useAsync(() => {
    if (tab !== 'training') return Promise.resolve({ items: [], total: 0, topics: [] });
    const qs = new URLSearchParams({ limit: '100' });
    if (topicFilter) qs.set('topic', topicFilter);
    if (debouncedTrainingSearch) qs.set('search', debouncedTrainingSearch);
    return api.get('/api/v2/tommy/learned-responses?' + qs.toString());
  }, [tab, topicFilter, debouncedTrainingSearch]);

  React.useEffect(() => {
    function onEv() { approvals.reload(); stats.reload(); }
    window.addEventListener('raw:event', onEv);
    return () => window.removeEventListener('raw:event', onEv);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const s = stats.data || {};
  const list = approvals.data?.approvals || [];
  const msgs = history.data?.messages || history.data?.items || [];

  async function approve(a) {
    const msg = prompt('Send as:', a.tommy_draft) ?? a.tommy_draft;
    if (!msg) return;
    try {
      await api.post('/api/v2/tommy/approve', { approval_id: a.id, message: msg });
      approvals.reload(); stats.reload();
    } catch (e) {
      if (isQuietHoursError(e) && confirm(quietHoursPrompt(e, 'approve and send'))) {
        try {
          await api.post('/api/v2/tommy/approve', {
            approval_id: a.id, message: msg, override_quiet_hours: true,
          });
          approvals.reload(); stats.reload();
          return;
        } catch (e2) { alert(friendlyApiError(e2, 'Approve failed')); return; }
      }
      alert(friendlyApiError(e, 'Approve failed'));
    }
  }
  async function reject(a) {
    try {
      await api.post('/api/v2/tommy/reject', { approval_id: a.id });
      approvals.reload(); stats.reload();
    } catch (e) { alert(friendlyApiError(e, 'Reject failed')); }
  }
  async function dismiss(a) {
    try {
      await api.post('/api/v2/tommy/dismiss', { approval_id: a.id });
      approvals.reload(); stats.reload();
    } catch (e) { alert(friendlyApiError(e, 'Dismiss failed')); }
  }

  return (
    <div className="app-main">
      <div className="page-hd">
        <div>
          <div className="kicker" style={{marginBottom:8}}>— AI SMS worker</div>
          <h1>Tommy</h1>
          <div className="sub">Drafts, approvals, and learned responses · model <span style={{fontFamily:'var(--mono)', fontSize:12}}>{config.data?.model || 'claude-sonnet'}</span></div>
        </div>
        <div className="actions">
          <button className="btn" onClick={() => onNavigate({view:'system'})}>Config →</button>
        </div>
      </div>

      <div style={{display:'flex', gap:16, marginBottom:20}}>
        <TommyStatPill
          label="Pending · now"
          value={s.pending_approvals ?? '—'}
          sub={`${s.unread_count ?? 0} unread`}
        />
        <TommyStatPill
          label="Sent today"
          value={s.messages_sent_today ?? '—'}
          sub={`total lifetime: ${s.messages_sent_total ?? 0}`}
        />
        <TommyStatPill
          label="Active conversations · 7d"
          value={s.convos_active ?? '—'}
          sub="distinct contacts"
        />
        <TommyStatPill
          label="Status"
          value={s.status === 'ok' ? 'live' : (s.status || '—')}
          sub="worker · pg_notify idle"
        />
      </div>

      <div style={{
        display:'flex', gap:2,
        borderBottom:'1px solid var(--line)',
        marginBottom:16,
      }}>
        {[
          { id:'pending',  label:`Pending · ${list.length}` },
          { id:'history',  label:'Sent · recent' },
          { id:'training', label:'Training' },
          { id:'config',   label:'Config' },
        ].map(t => (
          <button
            key={t.id}
            onClick={() => setTab(t.id)}
            style={{
              background:'transparent', border:'none',
              padding:'10px 14px', fontSize:13, fontWeight:500,
              color: tab===t.id ? 'var(--ink)' : 'var(--muted)',
              borderBottom: tab===t.id ? '2px solid var(--ink)' : '2px solid transparent',
              marginBottom:-1,
              cursor:'pointer',
            }}
          >{t.label}</button>
        ))}
      </div>

      {tab === 'pending' && (
        <div className="card">
          <div className="hd">
            <div className="title">— <b>Pending approvals</b></div>
            <div className="aside">
              <span style={{fontFamily:'var(--mono)', fontSize:11, color:'var(--muted)'}}>auto-expires in 24h</span>
            </div>
          </div>
          <div className="bd p0">
            {list.length === 0 && !approvals.loading && <div className="empty">All caught up. Tommy is auto-sending.</div>}
            {list.map(a => {
              const lastInbound = a.inbound_message || '';
              return (
                <div key={a.id} className="tommy-approval-row">
                  <div className="tar-who">
                    <div style={{display:'flex', alignItems:'center', gap:10, marginBottom:8}}>
                      <span className="avatar" style={{width:32, height:32, fontSize:11, background:'var(--bone-3)', color:'var(--ink)'}}>
                        {initialsOf(a.contact_name)}
                      </span>
                      <div>
                        <div style={{fontWeight:500}}>{a.contact_name}</div>
                        <div style={{fontFamily:'var(--mono)', fontSize:11, color:'var(--muted)'}}>{a.contact_phone || '—'}</div>
                      </div>
                    </div>
                    <div style={{display:'flex', gap:6, flexWrap:'wrap'}}>
                      <span className={'chip stage-' + stageGroupOf(a.stage)}><span className="dot" />{(a.stage || 'new lead').toLowerCase()}</span>
                      {a.is_member && <span className="chip" style={{color:'var(--signal-ink)', background:'var(--signal-soft)'}}>member</span>}
                      {a.hot && <span className="chip tommy-unanswered"><span className="dot" />hot</span>}
                    </div>
                  </div>

                  <div className="tar-msg">
                    {lastInbound && (
                      <div style={{marginBottom:10}}>
                        <div className="kicker" style={{marginBottom:6}}>— Inbound</div>
                        <div className="msg-bubble" style={{padding:'10px 14px', background:'var(--bone-2)', borderRadius:4, fontSize:13, lineHeight:1.5}}>
                          {lastInbound}
                        </div>
                      </div>
                    )}
                    <div className="kicker" style={{marginBottom:6}}>— Tommy draft</div>
                    <div className="msg-bubble" style={{padding:'10px 14px', background:'var(--bone)', borderLeft:'2px solid var(--signal)', borderRadius:4, fontSize:13, lineHeight:1.5}}>
                      {a.tommy_draft || (a.status === 'context_requested' ? 'Redrafting with context…' : 'Draft pending…')}
                    </div>
                  </div>

                  <div className="tar-side">
                    <div className="tar-meta">
                      <div>status · <span style={{color:'var(--ink)'}}>{a.status}</span></div>
                      <div>waiting · <span style={{color:'var(--ink)'}}>{fmtAgoFrom(a.waiting_since)}</span></div>
                      <div>reason · <span style={{color:'var(--ink)'}}>{a.hold_reason || 'needs review'}</span></div>
                      <div>source · <span style={{color:'var(--ink)'}}>{a.source || '—'}</span></div>
                    </div>
                    <div className="tar-actions">
                      <button className="btn sm" onClick={() => onNavigate({view:'lead', id:a.contact_id})}>Open thread</button>
                      <button className="btn sm" onClick={() => dismiss(a)} title="Dismiss without sending or learning from this">Dismiss</button>
                      <button className="btn sm" onClick={() => reject(a)}>Reject</button>
                      <button className="btn sm primary" onClick={() => approve(a)} disabled={a.status === 'context_requested'}>Approve</button>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      )}

      {tab === 'history' && (
        <div className="card">
          <div className="hd">
            <div className="title">— <b>Sent messages</b> · recent</div>
            <div className="aside">
              <span style={{fontFamily:'var(--mono)', fontSize:11, color:'var(--muted)'}}>{msgs.length} shown</span>
            </div>
          </div>
          <div className="bd p0">
            {msgs.length === 0 && !history.loading && <div className="empty">No messages yet.</div>}
            {msgs.length > 0 && (
              <table className="tbl">
                <thead>
                  <tr>
                    <th style={{paddingLeft:20}}>Contact</th>
                    <th>Direction</th>
                    <th>Message</th>
                    <th style={{textAlign:'right'}}>Sent</th>
                  </tr>
                </thead>
                <tbody>
                  {msgs.map((m, i) => {
                    const isOut = (m.direction || '').toLowerCase() === 'outbound' || m.direction === 'auto' || m.direction === 'approved';
                    const typeColor = isOut ? 'var(--green)' : 'var(--blue)';
                    const typeBg    = isOut ? 'var(--green-soft)' : 'var(--blue-soft)';
                    return (
                      <tr key={m.id || i} onClick={() => m.contact_id && onNavigate({view:'lead', id:m.contact_id})}>
                        <td className="name" style={{paddingLeft:20}}>{m.contact_name || m.contact_id || '—'}</td>
                        <td>
                          <span style={{
                            fontFamily:'var(--mono)', fontSize:10,
                            padding:'2px 8px', borderRadius:10,
                            color: typeColor, background: typeBg,
                            letterSpacing:'0.04em', textTransform:'uppercase',
                          }}>{isOut ? 'outbound' : 'inbound'}</span>
                        </td>
                        <td style={{maxWidth:560, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', color:'var(--muted)'}}>{m.message}</td>
                        <td className="mono" style={{textAlign:'right'}}>{fmtAgoFrom(m.sent_at)}</td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            )}
          </div>
        </div>
      )}

      {tab === 'training' && (
        <div className="card">
          <div className="hd">
            <div className="title">— <b>Training library</b></div>
            <div className="aside">
              <span style={{fontFamily:'var(--mono)', fontSize:11, color:'var(--muted)'}}>
                {training.data?.total ?? 0} examples · few-shot memory for Tommy
              </span>
            </div>
          </div>
          <div style={{padding:'12px 18px', display:'flex', gap:10, alignItems:'center', flexWrap:'wrap', borderBottom:'1px solid var(--line-2)'}}>
            <input
              type="text"
              placeholder="Search inbound or staff reply…"
              value={trainingSearch}
              onChange={e => setTrainingSearch(e.target.value)}
              style={{
                flex:1, minWidth:220, height:32, padding:'0 12px',
                border:'1px solid var(--line)', borderRadius:'var(--radius-sm)',
                background:'var(--bone-2)', fontSize:13, outline:'none',
              }}
            />
            <div style={{display:'flex', gap:6, flexWrap:'wrap'}}>
              <button
                className={'btn sm' + (!topicFilter ? ' primary' : '')}
                onClick={() => setTopicFilter('')}
              >All</button>
              {(training.data?.topics || []).map(t => (
                <button
                  key={t.topic}
                  className={'btn sm' + (topicFilter === t.topic ? ' primary' : '')}
                  onClick={() => setTopicFilter(t.topic)}
                >
                  {t.topic} <span style={{color:'var(--muted-2)', marginLeft:4, fontFamily:'var(--mono)', fontSize:10}}>{t.n}</span>
                </button>
              ))}
            </div>
          </div>
          <div className="bd p0">
            {training.loading && <div className="empty">Loading training library…</div>}
            {!training.loading && (training.data?.items || []).length === 0 && (
              <div className="empty">
                No learned responses yet. When staff coach a Tommy draft or send their own reply, it's stored here as a few-shot example.
              </div>
            )}
            {(training.data?.items || []).map(item => (
              <TrainingRow key={item.id} item={item} onReload={() => training.reload()} />
            ))}
          </div>
        </div>
      )}

      {tab === 'config' && (
        <div className="card">
          <div className="hd"><div className="title">— <b>Tommy configuration</b></div></div>
          <div className="bd" style={{fontFamily:'var(--mono)', fontSize:12, color:'var(--muted)', lineHeight:1.8, letterSpacing:'0.02em'}}>
            <div>MODEL · <span style={{color:'var(--ink)'}}>{config.data?.model || '—'}</span></div>
            <div>MEMORY SOURCE · <span style={{color:'var(--ink)'}}>{config.data?.memory_source || '—'}</span></div>
            <div>TONE · <span style={{color:'var(--ink)'}}>{config.data?.tone || '—'}</span></div>
            <div>ROUTING · <span style={{color:'var(--ink)'}}>{config.data?.contact_routing || '—'}</span></div>
            <div style={{marginTop:12}}>APPROVAL TRIGGERS:</div>
            <ul style={{margin:'6px 0 0 20px', padding:0, fontFamily:'var(--sans)', fontSize:13, color:'var(--ink)', lineHeight:1.6}}>
              {(config.data?.approval_triggers || []).map((t, i) => <li key={i}>{t}</li>)}
            </ul>
          </div>
        </div>
      )}
    </div>
  );
}

function TrainingRow({ item, onReload }) {
  const [editing, setEditing] = React.useState(false);
  const [saving, setSaving] = React.useState(false);
  const [staffResponse, setStaffResponse] = React.useState(item.staff_response || '');
  const [topic, setTopic] = React.useState(item.topic || '');

  React.useEffect(() => {
    setStaffResponse(item.staff_response || '');
    setTopic(item.topic || '');
  }, [item.id]);

  async function save() {
    if (!staffResponse.trim()) { alert('Staff response cannot be empty.'); return; }
    setSaving(true);
    try {
      await api.patch(`/api/v2/tommy/learned-responses/${item.id}`, {
        staff_response: staffResponse.trim(),
        topic: topic.trim() || null,
      });
      setEditing(false);
      await onReload();
    } catch (e) { alert(e.message || 'Save failed'); }
    finally { setSaving(false); }
  }

  async function remove() {
    if (!confirm('Remove this example from Tommy\'s training library?')) return;
    try {
      await api.del(`/api/v2/tommy/learned-responses/${item.id}`);
      await onReload();
    } catch (e) { alert(e.message || 'Delete failed'); }
  }

  function cancel() {
    setStaffResponse(item.staff_response || '');
    setTopic(item.topic || '');
    setEditing(false);
  }

  return (
    <div style={{
      padding:'16px 20px',
      borderBottom:'1px solid var(--line-2)',
    }}>
      <div style={{display:'flex', alignItems:'center', gap:10, marginBottom:10}}>
        {editing ? (
          <input
            type="text"
            placeholder="topic (e.g. hours, pricing, cancel)"
            value={topic}
            onChange={e => setTopic(e.target.value)}
            style={{
              height:22, padding:'0 10px',
              border:'1px solid var(--line)', borderRadius:11,
              fontFamily:'var(--mono)', fontSize:11, letterSpacing:'0.04em',
              background:'#fff', outline:'none', minWidth:120,
            }}
          />
        ) : (
          item.topic ? (
            <span className="chip" style={{background:'var(--bone-3)', color:'var(--ink)'}}>
              <span className="dot" />{item.topic}
            </span>
          ) : (
            <span className="chip" style={{background:'var(--bone-2)', color:'var(--muted-2)'}}>
              <span className="dot" />untagged
            </span>
          )
        )}
        {item.was_edited && (
          <span style={{
            fontFamily:'var(--mono)', fontSize:9, letterSpacing:'0.14em', textTransform:'uppercase',
            color:'var(--blue)', background:'var(--blue-soft)', padding:'2px 7px', borderRadius:10,
          }}>coached</span>
        )}
        <span style={{fontFamily:'var(--mono)', fontSize:10, letterSpacing:'0.04em', color:'var(--muted)'}}>
          {fmtAgoFrom(item.created_at)}
        </span>
        <div style={{marginLeft:'auto', display:'flex', gap:6}}>
          {!editing && (
            <>
              <button className="btn sm" onClick={() => setEditing(true)}>Edit</button>
              <button className="btn sm" onClick={remove} style={{color:'var(--warn)'}}>Delete</button>
            </>
          )}
          {editing && (
            <>
              <button className="btn sm" onClick={cancel} disabled={saving}>Cancel</button>
              <button className="btn sm primary" onClick={save} disabled={saving}>{saving ? 'Saving…' : 'Save'}</button>
            </>
          )}
        </div>
      </div>

      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
        <div>
          <div className="kicker" style={{marginBottom:6}}>— Inbound</div>
          <div style={{padding:'10px 14px', background:'var(--bone-2)', borderRadius:4, fontSize:13, lineHeight:1.5}}>
            {item.inbound_message}
          </div>
          {item.tommy_draft && (
            <>
              <div className="kicker" style={{marginTop:10, marginBottom:6}}>— Tommy's original draft</div>
              <div style={{padding:'10px 14px', background:'var(--bone)', borderLeft:'2px solid var(--muted-2)', borderRadius:4, fontSize:13, lineHeight:1.5, color:'var(--muted)'}}>
                {item.tommy_draft}
              </div>
            </>
          )}
        </div>
        <div>
          <div className="kicker" style={{marginBottom:6}}>
            — Staff reply {item.was_edited ? '· edited by staff' : '· used as-is'}
          </div>
          {editing ? (
            <textarea
              value={staffResponse}
              onChange={e => setStaffResponse(e.target.value)}
              rows={5}
              style={{
                width:'100%', padding:'10px 14px',
                background:'#fff', border:'1px solid var(--ink)', borderRadius:4,
                fontFamily:'var(--sans)', fontSize:13, lineHeight:1.5,
                outline:'none', resize:'vertical',
              }}
              disabled={saving}
            />
          ) : (
            <div style={{padding:'10px 14px', background:'var(--bone)', borderLeft:'2px solid var(--signal)', borderRadius:4, fontSize:13, lineHeight:1.5}}>
              {item.staff_response}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { TommyView });
