// tab-contacts.jsx — the address book: a superset of the pipeline.
// Everyone synced from your Google contacts lives here; a row is "in pipeline"
// only once you promote it. Also the source for composer To-field autocomplete.
const { useState: useStateCt, useEffect: useEffectCt, useMemo: useMemoCt } = React;
const RSct = window.RaiseShell;

function ContactTr({ b, onAdd, busyId, selected, onToggle }){
  const inPipe = !!b.contactId;
  const open = ()=>{ if(inPipe && window.RaiseStore) window.RaiseStore.openPerson(b.contactId); };
  return (
    <tr className={(inPipe?'ctbl-inpipe':'')+(selected?' ctbl-sel':'')} onClick={open}>
      <td className="ctbl-chk" onClick={e=>e.stopPropagation()}>
        <input type="checkbox" checked={!!selected} onChange={()=>onToggle(b.id)} />
      </td>
      <td className="ctbl-name">
        <RSct.Avatar name={b.name || b.email || '?'} />
        <span className="ctbl-nm">{b.name || <span className="muted">(no name)</span>}</span>
      </td>
      <td>{b.org || '—'}</td>
      <td className="mono ctbl-em">{b.email || '—'}</td>
      <td className="mono">{b.phone || '—'}</td>
      <td>{b.location || '—'}</td>
      <td>{b.source==='mail' ? <span className="ctc-srctag" title="Auto-saved from mail">mail</span> : 'Google'}</td>
      <td className="ctbl-act">
        {inPipe
          ? <span className="ctc-pipe">✓ In pipeline</span>
          : <button className="btn sm" disabled={busyId===b.id}
              onClick={e=>{ e.stopPropagation(); onAdd(b); }}>{busyId===b.id?'Adding…':'＋ Pipeline'}</button>}
      </td>
    </tr>
  );
}

// windowed page numbers with ellipses (shared shape with the pipeline pager)
function pageNums(cur, total){
  if(total<=7) return Array.from({length:total},(_,i)=>i+1);
  const set=new Set([1,2,total-1,total,cur-1,cur,cur+1]);
  const arr=[...set].filter(n=>n>=1&&n<=total).sort((a,b)=>a-b);
  const out=[]; let prev=0;
  for(const n of arr){ if(prev && n-prev>1) out.push('…'); out.push(n); prev=n; }
  return out;
}
function Pager({ page, pageCount, total, start, size, onPage, onSize }){
  if(total===0) return null;
  return (
    <div className="rpg-bar">
      <div className="rpg-l mono">Showing {start+1}–{Math.min(start+size, total)} of {total}</div>
      <div className="rpg-nav">
        <button className="rpg-btn" disabled={page<=1} onClick={()=>onPage(page-1)}>‹</button>
        {pageNums(page, pageCount).map((n,i)=> n==='…'
          ? <span key={'e'+i} className="rpg-ell">…</span>
          : <button key={n} className={'rpg-btn'+(n===page?' on':'')} onClick={()=>onPage(n)}>{n}</button>)}
        <button className="rpg-btn" disabled={page>=pageCount} onClick={()=>onPage(page+1)}>›</button>
      </div>
      <div className="rpg-r">
        <span className="rpg-lbl mono">Per page</span>
        {[20,50,100].map(n=> <button key={n} className={'rpg-sz'+(size===n?' on':'')} onClick={()=>onSize(n)}>{n}</button>)}
      </div>
    </div>
  );
}
window.RaisePager = Pager;   // reused by the Pipeline footer

function TabContacts(){
  const { TopBar } = RSct;
  const LD = window.RaiseLiveData;
  const [,bump] = useStateCt(0);
  const [q, setQ] = useStateCt('');
  const [busy, setBusy] = useStateCt(false);
  const [busyId, setBusyId] = useStateCt(null);
  useEffectCt(()=>{
    const h=()=>bump(x=>x+1); window.addEventListener('raise-livedata',h);
    if(LD && !LD.isBookLive()) LD.loadBook();
    return ()=>window.removeEventListener('raise-livedata',h);
  },[]);

  const book = (LD && LD.book()) || [];
  const filtered = useMemoCt(()=>{
    const s = q.trim().toLowerCase();
    let list = book;
    if(s) list = book.filter(b => (b.name && b.name.toLowerCase().includes(s)) || (b.email && b.email.toLowerCase().includes(s)));
    return list;
  }, [book, q]);
  const inPipeCount = book.filter(b=>b.contactId).length;

  const sync = async ()=>{
    setBusy(true);
    const r = await LD.syncBook();
    setBusy(false);
    if(r.ok) RSct.toast('Synced '+r.count+' contacts from Google');
    else if(r.error==='paused') RSct.toast('Live is paused — turn it on in Settings → Google');
    else if(r.error==='not_connected' || /not_connected/.test(r.error||'')) RSct.toast('Reconnect Google in Settings to grant contacts access');
    else RSct.toast('Sync failed — '+(r.error||'error'));
  };
  const add = async (b)=>{
    setBusyId(b.id);
    const r = await LD.addBookToPipeline(b.id);
    setBusyId(null);
    RSct.toast(r.ok ? (b.name||b.email)+' added to pipeline' : 'Couldn’t add — '+(r.error||'error'));
  };

  // ── bulk selection (persists across pages, keyed by id) ──
  const [sel, setSel] = useStateCt(()=> new Set());
  const toggle = (id)=> setSel(s=>{ const n=new Set(s); n.has(id)?n.delete(id):n.add(id); return n; });
  const clearSel = ()=> setSel(new Set());
  const selIds = [...sel];
  const bulkDelete = async ()=>{
    if(!window.confirm('Delete '+selIds.length+' contact'+(selIds.length===1?'':'s')+' from your address book? (Does not affect anyone already in the pipeline.)')) return;
    const r = await LD.bulkDeleteBook(selIds);
    if(r.ok){ RSct.toast('Deleted '+r.count+' contacts'); clearSel(); } else RSct.toast('Failed — '+(r.error||'error'));
  };
  const bulkAdd = async ()=>{
    const r = await LD.bulkAddBookToPipeline(selIds);
    if(r.ok){ RSct.toast('Added '+r.count+' to pipeline'); clearSel(); } else RSct.toast('Failed — '+(r.error||'error'));
  };

  const [pageSize, setPageSize] = useStateCt(50);
  const [page, setPage] = useStateCt(1);
  const pageCount = Math.max(1, Math.ceil(filtered.length / pageSize));
  const pageC = Math.min(page, pageCount);
  useEffectCt(()=>{ setPage(1); }, [q, pageSize, book.length]);
  const start = (pageC - 1) * pageSize;
  const shown = filtered.slice(start, start + pageSize);
  return (
    <>
      <TopBar title="Contacts" sub={book.length ? book.length+' contacts · '+inPipeCount+' in pipeline' : 'your address book'}>
        <input className="ctc-search" placeholder="Search name or email" value={q} onChange={e=>setQ(e.target.value)} />
        <button className="btn sm ic" disabled={busy} onClick={sync} title="Pull your Google contacts">{busy?'Syncing…':<><window.Ico n="refresh" size={13} /> Sync from Google</>}</button>
      </TopBar>
      {sel.size>0 && (
        <div className="bulkbar">
          <span className="bulkbar-c">{sel.size} selected</span>
          <button className="btn sm" onClick={bulkAdd}>＋ Add to pipeline</button>
          <button className="btn sm danger" onClick={bulkDelete}>Delete</button>
          <button className="linkbtn" onClick={clearSel} style={{marginLeft:'auto'}}>Clear</button>
        </div>
      )}
      <div className="ctc-wrap scroll">
        {book.length===0 ? (
          <div className="ctc-empty">
            <div className="ctc-empty-ic">◑</div>
            <div className="ctc-empty-t">No contacts yet</div>
            <div className="ctc-empty-s">Sync your Google address book to autofill the composer and build your pipeline from people you already know. First time needs a one-time reconnect in Settings → Google to grant contacts access.</div>
            <button className="btn primary sm ic" disabled={busy} onClick={sync} style={{marginTop:14}}>{busy?'Syncing…':<><window.Ico n="refresh" size={13} /> Sync from Google</>}</button>
          </div>
        ) : filtered.length===0 ? (
          <div className="ctc-empty-s" style={{textAlign:'center',padding:'30px'}}>No contacts match “{q}”.</div>
        ) : (
          <table className="ctbl">
            <thead>
              <tr>
                <th className="ctbl-chk"><input type="checkbox"
                  checked={shown.length>0 && shown.every(b=>sel.has(b.id))}
                  onChange={e=>{ const ids=shown.map(b=>b.id); setSel(s=>{ const n=new Set(s); if(e.target.checked) ids.forEach(i=>n.add(i)); else ids.forEach(i=>n.delete(i)); return n; }); }} /></th>
                <th>Name</th><th>Firm</th><th>Email</th><th>Phone</th><th>Location</th><th>Source</th><th></th>
              </tr>
            </thead>
            <tbody>
              {shown.map(b => <ContactTr key={b.id} b={b} onAdd={add} busyId={busyId} selected={sel.has(b.id)} onToggle={toggle} />)}
            </tbody>
          </table>
        )}
      </div>
      {book.length>0 && filtered.length>0 &&
        <Pager page={pageC} pageCount={pageCount} total={filtered.length} start={start} size={pageSize} onPage={setPage} onSize={setPageSize} />}
    </>
  );
}
window.TabContacts = TabContacts;
