// Leads — filterable table wired to GET /api/v2/leads and GET /pipeline-counts.

function LeadCard({ c, onClick }) {
  return (
    <div className="lead-card" onClick={onClick}>
      <span className="avatar lc-avatar">{initialsOf(c.name)}</span>
      <div className="lc-body">
        <div className="lc-top">
          <span className="lc-name">{c.name}</span>
          {c.hot && <span className="lc-hot">HOT</span>}
        </div>
        <div className="lc-phone">{c.phone || c.email || '—'}</div>
        <div className="lc-meta">
          <span className={'chip stage-' + c.stage}><span className="dot" />{(c.stage_raw || c.stage || '').toLowerCase()}</span>
          {c.tommy_status === 'pending_approval' && <span className="chip tommy-pending"><span className="dot" />pending</span>}
          {c.tommy_status === 'unanswered' && <span className="chip tommy-unanswered"><span className="dot" />unread</span>}
          {c.scheduled_label && <span className="lc-sched">{c.scheduled_label}</span>}
          {c.source && <span className="lc-source">{c.source}</span>}
        </div>
      </div>
      <div className="lc-time">{fmtAgo(c.lastActivity)}</div>
    </div>
  );
}

function LeadsView({ onNavigate, initialFilter, onOpenLead }) {
  const isMobile = useMediaQuery('(max-width: 480px)');
  const [filter, setFilter] = React.useState(initialFilter || 'all');
  const [q, setQ] = React.useState('');
  const [debouncedQ, setDebouncedQ] = React.useState('');
  const [loading, setLoading] = React.useState(true);
  const [leads, setLeads] = React.useState([]);
  const [total, setTotal] = React.useState(0);
  // Bumped when a new lead is created from the modal; the main fetch
  // useEffect depends on it and re-runs.
  const [refreshKey, setRefreshKey] = React.useState(0);
  const pipeline = useAsync(() => api.get('/api/v2/pipeline-counts'), []);

  React.useEffect(() => {
    function onLead() {
      setRefreshKey(k => k + 1);
      pipeline.reload();
    }
    window.addEventListener('raw:lead-created', onLead);
    return () => window.removeEventListener('raw:lead-created', onLead);
  }, [pipeline.reload]);

  React.useEffect(() => {
    const t = setTimeout(() => setDebouncedQ(q.trim()), 250);
    return () => clearTimeout(t);
  }, [q]);

  React.useEffect(() => {
    let live = true;
    setLoading(true);
    const qs = new URLSearchParams({ limit: '200' });
    if (debouncedQ) qs.set('search', debouncedQ);
    // Each filter sends the same stages that contribute to its chip
    // count below (sumStages() calls). Keeping these in sync means
    // clicking "Booked 104" actually returns 104 rows — previously
    // it sent only DAY PASS SCHEDULED and returned 100, dropping
    // the 4 SHOWED + 0 FDP BOOKED rows. Backend accepts a
    // comma-separated list (see leads.py /api/v2/leads).
    const stageByFilter = {
      new: 'NEW LEAD,FIRST TOUCH',
      contacted: 'INTERESTED,BOT ENGAGED,FOLLOW UP',
      booked: 'DAY PASS SCHEDULED,SHOWED,FDP BOOKED',
      reschedule: 'NEEDS_RESCHEDULE',
      member: 'MEMBER',
      churned: 'DEAD,NO SHOW,LOST',
    };
    if (filter === 'hot') qs.set('hot', 'true');
    else if (stageByFilter[filter]) qs.set('stage', stageByFilter[filter]);

    api.get('/api/v2/leads?' + qs.toString())
      .then(r => {
        if (!live) return;
        const rows = (r?.leads || []).map(adaptLead);
        cacheContacts(rows);
        setLeads(rows);
        setTotal(r?.total || rows.length);
      })
      .catch(() => { if (live) { setLeads([]); setTotal(0); } })
      .finally(() => { if (live) setLoading(false); });
    return () => { live = false; };
  }, [filter, debouncedQ, refreshKey]);

  const pipelineCounts = pipeline.data?.counts || {};
  const totalAll = pipeline.data?.total || 0;
  const hotCount = pipeline.data?.hot_leads || 0;

  // UI filter chips; counts come from pipeline when available
  function sumStages(...stages) {
    return stages.reduce((s, k) => s + (pipelineCounts[k] || 0), 0);
  }
  const filters = [
    { id: 'all',         label: 'All',         count: totalAll },
    { id: 'hot',         label: 'Hot',         count: hotCount },
    { id: 'new',         label: 'New',         count: sumStages('NEW LEAD', 'FIRST TOUCH') },
    { id: 'contacted',   label: 'Contacted',   count: sumStages('INTERESTED', 'BOT ENGAGED', 'FOLLOW UP') },
    { id: 'booked',      label: 'Booked',      count: sumStages('DAY PASS SCHEDULED', 'SHOWED', 'FDP BOOKED') },
    { id: 'reschedule',  label: 'Reschedule',  count: sumStages('NEEDS_RESCHEDULE') },
    { id: 'member',      label: 'Members',     count: pipeline.data?.member_count || 0 },
    { id: 'churned',     label: 'Churned',     count: sumStages('DEAD', 'NO SHOW', 'LOST') },
  ];

  // Client-side filter for free-text search on the loaded page
  const rows = React.useMemo(() => {
    if (!debouncedQ) return leads;
    const n = debouncedQ.toLowerCase();
    return leads.filter(c =>
      (c.name || '').toLowerCase().includes(n) ||
      (c.phone || '').toLowerCase().includes(n) ||
      (c.email || '').toLowerCase().includes(n)
    );
  }, [leads, debouncedQ]);

  return (
    <div className="app-main">
      <div className="page-hd">
        <div>
          <div className="kicker" style={{marginBottom:8}}>— Leads &amp; contacts</div>
          <h1>All contacts</h1>
          <div className="sub">
            {pipeline.data?.source === 'db' ? 'Synced from GoHighLevel' : 'Live from GHL'} · {totalAll} total · {hotCount} hot
          </div>
        </div>
        <div className="actions">
          <button className="btn" onClick={async () => {
            try {
              const r = await api.post('/api/v2/leads/auto-flag-hot', {});
              alert('Hot re-scored. ' + (r?.flagged != null ? `${r.flagged} contacts updated.` : ''));
              pipeline.reload();
            } catch (e) { alert(e.message || 'Re-score failed'); }
          }} title="Re-evaluate hot flag across all contacts based on stage + recency">Re-score hot</button>
          <button className="btn" onClick={async () => {
            try { await api.post('/api/v2/admin/sync-contacts', {}); alert('Sync started in background'); }
            catch (e) { alert(e.message || 'Sync failed'); }
          }}>Sync now</button>
          <button className="btn primary" onClick={() => onOpenLead?.()}>+ New lead</button>
        </div>
      </div>

      <div className="leads-toolbar">
        {filters.map(f => (
          <button
            key={f.id}
            className={'flt' + (filter===f.id ? ' active' : '')}
            onClick={() => setFilter(f.id)}
          >
            {f.label} <span className="cnt">{f.count}</span>
          </button>
        ))}
        <div className="spacer" />
        <input
          value={q}
          onChange={e => setQ(e.target.value)}
          placeholder="Filter by name, phone, email…"
          style={{
            height:26, padding:'0 10px', fontSize:12,
            border:'1px solid var(--line)', background:'var(--bone)',
            borderRadius:14, outline:'none', minWidth:240,
            fontFamily:'var(--sans)',
          }}
        />
        <span className="mono-meta">{rows.length} rows{loading ? ' · loading…' : ''}</span>
      </div>

      {isMobile ? (
        <div className="leads-cards">
          {!loading && rows.length === 0 && <div className="empty">No contacts match this filter.</div>}
          {rows.map(c => (
            <LeadCard key={c.id} c={c} onClick={() => onNavigate({view:'lead', id:c.id})} />
          ))}
        </div>
      ) : (
        <div className="leads-table-wrap">
          <table className="tbl">
            <thead>
              <tr>
                <th>Name</th>
                <th>Stage</th>
                <th>Source</th>
                <th>Tags</th>
                <th>Tommy</th>
                <th>Scheduled</th>
                <th style={{textAlign:'right'}}>Last activity</th>
              </tr>
            </thead>
            <tbody>
              {!loading && rows.length === 0 && (
                <tr><td colSpan="7"><div className="empty">No contacts match this filter.</div></td></tr>
              )}
              {rows.map(c => (
                <tr key={c.id} onClick={() => onNavigate({view:'lead', id:c.id})}>
                  <td className="name">
                    <div style={{display:'flex', alignItems:'center', gap:10}}>
                      <span className="avatar" style={{width:26, height:26, fontSize:10, background:'var(--bone-3)', color:'var(--ink)'}}>
                        {initialsOf(c.name)}
                      </span>
                      <div>
                        <div>{c.name} {c.hot && <span style={{marginLeft:6, color:'var(--warn)', fontFamily:'var(--mono)', fontSize:10}}>· HOT</span>}</div>
                        <div style={{fontFamily:'var(--mono)', fontSize:11, color:'var(--muted)'}}>{c.phone || c.email || '—'}</div>
                      </div>
                    </div>
                  </td>
                  <td><span className={'chip stage-' + c.stage}><span className="dot" />{c.stage_raw || c.stage}</span></td>
                  <td className="mono">{c.source || '—'}</td>
                  <td>
                    <div style={{display:'flex', gap:4, flexWrap:'wrap'}}>
                      {(c.tags || []).slice(0, 3).map(t => (
                        <span key={t} className="chip" style={{height:18, padding:'0 6px', fontSize:10}}>{String(t)}</span>
                      ))}
                    </div>
                  </td>
                  <td>
                    {c.tommy_status === 'pending_approval' && <span className="chip tommy-pending"><span className="dot" />pending</span>}
                    {c.tommy_status === 'unanswered' && <span className="chip tommy-unanswered"><span className="dot" />unread</span>}
                    {c.tommy_status === 'idle' && (c.tommy_contacted ? <span style={{color:'var(--muted-2)', fontSize:11, fontFamily:'var(--mono)'}}>contacted</span> : <span style={{color:'var(--muted-2)', fontSize:11, fontFamily:'var(--mono)'}}>—</span>)}
                  </td>
                  <td className="mono">{c.scheduled_label || '—'}</td>
                  <td className="mono" style={{textAlign:'right'}}>{fmtAgo(c.lastActivity)}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { LeadsView });
