// crm-leads.jsx — Leads List + Lead Detail Modal
const { useState, useEffect, useCallback, useRef } = React;

const ACT_ICONS = { note:'📝', call:'📞', email:'📧', meeting:'🤝', proposal:'📄' };
const ACT_TYPES = ['note','call','email','meeting','proposal'];

// ── NOTE TEXT — preserves line breaks; long notes truncate ──
// Whitespace/line breaks render as typed (pre-wrap). Notes longer
// than `limit` show the first `limit` characters with a View toggle.
function NoteText({ text, limit = 500 }) {
  const [expanded, setExpanded] = useState(false);
  const s = String(text || '');
  const long = s.length > limit;
  const shown = expanded || !long ? s : s.slice(0, limit).trimEnd() + '…';
  return (
    <span style={{ whiteSpace:'pre-wrap', overflowWrap:'break-word' }}>
      {shown}
      {long && (
        <button onClick={() => setExpanded(x => !x)}
          style={{ background:'none', border:'none', cursor:'pointer', color:'var(--blue)', fontSize:12, fontWeight:600, padding:'0 4px', fontFamily:'var(--font)' }}>
          {expanded ? 'View less' : 'View'}
        </button>
      )}
    </span>
  );
}

// ── STAGE PIPELINE — clickable colored chevron arrows ──
// All stages render as chevron-shaped buttons in a row. Stages
// at-or-before the current stage are filled with their color;
// later stages are dimmed. Clicking any chevron sets the stage.
function StagePipeline({ currentStage, onChange }) {
  const stages = CRM.STAGES || [];
  const curIdx = stages.findIndex(s => s.id === currentStage);
  // Lost is special — render as a "side exit" pill rather than in the flow
  const flow = stages.filter(s => s.id !== 'lost');
  const lost = stages.find(s => s.id === 'lost');

  const chevronClip = (isFirst, isLast) => {
    if (isFirst) return 'polygon(0 0, calc(100% - 14px) 0, 100% 50%, calc(100% - 14px) 100%, 0 100%)';
    if (isLast)  return 'polygon(0 0, 100% 0, 100% 100%, 0 100%, 14px 50%)';
    return 'polygon(0 0, calc(100% - 14px) 0, 100% 50%, calc(100% - 14px) 100%, 0 100%, 14px 50%)';
  };

  return (
    <div style={{ display:'flex', alignItems:'center', gap:8, flexWrap:'wrap' }}>
      <div style={{ display:'flex', flex:'1 1 auto', minWidth:0 }}>
        {flow.map((s, i) => {
          const isFirst  = i === 0;
          const isLast   = i === flow.length - 1;
          const stageIdx = stages.findIndex(x => x.id === s.id);
          const isActive = curIdx >= 0 && curIdx === stageIdx;
          const isDone   = curIdx >= 0 && stageIdx < curIdx && currentStage !== 'lost';
          const filled   = isActive || isDone;
          const bg       = filled ? s.color : '#F1F3F6';
          const fg       = filled ? '#fff'  : '#5A6478';
          return (
            <button key={s.id} type="button" onClick={() => onChange(s)}
              title={s.label}
              style={{
                flex:'1 1 0', minWidth:0, padding:'10px 18px 10px 22px',
                marginRight: isLast ? 0 : -10,
                fontSize:12, fontWeight:700, letterSpacing:'.02em',
                background: bg, color: fg, border:'none',
                clipPath: chevronClip(isFirst, isLast),
                cursor:'pointer', whiteSpace:'nowrap',
                transition:'background .15s, transform .12s',
                transform: isActive ? 'scale(1.02)' : 'none',
                boxShadow: isActive ? '0 1px 6px rgba(0,0,0,.18)' : 'none',
                position:'relative', zIndex: isActive ? 2 : (isDone ? 1 : 0),
              }}>
              {s.label}
            </button>
          );
        })}
      </div>
      {lost && (
        <button type="button" onClick={() => onChange(lost)}
          title="Mark as Closed Lost"
          style={{
            flex:'0 0 auto', padding:'8px 14px', fontSize:12, fontWeight:700,
            borderRadius:6, cursor:'pointer', whiteSpace:'nowrap',
            border: currentStage === 'lost' ? `1.5px solid ${lost.color}` : '1.5px solid var(--g200)',
            background: currentStage === 'lost' ? lost.color : '#fff',
            color: currentStage === 'lost' ? '#fff' : 'var(--g600)',
          }}>✕ {lost.label}</button>
      )}
    </div>
  );
}


// ── LEADS LIST ──
function Leads({ user, showToast, quickAdd, openLeadId, onOpenedLead }) {
  const [leads,          setLeads]          = useState([]);
  const [search,         setSearch]         = useState('');
  const [stageFilter,    setStageFilter]    = useState('');
  const [repFilter,      setRepFilter]      = useState(user.role === 'rep' && !user.isAdmin ? user.id : '');
  const [industryFilter, setIndustryFilter] = useState('');
  const [statusFilter,   setStatusFilter]   = useState('active');  // active | inactive | all
  const [overdueOnly,    setOverdueOnly]    = useState(false);
  const [sortCol,        setSortCol]        = useState('updatedAt');
  const [sortDir,        setSortDir]        = useState('desc');
  const [selected,       setSelected]       = useState(null);
  const [showAdd,        setShowAdd]        = useState(false);
  const [showImport,     setShowImport]     = useState(false);
  const [loading,        setLoading]        = useState(false);

  useEffect(() => { if (quickAdd) setShowAdd(true); }, [quickAdd]);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const filters = {};
      if (repFilter)   filters.repId  = repFilter;
      if (search)      filters.search = search;
      if (stageFilter) filters.stage  = stageFilter;
      if (statusFilter !== 'active') filters.showInactive = true;
      const results = await CRM.LeadsAPI.getAll(filters);
      setLeads(results);
    } catch (e) {
      showToast('Failed to load leads: ' + e.message, 'error');
    } finally {
      setLoading(false);
    }
  }, [search, stageFilter, repFilter, statusFilter]);

  useEffect(() => { load(); }, [load]);

  // Deep-link from dashboard/global search: open a specific lead's detail.
  // Fetched by id so it works even when the lead is filtered out (inactive).
  useEffect(() => {
    if (!openLeadId) return;
    CRM.LeadsAPI.getById(openLeadId)
      .then(setSelected)
      .catch(() => showToast('Lead not found (it may be outside your assignments).', 'default'))
      .finally(() => onOpenedLead?.());
  }, [openLeadId]);

  const reps       = CRM.UsersAPI.getAll().filter(u => u.role === 'rep');
  const today      = new Date().toISOString().split('T')[0];
  const industries = [...new Set(leads.map(l => l.industry).filter(Boolean))].sort();

  // ── Client-side filtering ──────────────────────────────────
  // Bounded render — never mount every lead row at once (renderer OOM)
  const [rowCap, setRowCap] = useState(100);
  useEffect(() => { setRowCap(100); }, [search, stageFilter, repFilter, industryFilter, statusFilter, overdueOnly]);

  let displayed = leads;
  if (statusFilter === 'inactive') displayed = displayed.filter(l => l.isActive === false);
  if (industryFilter) displayed = displayed.filter(l => l.industry === industryFilter);
  if (overdueOnly)    displayed = displayed.filter(l =>
    l.followUpDate && l.followUpDate < today && !['won','lost'].includes(l.stage));

  // ── Client-side sorting ────────────────────────────────────
  const toggleSort = col => {
    if (sortCol === col) setSortDir(d => d === 'asc' ? 'desc' : 'asc');
    else { setSortCol(col); setSortDir('asc'); }
  };

  displayed = [...displayed].sort((a, b) => {
    let av, bv;
    if (sortCol === 'assignedRep') {
      av = (CRM.UsersAPI.getById(a.assignedRepId) || a.assignedRep)?.name || '';
      bv = (CRM.UsersAPI.getById(b.assignedRepId) || b.assignedRep)?.name || '';
    } else {
      av = a[sortCol] ?? '';
      bv = b[sortCol] ?? '';
    }
    if (typeof av === 'number' && typeof bv === 'number')
      return sortDir === 'asc' ? av - bv : bv - av;
    return sortDir === 'asc'
      ? String(av).localeCompare(String(bv))
      : String(bv).localeCompare(String(av));
  });

  // ── Sortable column header ─────────────────────────────────
  const Th = ({ col, label, style }) => {
    const active = sortCol === col;
    return (
      <th onClick={() => toggleSort(col)}
        style={{cursor:'pointer', userSelect:'none', whiteSpace:'nowrap', ...style}}>
        {label}
        <span style={{marginLeft:4, fontSize:9, opacity: active ? 0.85 : 0.18}}>
          {active && sortDir === 'asc' ? ' ▲' : ' ▼'}
        </span>
      </th>
    );
  };

  const exportCSV = () => {
    const headers = ['Company','Contact','Title','Email','Phone','Industry','Employees','Source','Stage','Value','Rep','Follow-Up','Created'];
    const rows = leads.map(l => {
      const rep = CRM.UsersAPI.getById(l.assignedRepId);
      return [l.companyName,l.contactName,l.contactTitle,l.contactEmail,l.contactPhone,
        l.industry,l.employeeCount,l.leadSource,l.stage,l.estimatedValue,
        rep?.name||'',l.followUpDate||'',l.createdAt].map(v => `"${(v||'').toString().replace(/"/g,'""')}"`).join(',');
    });
    const csv = [headers.join(','),...rows].join('\n');
    const a = document.createElement('a');
    a.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv);
    a.download = 'CTR-NY-Leads.csv';
    a.click();
    showToast('Exported to CSV!', 'success');
  };

  const handleUpdate = async () => {
    await load();
    if (selected) {
      try {
        const refreshed = await CRM.LeadsAPI.getById(selected.id);
        setSelected(refreshed);
      } catch { setSelected(null); }
    }
  };

  const hasClientFilters = industryFilter || overdueOnly;

  return (
    <div>
      {/* Search & Filters */}
      <div className="search-bar">
        <input className="search-input" placeholder="🔍  Search company, contact…"
          value={search} onChange={e => setSearch(e.target.value)} />

        <select className="search-input" style={{flex:'unset',width:148}}
          value={stageFilter} onChange={e => setStageFilter(e.target.value)}>
          <option value="">All Stages</option>
          {CRM.STAGES.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}
        </select>

        <select className="search-input" style={{flex:'unset',width:160}}
          value={industryFilter} onChange={e => setIndustryFilter(e.target.value)}>
          <option value="">All Industries</option>
          {industries.map(i => <option key={i} value={i}>{i}</option>)}
        </select>

        {user.isAdmin && (
          <select className="search-input" style={{flex:'unset',width:148}}
            value={repFilter} onChange={e => setRepFilter(e.target.value)}>
            <option value="">All Reps</option>
            {reps.map(r => <option key={r.id} value={r.id}>{r.name}</option>)}
          </select>
        )}

        <select className="search-input" style={{flex:'unset',width:120}}
          value={statusFilter} onChange={e => setStatusFilter(e.target.value)}>
          <option value="active">Active</option>
          <option value="inactive">Inactive</option>
          <option value="all">All Status</option>
        </select>

        <label style={{display:'flex',alignItems:'center',gap:6,fontSize:12,color:'var(--g600)',cursor:'pointer',whiteSpace:'nowrap',flexShrink:0}}>
          <input type="checkbox" checked={overdueOnly} onChange={e => setOverdueOnly(e.target.checked)} />
          Overdue only
        </label>

        <button className="btn btn-ghost btn-sm" onClick={exportCSV}>⬇ CSV</button>
        <button className="btn btn-ghost btn-sm" onClick={() => setShowImport(true)}>⬆ Import</button>
        <button className="btn btn-primary btn-sm" onClick={() => setShowAdd(true)}>+ Add Lead</button>
      </div>

      {/* Results count + clear filters */}
      <div style={{fontSize:12,color:'var(--g400)',marginBottom:12,display:'flex',alignItems:'center',gap:10}}>
        {loading ? 'Loading…'
          : `${displayed.length}${displayed.length !== leads.length ? ` of ${leads.length}` : ''} lead${leads.length!==1?'s':''}`}
        {hasClientFilters && (
          <button onClick={() => { setIndustryFilter(''); setOverdueOnly(false); }}
            style={{fontSize:11,color:'var(--red)',background:'none',border:'1px solid var(--red)',borderRadius:4,cursor:'pointer',padding:'1px 7px'}}>
            ✕ Clear filters
          </button>
        )}
      </div>

      {/* Table */}
      <div className="card" style={{overflow:'hidden',padding:0}}>
        <div style={{overflowX:'auto'}}>
          <table className="tbl">
            <thead>
              <tr>
                <Th col="companyName"    label="Company" />
                <Th col="contactName"    label="Contact" />
                <Th col="industry"       label="Industry" />
                <Th col="stage"          label="Stage" />
                <Th col="estimatedValue" label="Value"     style={{textAlign:'right'}} />
                <Th col="assignedRep"    label="Rep" />
                <Th col="followUpDate"   label="Follow-Up" />
                <Th col="updatedAt"      label="Updated" />
              </tr>
            </thead>
            <tbody>
              {displayed.length === 0 && (
                <tr>
                  <td colSpan={8} style={{textAlign:'center',padding:'40px',color:'var(--g400)',fontWeight:'normal'}}>
                    {loading ? 'Loading…' : 'No leads found.'}
                  </td>
                </tr>
              )}
              {displayed.length > rowCap && (
                <tr><td colSpan={8} style={{textAlign:'center',padding:'10px'}}>
                  <button className="btn btn-ghost btn-sm" onClick={e => { e.stopPropagation(); setRowCap(c => c + 200); }}>
                    Showing {rowCap} of {displayed.length} — Show more
                  </button>
                </td></tr>
              )}
              {displayed.slice(0, rowCap).map(l => {
                const rep = CRM.UsersAPI.getById(l.assignedRepId) || l.assignedRep;
                const overdue = l.followUpDate && l.followUpDate < today && !['won','lost'].includes(l.stage);
                return (
                  <tr key={l.id} onClick={() => setSelected(l)} style={{opacity: l.isActive === false ? 0.6 : 1}}>
                    <td>
                      <div style={{fontWeight:700}}>{l.companyName}{l.isActive === false && <span className="badge badge-gray" style={{marginLeft:8}}>Inactive</span>}</div>
                      <div style={{fontSize:11,color:'var(--g400)',fontWeight:'normal'}}>
                        {l.address?.split(',').slice(-2).join(',').trim()||''}
                      </div>
                    </td>
                    <td style={{fontWeight:'normal'}}>
                      <div style={{fontWeight:500,color:'var(--navy)'}}>{l.contactName||'—'}</div>
                      <div style={{fontSize:11,color:'var(--g400)'}}>{l.contactTitle}</div>
                    </td>
                    <td style={{fontWeight:'normal'}}>{l.industry||'—'}</td>
                    <td><StageBadge stage={l.stage} /></td>
                    <td style={{fontWeight:700,color:'var(--green)',textAlign:'right'}}>
                      {l.estimatedValue ? '$'+l.estimatedValue.toLocaleString() : '—'}
                    </td>
                    <td style={{fontWeight:'normal'}}>{rep?.name?.split(' ')[0]||'—'}</td>
                    <td style={{fontWeight:'normal',whiteSpace:'nowrap',color:overdue?'var(--red)':'var(--g600)'}}>
                      {l.followUpDate||'—'}{overdue?' ⚠️':''}
                    </td>
                    <td style={{fontWeight:'normal',fontSize:12,color:'var(--g400)',whiteSpace:'nowrap'}}>
                      {l.updatedAt ? l.updatedAt.split('T')[0] : '—'}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>

      {selected && (
        <LeadDetailModal lead={selected} user={user}
          onClose={() => setSelected(null)}
          onUpdate={handleUpdate}
          showToast={showToast} />
      )}
      {showAdd && (
        <AddLeadModal user={user} defaultStage="lead"
          onClose={() => setShowAdd(false)}
          onSave={async data => {
            try {
              await CRM.LeadsAPI.create(data);
              await load();
              setShowAdd(false);
              showToast('Lead added!', 'success');
            } catch (e) { showToast('Failed to add lead: ' + e.message, 'error'); }
          }} />
      )}
      {showImport && (
        <ImportModal type="leads" onClose={() => setShowImport(false)}
          onDone={() => { load(); showToast('Leads imported successfully!', 'success'); }} />
      )}
    </div>
  );
}

// ── LEAD DETAIL MODAL ──
function LeadDetailModal({ lead: initialLead, user, onClose, onUpdate, showToast }) {
  const [lead, setLead] = useState(initialLead);
  const [tab, setTab] = useState('info');
  const [activities, setActivities] = useState([]);
  const [syncedEmails, setSyncedEmails] = useState([]);
  const [actCap, setActCap] = useState(30);   // bound rendered activity timeline
  const [files, setFiles] = useState([]);
  const [proposals, setProposals] = useState([]);
  const [contacts,  setContacts]  = useState([]);
  const [showAddContact, setShowAddContact] = useState(false);
  const [contactForm, setContactForm] = useState({ name:'', title:'', email:'', phone:'', primary:false });
  const [editingContactId, setEditingContactId] = useState(null);
  const [editContactForm,  setEditContactForm]  = useState({ name:'', title:'', email:'', phone:'', primary:false });
  const [uploading, setUploading] = useState(false);
  const [editing, setEditing] = useState(false);
  const [converting,  setConverting]  = useState(false);
  const [emailing,    setEmailing]    = useState(false);
  const [form, setForm] = useState({ ...initialLead });
  const [actType, setActType] = useState('note');
  const [actText, setActText] = useState('');
  const [saving, setSaving] = useState(false);
  const reps = CRM.UsersAPI.getAll().filter(u => u.role === 'rep');

  const loadActivities = async () => {
    try {
      const acts = await CRM.ActivitiesAPI.getByLeadId(lead.id);
      setActivities(acts);
    } catch (e) { showToast('Failed to load activities.', 'error'); }
  };

  const loadFiles = async () => {
    try {
      const f = await CRM.FilesAPI.getByLead(lead.id);
      setFiles(f);
    } catch (e) { /* silently ignore */ }
  };

  const loadProposals = async () => {
    try { setProposals(await CRM.ProposalFormsAPI.getByLead(lead.id)); }
    catch (e) { /* silently ignore */ }
  };

  const loadContacts = async () => {
    try { setContacts(await CRM.ContactsAPI.getByLead(lead.id)); }
    catch (e) { /* silently ignore */ }
  };

  const setCF = (k, v) => setContactForm(f => ({ ...f, [k]: v }));

  const addContact = async () => {
    if (!contactForm.name.trim()) return showToast('Name is required.', 'error');
    try {
      await CRM.ContactsAPI.create({ ...contactForm, leadId: lead.id });
      setContactForm({ name:'', title:'', email:'', phone:'', primary:false });
      setShowAddContact(false);
      await loadContacts();
      showToast('Contact added!', 'success');
    } catch (e) { showToast('Failed to add contact: ' + e.message, 'error'); }
  };

  const removeContact = async (id) => {
    if (!confirm('Remove this contact?')) return;
    try {
      await CRM.ContactsAPI.delete(id);
      await loadContacts();
      showToast('Contact removed.');
    } catch (e) { showToast('Failed to remove contact.', 'error'); }
  };

  const makePrimaryContact = async (id) => {
    try {
      await CRM.ContactsAPI.update(id, { primary: true });
      await loadContacts();
    } catch (e) { showToast('Failed to update primary contact.', 'error'); }
  };

  const startEditContact = c => {
    setEditingContactId(c.id);
    setEditContactForm({
      name: c.name || '', title: c.title || '',
      email: c.email || '', phone: c.phone || '',
      primary: !!c.isPrimary,
    });
  };
  const cancelEditContact = () => setEditingContactId(null);
  const setECF = (k, v) => setEditContactForm(f => ({ ...f, [k]: v }));
  const saveEditContact = async () => {
    if (!editContactForm.name.trim()) return showToast('Name is required.', 'error');
    try {
      await CRM.ContactsAPI.update(editingContactId, editContactForm);
      setEditingContactId(null);
      await loadContacts();
      showToast('Contact updated.', 'success');
    } catch (e) { showToast('Failed to update contact: ' + e.message, 'error'); }
  };

  const loadSyncedEmails = async () => {
    setSyncedEmails(await CRM.GraphAPI.leadEmails(lead.id).catch(() => []));
  };

  useEffect(() => { loadActivities(); loadFiles(); loadProposals(); loadContacts(); loadSyncedEmails(); }, [lead.id]);

  const uploadFile = async (e) => {
    const file = e.target.files[0];
    if (!file) return;
    e.target.value = '';
    setUploading(true);
    try {
      await CRM.FilesAPI.uploadForLead(lead.id, file);
      await loadFiles();
      showToast('File uploaded!', 'success');
    } catch (err) {
      showToast('Upload failed: ' + err.message, 'error');
    } finally { setUploading(false); }
  };

  const deleteFile = async (id, name) => {
    if (!confirm(`Delete "${name}"?`)) return;
    try {
      await CRM.FilesAPI.delete(id);
      setFiles(f => f.filter(x => x.id !== id));
      showToast('File deleted.');
    } catch (e) { showToast('Failed to delete file.', 'error'); }
  };

  const set = (k, v) => setForm(f => ({...f, [k]: v}));
  const toggleHw = id => setForm(f => ({...f, hardwareInterest: (f.hardwareInterest||[]).includes(id) ? (f.hardwareInterest||[]).filter(x=>x!==id) : [...(f.hardwareInterest||[]),id]}));

  const save = async () => {
    setSaving(true);
    try {
      const updated = await CRM.LeadsAPI.update(lead.id, { ...form, estimatedValue: parseFloat(form.estimatedValue)||0 });
      setLead(updated);
      setEditing(false);
      onUpdate();
      showToast('Lead updated!', 'success');
    } catch (e) {
      showToast('Failed to save: ' + e.message, 'error');
    } finally { setSaving(false); }
  };

  const addActivity = async () => {
    if (!actText.trim()) return;
    try {
      await CRM.ActivitiesAPI.create(lead.id, { type: actType, content: actText });
      setActText('');
      await loadActivities();
      showToast('Activity logged!', 'success');
    } catch (e) { showToast('Failed to log activity.', 'error'); }
  };

  const deleteLead = async () => {
    if (!confirm(`Delete "${lead.companyName}"? This cannot be undone.`)) return;
    try {
      await CRM.LeadsAPI.delete(lead.id);
      onUpdate();
      onClose();
      showToast('Lead deleted.');
    } catch (e) { showToast('Failed to delete: ' + e.message, 'error'); }
  };

  const stageRep = CRM.UsersAPI.getById(lead.assignedRepId) || lead.assignedRep;

  return (
    <>
    <div className="modal-overlay" {...overlayClose(onClose)}>
      <div className="modal-panel" onClick={e => e.stopPropagation()} style={{width:'min(780px,100%)'}}>
        {/* Header */}
        <div className="modal-hd">
          <div>
            <div className="modal-title">{lead.companyName}</div>
            <div style={{fontSize:12,color:'var(--g400)',marginTop:2}}>{lead.contactName}{lead.contactTitle?` · ${lead.contactTitle}`:''} &nbsp;·&nbsp; <StageBadge stage={lead.stage}/></div>
          </div>
          <div style={{display:'flex',gap:8,alignItems:'center'}}>
            {lead.isActive === false && <span className="badge badge-gray">Inactive</span>}
            <QuickTaskAdd leadId={lead.id} showToast={showToast} />
            {lead.contactEmail && (
              <button className="btn btn-sm" style={{background:'#EFF6FF',color:'#1D4ED8',border:'1px solid #BFDBFE'}}
                onClick={() => setEmailing(true)}>✉ Email</button>
            )}
            {lead.isActive === false ? (
              <button className="btn btn-primary btn-sm" onClick={async () => {
                try {
                  const updated = await CRM.LeadsAPI.reactivate(lead.id);
                  setLead(updated); onUpdate();
                  showToast('Lead reactivated!', 'success');
                } catch (e) { showToast('Failed to reactivate: ' + e.message, 'error'); }
              }}>↺ Reactivate</button>
            ) : (
              <button className="btn btn-sm" style={{background:'#FEF3C7',color:'#92400E',border:'1px solid #FCD34D'}} onClick={async () => {
                if (!confirm(`Mark "${lead.companyName}" as inactive? It will be hidden from the list, pipeline, and dashboard.`)) return;
                try {
                  const updated = await CRM.LeadsAPI.deactivate(lead.id);
                  setLead(updated); onUpdate();
                  showToast('Lead marked inactive.', 'success');
                } catch (e) { showToast('Failed to deactivate: ' + e.message, 'error'); }
              }}>💤 Mark Inactive</button>
            )}
            <button className="modal-close" onClick={onClose}>×</button>
          </div>
        </div>

        {/* Tabs */}
        <div style={{padding:'0 24px',borderBottom:'1px solid var(--g200)'}}>
          <div className="tabs" style={{margin:0}}>
            {['info','activity','contacts','hardware','proposals','files'].map(t => (
              <button key={t} className={`tab-btn${tab===t?' active':''}`} onClick={() => setTab(t)}>
                {t==='info'?'📋 Info'
                  :t==='activity'?`💬 Activity (${activities.length + syncedEmails.length})`
                  :t==='contacts'?`👤 Contacts (${contacts.length})`
                  :t==='hardware'?'🖥 Hardware'
                  :t==='proposals'?`📄 Proposals (${proposals.length})`
                  :`📎 Files (${files.length})`}
              </button>
            ))}
          </div>
        </div>

        <div className="modal-body">
          {/* INFO TAB */}
          {tab === 'info' && (
            <div>
              {!editing ? (
                <>
                  {/* Quick summary */}
                  <div style={{display:'grid',gridTemplateColumns:'1fr 1fr 1fr 1fr',gap:12,marginBottom:20}}>
                    <div style={{background:'var(--off)',borderRadius:6,padding:'12px 14px'}}>
                      <div style={{fontSize:10,fontWeight:700,letterSpacing:'.1em',textTransform:'uppercase',color:'var(--g400)',marginBottom:4}}>Est. Value</div>
                      <div style={{fontSize:20,fontWeight:800,color:'var(--green)'}}>{lead.estimatedValue?'$'+lead.estimatedValue.toLocaleString():'—'}</div>
                    </div>
                    <div style={{background:'var(--off)',borderRadius:6,padding:'12px 14px'}}>
                      <div style={{fontSize:10,fontWeight:700,letterSpacing:'.1em',textTransform:'uppercase',color:'var(--g400)',marginBottom:4}}>Single Purchase</div>
                      <div style={{fontSize:20,fontWeight:800,color:'var(--navy)'}}>{lead.singlePurchaseValue?'$'+Number(lead.singlePurchaseValue).toLocaleString():'—'}</div>
                    </div>
                    <div style={{background:'var(--off)',borderRadius:6,padding:'12px 14px'}}>
                      <div style={{fontSize:10,fontWeight:700,letterSpacing:'.1em',textTransform:'uppercase',color:'var(--g400)',marginBottom:4}}>Follow-Up</div>
                      <div style={{fontSize:14,fontWeight:700,color:'var(--navy)'}}>{lead.followUpDate||'Not set'}</div>
                    </div>
                    <div style={{background:'var(--off)',borderRadius:6,padding:'12px 14px'}}>
                      <div style={{fontSize:10,fontWeight:700,letterSpacing:'.1em',textTransform:'uppercase',color:'var(--g400)',marginBottom:4}}>Assigned Rep</div>
                      <div style={{fontSize:14,fontWeight:700,color:'var(--navy)'}}>{stageRep?.name||'—'}</div>
                    </div>
                  </div>

                  <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:20,marginBottom:16}}>
                    <div>
                      <div className="form-section" style={{marginTop:0}}>Contact</div>
                      <InfoRow label="Email" value={lead.contactEmail} link={`mailto:${lead.contactEmail}`} />
                      <InfoRow label="Phone" value={lead.contactPhone} link={`tel:${lead.contactPhone}`} />
                      <InfoRow label="Address" value={lead.address} />
                    </div>
                    <div>
                      <div className="form-section" style={{marginTop:0}}>Company</div>
                      <InfoRow label="Industry" value={lead.industry} />
                      <InfoRow label="Employees" value={lead.employeeCount} />
                      <InfoRow label="Source" value={lead.leadSource} />
                    </div>
                  </div>

                  {/* Pipeline-style stage selector */}
                  <div>
                    <div className="form-section">Stage</div>
                    <StagePipeline currentStage={lead.stage} onChange={async (s) => {
                      if (s.id === lead.stage) return;
                      try {
                        const updated = await CRM.LeadsAPI.updateStage(lead.id, s.id);
                        setLead(updated);
                        onUpdate();
                        showToast('Stage updated to ' + s.label, 'success');
                      } catch(e) { showToast('Failed to update stage.', 'error'); }
                    }} />
                  </div>

                  {lead.notes && (
                    <div>
                      <div className="form-section">Notes</div>
                      <div style={{fontSize:13,color:'var(--g600)',lineHeight:1.7,background:'var(--off)',padding:'12px 14px',borderRadius:6}}><NoteText text={lead.notes} /></div>
                    </div>
                  )}

                  <div style={{display:'flex',gap:8,marginTop:20,flexWrap:'wrap'}}>
                    <button className="btn btn-primary btn-sm" onClick={() => setEditing(true)}>✏️ Edit</button>
                    {lead.stage === 'won' && !lead.convertedAccountId && (
                      <button className="btn btn-green btn-sm" onClick={() => setConverting(true)}>🏢 Convert to Account</button>
                    )}
                    {lead.convertedAccountId && (
                      <span style={{display:'inline-flex',alignItems:'center',gap:6,fontSize:12,fontWeight:700,color:'var(--green)',background:'#F0FDF4',border:'1px solid #BBF7D0',borderRadius:6,padding:'6px 12px'}}>
                        ✔ Converted to Account
                      </span>
                    )}
                    {user.isAdmin && <button className="btn btn-ghost btn-sm" onClick={deleteLead} style={{color:'var(--red)'}}>🗑 Delete</button>}
                  </div>
                </>
              ) : (
                <>
                  <div className="form-section" style={{marginTop:0}}>Deal</div>
                  <div className="fg fg-2">
                    <div className="field"><label>Stage</label>
                      <select value={form.stage||''} onChange={e=>set('stage',e.target.value)}>
                        {CRM.STAGES.map(s=><option key={s.id} value={s.id}>{s.label}</option>)}
                      </select>
                    </div>
                    <div className="field"><label>Estimated Value ($)</label><input type="number" value={form.estimatedValue||''} onChange={e=>set('estimatedValue',e.target.value)} /></div>
                  </div>
                  <div className="fg fg-2">
                    <div className="field"><label>Single Purchase Value ($)</label><input type="number" value={form.singlePurchaseValue||''} onChange={e=>set('singlePurchaseValue',e.target.value)} placeholder="0" /></div>
                  </div>
                  <div className="fg fg-2">
                    {user.isAdmin && <div className="field"><label>Assigned Rep</label>
                      <select value={form.assignedRepId||''} onChange={e=>set('assignedRepId',e.target.value||null)}>
                        <option value="">— Unassigned —</option>
                        {reps.map(r=><option key={r.id} value={r.id}>{r.name}</option>)}
                      </select>
                    </div>}
                    <div className="field"><label>Follow-Up Date</label><input type="date" value={form.followUpDate||''} onChange={e=>set('followUpDate',e.target.value)} /></div>
                  </div>

                  <div className="form-section">Company</div>
                  <div className="fg fg-2">
                    <div className="field"><label>Company Name</label><input value={form.companyName||''} onChange={e=>set('companyName',e.target.value)} /></div>
                    <div className="field"><label>Industry</label>
                      <select value={form.industry||''} onChange={e=>set('industry',e.target.value)}>
                        <option value="">— Select —</option>
                        {CRM.INDUSTRIES.map(i=><option key={i}>{i}</option>)}
                      </select>
                    </div>
                  </div>
                  <div className="fg fg-2">
                    <div className="field"><label>Employee Count</label>
                      <select value={form.employeeCount||''} onChange={e=>set('employeeCount',e.target.value)}>
                        <option value="">— Select —</option>
                        {CRM.EMPLOYEE_COUNTS.map(v=><option key={v}>{v}</option>)}
                      </select>
                    </div>
                    <div className="field"><label>Lead Source</label>
                      <select value={form.leadSource||''} onChange={e=>set('leadSource',e.target.value)}>
                        <option value="">— Select —</option>
                        {CRM.LEAD_SOURCES.map(s=><option key={s}>{s}</option>)}
                      </select>
                    </div>
                  </div>
                  <div className="fg fg-1"><div className="field"><label>Address</label><input value={form.address||''} onChange={e=>set('address',e.target.value)} /></div></div>

                  <div className="form-section">Contact</div>
                  <div className="fg fg-2">
                    <div className="field"><label>Name</label><input value={form.contactName||''} onChange={e=>set('contactName',e.target.value)} /></div>
                    <div className="field"><label>Title</label><input value={form.contactTitle||''} onChange={e=>set('contactTitle',e.target.value)} /></div>
                  </div>
                  <div className="fg fg-2">
                    <div className="field"><label>Email</label><input type="email" value={form.contactEmail||''} onChange={e=>set('contactEmail',e.target.value)} /></div>
                    <div className="field"><label>Phone</label><input value={form.contactPhone||''} onChange={e=>set('contactPhone',e.target.value)} /></div>
                  </div>

                  <div className="fg fg-1"><div className="field"><label>Notes</label><textarea value={form.notes||''} onChange={e=>set('notes',e.target.value)} /></div></div>
                </>
              )}
            </div>
          )}

          {/* ACTIVITY TAB */}
          {tab === 'activity' && (
            <div>
              <div className="add-activity">
                <div style={{display:'flex',gap:8,marginBottom:10,flexWrap:'wrap'}}>
                  {ACT_TYPES.map(t => (
                    <button key={t} onClick={() => setActType(t)}
                      style={{padding:'5px 12px',fontSize:12,fontWeight:600,borderRadius:5,cursor:'pointer',fontFamily:'var(--font)',
                        background: actType===t ? 'var(--navy)' : 'white',
                        color: actType===t ? 'white' : 'var(--g600)',
                        border: actType===t ? '1.5px solid var(--navy)' : '1.5px solid var(--g200)'}}>
                      {ACT_ICONS[t]} {t.charAt(0).toUpperCase()+t.slice(1)}
                    </button>
                  ))}
                </div>
                <div className="add-act-row">
                  <textarea className="field" style={{flex:1,border:'1.5px solid var(--g200)',borderRadius:5,padding:'9px 12px',fontSize:13,fontFamily:'var(--font)',color:'var(--navy)',resize:'none',height:64,outline:'none',background:'white'}}
                    placeholder={`Log a ${actType}…`} value={actText} onChange={e=>setActText(e.target.value)} />
                  <button className="btn btn-primary btn-sm" onClick={addActivity}>Log</button>
                </div>
              </div>
              <div className="activity-list" style={{marginTop:16}}>
                {activities.length === 0 && syncedEmails.length === 0 && <div className="empty"><div className="empty-icon">💬</div><div className="empty-text">No activity yet.</div></div>}
                {(() => {
                  // Bounded render — synced email can make this timeline huge
                  const full = [
                    ...activities.map(a => ({ kind: 'act', at: a.createdAt, a })),
                    ...syncedEmails.map(m => ({ kind: 'mail', at: m.sentAt || m.createdAt, m })),
                  ].sort((x, y) => new Date(y.at) - new Date(x.at));
                  const timeline = full.slice(0, actCap);
                  const more = full.length - timeline.length;
                  const showMore = more > 0 ? (
                    <button key="__more" className="btn btn-ghost btn-sm" style={{marginTop:10}}
                      onClick={() => setActCap(c => c + 100)}>Show more ({more} more)</button>
                  ) : null;
                  return [...timeline.map(item => item.kind === 'act' ? (
                    <div key={item.a.id} className="activity-item">
                      <div className={`act-icon act-${item.a.type}`}>{ACT_ICONS[item.a.type]||'📌'}</div>
                      <div className="act-content">
                        <div className="act-text"><NoteText text={item.a.content} /></div>
                        <div className="act-meta">{item.a.userName} · {new Date(item.a.createdAt).toLocaleString()}</div>
                      </div>
                    </div>
                  ) : (
                    <div key={`mail-${item.m.id}`} className="activity-item">
                      <div className="act-icon act-email">{item.m.direction === 'in' ? '📥' : '📤'}</div>
                      <div className="act-content" style={{minWidth:0}}>
                        <div className="act-text" style={{fontWeight:700}}>{item.m.subject || '(no subject)'}</div>
                        <div style={{fontSize:12,color:'var(--g400)',whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>
                          {item.m.fromName || item.m.fromAddress} → {item.m.toAddresses}
                        </div>
                        {item.m.bodyPreview && <div className="act-text" style={{marginTop:2}}><NoteText text={item.m.bodyPreview} limit={200} /></div>}
                        <div className="act-meta">
                          {new Date(item.at).toLocaleString()}
                          {item.m.webLink && <> · <a href={item.m.webLink} target="_blank" rel="noreferrer" style={{color:'var(--blue)',fontSize:11}}>Open in Outlook ↗</a></>}
                        </div>
                      </div>
                    </div>
                  )), showMore];
                })()}
              </div>
            </div>
          )}

          {/* HARDWARE TAB */}
          {tab === 'hardware' && (
            <div>
              <div style={{fontSize:13,color:'var(--g600)',marginBottom:16}}>Select hardware options this client is interested in. These will pre-select when generating a proposal.</div>
              <div style={{display:'flex',flexWrap:'wrap',gap:10,marginBottom:24}}>
                {CRM.HW_OPTIONS.map(h => {
                  const sel = (form.hardwareInterest||[]).includes(h.id);
                  return (
                    <button key={h.id} onClick={() => toggleHw(h.id)}
                      style={{padding:'10px 16px',fontSize:13,fontWeight:600,borderRadius:6,cursor:'pointer',fontFamily:'var(--font)',
                        background: sel ? 'var(--navy)' : 'white',
                        color: sel ? 'white' : 'var(--g600)',
                        border: sel ? '1.5px solid var(--navy)' : '1.5px solid var(--g200)'}}>
                      {sel ? '✓ ' : ''}{h.name}
                    </button>
                  );
                })}
              </div>
              <button className="btn btn-primary" onClick={save} disabled={saving}>{saving ? 'Saving…' : 'Save Hardware Selection'}</button>
            </div>
          )}

          {/* CONTACTS TAB */}
          {tab === 'contacts' && (
            <div>
              <div style={{display:'flex',justifyContent:'flex-end',marginBottom:16}}>
                <button className="btn btn-primary btn-sm" onClick={() => setShowAddContact(!showAddContact)}>+ Add Contact</button>
              </div>
              {showAddContact && (
                <div style={{background:'var(--off)',borderRadius:8,padding:16,marginBottom:16,borderLeft:'3px solid var(--red)'}}>
                  <div style={{fontWeight:700,fontSize:12,letterSpacing:'.1em',textTransform:'uppercase',color:'var(--red)',marginBottom:12}}>New Contact</div>
                  <div className="fg fg-2">
                    <div className="field"><label>Full Name *</label><input value={contactForm.name} onChange={e=>setCF('name',e.target.value)} /></div>
                    <div className="field"><label>Title</label><input value={contactForm.title} onChange={e=>setCF('title',e.target.value)} /></div>
                  </div>
                  <div className="fg fg-2">
                    <div className="field"><label>Email</label><input type="email" value={contactForm.email} onChange={e=>setCF('email',e.target.value)} /></div>
                    <div className="field"><label>Phone</label><input value={contactForm.phone} onChange={e=>setCF('phone',e.target.value)} /></div>
                  </div>
                  <div style={{display:'flex',gap:10,alignItems:'center',marginBottom:12}}>
                    <input type="checkbox" id="lead-primary-chk" checked={contactForm.primary} onChange={e=>setCF('primary',e.target.checked)} />
                    <label htmlFor="lead-primary-chk" style={{fontSize:13,color:'var(--g600)'}}>Set as primary contact</label>
                  </div>
                  <div style={{display:'flex',gap:8}}>
                    <button className="btn btn-primary btn-sm" onClick={addContact}>Add Contact</button>
                    <button className="btn btn-ghost btn-sm" onClick={() => setShowAddContact(false)}>Cancel</button>
                  </div>
                </div>
              )}
              {contacts.length === 0 && <div className="empty"><div className="empty-icon">👤</div><div className="empty-text">No contacts yet.</div></div>}
              <div style={{display:'flex',flexDirection:'column',gap:10}}>
                {contacts.map(c => editingContactId === c.id ? (
                  <div key={c.id} style={{background:'#F8FAFC',border:'1.5px solid var(--navy)',borderRadius:8,padding:14}}>
                    <div style={{fontWeight:700,fontSize:12,letterSpacing:'.1em',textTransform:'uppercase',color:'var(--navy)',marginBottom:10}}>Edit Contact</div>
                    <div className="fg fg-2">
                      <div className="field"><label>Full Name *</label><input value={editContactForm.name} onChange={e=>setECF('name',e.target.value)} /></div>
                      <div className="field"><label>Title</label><input value={editContactForm.title} onChange={e=>setECF('title',e.target.value)} /></div>
                    </div>
                    <div className="fg fg-2">
                      <div className="field"><label>Email</label><input type="email" value={editContactForm.email} onChange={e=>setECF('email',e.target.value)} /></div>
                      <div className="field"><label>Phone</label><input value={editContactForm.phone} onChange={e=>setECF('phone',e.target.value)} /></div>
                    </div>
                    <div style={{display:'flex',gap:10,alignItems:'center',marginBottom:10}}>
                      <input type="checkbox" id={`lead-edit-primary-${c.id}`} checked={editContactForm.primary} onChange={e=>setECF('primary',e.target.checked)} />
                      <label htmlFor={`lead-edit-primary-${c.id}`} style={{fontSize:13,color:'var(--g600)'}}>Primary contact</label>
                    </div>
                    <div style={{display:'flex',gap:8}}>
                      <button className="btn btn-primary btn-sm" onClick={saveEditContact}>Save</button>
                      <button className="btn btn-ghost btn-sm" onClick={cancelEditContact}>Cancel</button>
                    </div>
                  </div>
                ) : (
                  <div key={c.id} style={{background:'white',border:'1px solid var(--g200)',borderRadius:8,padding:'14px 16px',display:'flex',alignItems:'center',gap:14}}>
                    <div style={{width:40,height:40,borderRadius:'50%',background:c.primary?'var(--red)':'var(--navy)',color:'white',display:'flex',alignItems:'center',justifyContent:'center',fontSize:14,fontWeight:700,flexShrink:0}}>{(c.name || '?').charAt(0)}</div>
                    <div style={{flex:1}}>
                      <div style={{display:'flex',alignItems:'center',gap:8,marginBottom:2}}>
                        <span style={{fontSize:14,fontWeight:700,color:'var(--navy)'}}>{c.name}</span>
                        {c.primary && <span className="badge badge-red" style={{fontSize:10}}>Primary</span>}
                      </div>
                      <div style={{fontSize:12,color:'var(--g400)'}}>{c.title}</div>
                      <div style={{display:'flex',gap:12,marginTop:4}}>
                        {c.email && <a href={`mailto:${c.email}`} style={{fontSize:12,color:'var(--navy)',textDecoration:'none'}} onClick={e=>e.stopPropagation()}>📧 {c.email}</a>}
                        {c.phone && <a href={`tel:${c.phone}`} style={{fontSize:12,color:'var(--navy)',textDecoration:'none'}} onClick={e=>e.stopPropagation()}>📞 {c.phone}</a>}
                      </div>
                    </div>
                    <div style={{display:'flex',gap:6}}>
                      <button className="btn btn-ghost btn-xs" onClick={() => startEditContact(c)}>✏ Edit</button>
                      {!c.primary && <button className="btn btn-ghost btn-xs" onClick={() => makePrimaryContact(c.id)}>Make Primary</button>}
                      <button className="btn btn-xs" style={{background:'#fee2e2',color:'var(--red)',border:'none'}} onClick={() => removeContact(c.id)}>Remove</button>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* PROPOSALS TAB */}
          {tab === 'proposals' && (
            <LeadProposalsTab lead={lead} user={user} showToast={showToast}
              onChanged={loadProposals} />
          )}

          {/* FILES TAB */}
          {tab === 'files' && (
            <div>
              <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:16}}>
                <div style={{fontSize:13,color:'var(--g600)'}}>Attach documents, images, or PDFs to this lead.</div>
                <label className="btn btn-primary btn-sm" style={{cursor:'pointer'}}>
                  {uploading ? 'Uploading…' : '+ Upload File'}
                  <input type="file" accept=".pdf,.doc,.docx,.xls,.xlsx,.png,.jpg,.jpeg,.gif,.txt,.csv" onChange={uploadFile} style={{display:'none'}} disabled={uploading} />
                </label>
              </div>
              {files.length === 0 && !uploading && (
                <div className="empty"><div className="empty-icon">📎</div><div className="empty-text">No files attached yet.</div></div>
              )}
              <div style={{display:'flex',flexDirection:'column',gap:8}}>
                {files.map(f => (
                  <div key={f.id} style={{display:'flex',alignItems:'center',gap:12,padding:'10px 14px',background:'var(--off)',borderRadius:6,border:'1px solid var(--g200)'}}>
                    <span style={{fontSize:20}}>{fileIcon(f.contentType, f.fileName)}</span>
                    <div style={{flex:1,minWidth:0}}>
                      <div style={{fontSize:13,fontWeight:600,color:'var(--navy)',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{f.fileName}</div>
                      <div style={{fontSize:11,color:'var(--g400)'}}>{fmtSize(f.fileSize)} · {f.uploaderName} · {new Date(f.uploadedAt).toLocaleDateString()}</div>
                    </div>
                    <a href={CRM.FilesAPI.downloadUrl(f.id)} target="_blank" className="btn btn-ghost btn-xs" style={{flexShrink:0}}>⬇ Download</a>
                    <button onClick={() => deleteFile(f.id, f.fileName)} className="btn btn-xs" style={{background:'#fee2e2',color:'var(--red)',border:'none',flexShrink:0}}>✕</button>
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>

        {editing && (
          <div className="modal-footer">
            <button className="btn btn-ghost" onClick={() => { setEditing(false); setForm({...lead}); }}>Cancel</button>
            <button className="btn btn-primary" onClick={save} disabled={saving}>{saving ? 'Saving…' : 'Save Changes'}</button>
          </div>
        )}
      </div>
    </div>

    {converting && (
      <ConvertToAccountModal
        lead={lead}
        user={user}
        onClose={() => setConverting(false)}
        onConverted={() => { setConverting(false); showToast('Lead converted to account!', 'success'); onUpdate(); }}
        showToast={showToast}
      />
    )}
    {emailing && (
      <SendEmailModal
        toEmail={lead.contactEmail}
        toName={lead.contactName || lead.companyName}
        leadId={lead.id}
        onClose={() => setEmailing(false)}
        showToast={showToast}
      />
    )}
    </>
  );
}

function ConvertToAccountModal({ lead, user, onClose, onConverted, showToast }) {
  const [form, setForm] = useState({
    contractValue: lead.estimatedValue || '',
    contractStart: '',
    contractEnd: '',
    notes: lead.notes || '',
  });
  const [logSale, setLogSale] = useState(true);
  const [saleAmount, setSaleAmount] = useState(String(lead.estimatedValue || ''));
  const [saving, setSaving] = useState(false);
  const set = (k, v) => setForm(f => ({...f, [k]: v}));

  const convert = async () => {
    setSaving(true);
    try {
      const acc = await CRM.AccountsAPI.create({
        companyName:        lead.companyName,
        address:            lead.address       || null,
        industry:           lead.industry      || null,
        employeeCount:      lead.employeeCount || null,
        assignedRepId:      lead.assignedRepId || null,
        leadId:             lead.id,
        contractValue:      parseFloat(form.contractValue) || 0,
        contractStart:      form.contractStart || null,
        contractEnd:        form.contractEnd   || null,
        notes:              form.notes         || null,
        singlePurchaseValue: parseFloat(lead.singlePurchaseValue) || 0,
      });
      // Optional: log the deal as the account's first sale right away
      if (logSale && parseFloat(saleAmount) > 0 && acc?.id) {
        try {
          await CRM.AccountSalesAPI.create(acc.id, {
            amount: saleAmount,
            description: 'Initial sale — converted from lead',
            saleDate: new Date().toISOString().split('T')[0],
          });
        } catch (e) {
          showToast('Account created, but logging the sale failed: ' + e.message, 'error');
        }
      }
      onConverted();
    } catch (e) {
      showToast('Conversion failed: ' + e.message, 'error');
    } finally { setSaving(false); }
  };

  return (
    <div className="modal-overlay" {...overlayClose(onClose)}>
      <div className="modal-panel" style={{width:'min(480px,100%)'}} onClick={e => e.stopPropagation()}>
        <div className="modal-hd">
          <div className="modal-title">Convert to Account — {lead.companyName}</div>
          <button className="modal-close" onClick={onClose}>×</button>
        </div>
        <div className="modal-body">
          <div style={{fontSize:13,color:'var(--g600)',marginBottom:20}}>
            Creates a new account linked to this lead. Company info, industry, assigned rep, and address are copied over automatically.
          </div>
          <div className="fg fg-1">
            <div className="field"><label>Contract Value ($)</label>
              <input type="number" value={form.contractValue} onChange={e => set('contractValue', e.target.value)} />
            </div>
          </div>
          <div className="fg fg-2">
            <div className="field"><label>Contract Start</label>
              <input type="date" value={form.contractStart} onChange={e => set('contractStart', e.target.value)} />
            </div>
            <div className="field"><label>Contract End</label>
              <input type="date" value={form.contractEnd} onChange={e => set('contractEnd', e.target.value)} />
            </div>
          </div>
          <div className="fg fg-1">
            <div className="field"><label>Notes</label>
              <textarea value={form.notes} onChange={e => set('notes', e.target.value)} />
            </div>
          </div>
          <div style={{border:'1px solid var(--g100)',borderRadius:8,padding:'12px 14px',background:'var(--off)'}}>
            <label style={{display:'flex',alignItems:'center',gap:8,fontSize:13,fontWeight:600,color:'var(--navy)',cursor:'pointer'}}>
              <input type="checkbox" checked={logSale} onChange={e => setLogSale(e.target.checked)} style={{width:15,height:15}} />
              Log this deal as the account's first sale
            </label>
            {logSale && (
              <div className="field" style={{marginTop:10,marginBottom:0}}>
                <label>Sale Amount ($)</label>
                <input type="number" value={saleAmount} onChange={e => setSaleAmount(e.target.value)} />
              </div>
            )}
          </div>
        </div>
        <div className="modal-footer">
          <button className="btn btn-ghost" onClick={onClose}>Cancel</button>
          <button className="btn btn-green" onClick={convert} disabled={saving}>{saving ? 'Converting…' : '🏢 Create Account'}</button>
        </div>
      </div>
    </div>
  );
}

function InfoRow({ label, value, link }) {
  if (!value) return null;
  return (
    <div style={{display:'flex',gap:8,marginBottom:8,alignItems:'flex-start'}}>
      <span style={{fontSize:11,fontWeight:600,color:'var(--g400)',minWidth:64}}>{label}</span>
      {link
        ? <a href={link} style={{fontSize:13,color:'var(--navy)',textDecoration:'none',fontWeight:500}} onClick={e=>e.stopPropagation()}>{value}</a>
        : <span style={{fontSize:13,color:'var(--navy)',fontWeight:500}}>{value}</span>}
    </div>
  );
}

function fileIcon(contentType, fileName) {
  if (!contentType && !fileName) return '📎';
  const ct = (contentType || '').toLowerCase();
  const ext = (fileName || '').split('.').pop().toLowerCase();
  if (ct.includes('pdf') || ext === 'pdf') return '📄';
  if (ct.includes('word') || ['doc','docx'].includes(ext)) return '📝';
  if (ct.includes('sheet') || ct.includes('excel') || ['xls','xlsx'].includes(ext)) return '📊';
  if (ct.includes('image') || ['png','jpg','jpeg','gif','webp'].includes(ext)) return '🖼';
  if (ct.includes('text') || ['txt','csv'].includes(ext)) return '📃';
  return '📎';
}

function fmtSize(bytes) {
  if (!bytes) return '0 B';
  if (bytes < 1024) return bytes + ' B';
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
  return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
}

Object.assign(window, { Leads, LeadDetailModal, ConvertToAccountModal, InfoRow, fileIcon, fmtSize });
