const { useState, useEffect, useMemo, useRef } = React;

/* ────────── config ────────── */
const STAGES = [
  { key: 'new',         label: 'New',         color: '#1e5fa8' },
  { key: 'contacted',   label: 'Contacted',   color: '#1e5fa8' },
  { key: 'interview',   label: 'Interview',   color: '#d94c1f' },
  { key: 'onboarding',  label: 'Onboarding',  color: '#b8860b' },
  { key: 'processing',  label: 'Processing',  color: '#b8860b' },
  { key: 'tickets',     label: 'Tickets',     color: '#6d4eb8' },
  { key: 'orientation', label: 'Orientation', color: '#6d4eb8' },
  { key: 'enroute',     label: 'En route',    color: '#6d4eb8' },
  { key: 'active',      label: 'Driving',     color: '#2e7d4f' },
];
const STAGE_KEYS = STAGES.map(s => s.key);

const DISPOSITIONS = [
  { key: 'none',        label: 'No contact',         color: '#9a958c' },
  { key: 'answered',    label: 'Answered',           color: '#2e7d4f' },
  { key: 'voicemail',   label: 'Voicemail',          color: '#b8860b' },
  { key: 'no_answer',   label: 'No answer',          color: '#b91c1c' },
  { key: 'texted',      label: 'Texted',             color: '#1e5fa8' },
  { key: 'emailed',     label: 'Emailed',            color: '#1e5fa8' },
  { key: 'callback',    label: 'Callback set',       color: '#6d4eb8' },
  { key: 'declined',    label: 'Declined',           color: '#b91c1c' },
];

const DOC_TYPES = [
  { key: 'cdl',          label: 'CDL',                 sub: 'Driver License' },
  { key: 'medical',      label: 'Medical Card',        sub: 'MCSA-5876' },
  { key: 'ssn',          label: 'Social Security',     sub: 'SSN card' },
  { key: 'mvr',          label: 'MVR',                 sub: 'Motor Vehicle Record' },
  { key: 'psp',          label: 'PSP',                 sub: 'Pre-Employment Screening' },
  { key: 'drug',         label: 'Drug Screen',         sub: 'DOT drug + alcohol' },
  { key: 'background',   label: 'Background Check',    sub: '7-yr criminal' },
  { key: 'i9',           label: 'I-9 / W-9',           sub: 'Work eligibility' },
];

const SEED = [
  { id: 'p1', name: 'Marcus Johnson',  phone: '(973) 555-0148', email: 'mjohnson84@gmail.com',       city: 'Newark, NJ',      years: 8,  source: 'Indeed',    stage: 'new',         disposition: 'none',     daysIn: 1,  notes: '' },
  { id: 'p2', name: 'Ricardo Vega',    phone: '(862) 555-0192', email: 'rvega.trucking@yahoo.com',   city: 'Paterson, NJ',    years: 12, source: 'Referral',  stage: 'contacted',   disposition: 'answered', daysIn: 3,  notes: 'Owns 2020 Peterbilt 579 — owner-op.' },
  { id: 'p3', name: 'Tasha Williams',  phone: '(551) 555-0124', email: 'tasha.w@protonmail.com',     city: 'Bayonne, NJ',     years: 3,  source: 'Drive4PT',  stage: 'interview',   disposition: 'callback', daysIn: 5,  notes: 'Phone interview Thu 10 AM.' },
  { id: 'p4', name: 'Hank Olsen',      phone: '(610) 555-0187', email: 'h.olsen@gmail.com',          city: 'Allentown, PA',   years: 18, source: 'Referral',  stage: 'onboarding',  disposition: 'answered', daysIn: 8,  notes: '18 yrs clean. Likely top performer.' },
  { id: 'p5', name: 'Diego Morales',   phone: '(908) 555-0163', email: 'diegomorales@gmail.com',     city: 'Elizabeth, NJ',   years: 5,  source: 'Facebook',  stage: 'orientation', disposition: 'answered', daysIn: 11, notes: 'Orientation Mon May 19, 8 AM.' },
  { id: 'p6', name: 'Jamal Robinson',  phone: '(201) 555-0145', email: 'jrobinson06@outlook.com',    city: 'Jersey City, NJ', years: 6,  source: 'Class A',   stage: 'contacted',   disposition: 'voicemail',daysIn: 4,  notes: '' },
  { id: 'p7', name: 'Brittany Adams',  phone: '(973) 555-0156', email: 'b.adams.cdl@gmail.com',      city: 'Newark, NJ',      years: 2,  source: 'Indeed',    stage: 'new',         disposition: 'no_answer',daysIn: 2,  notes: 'Less than 2 yrs exp.' },
  { id: 'p8', name: 'Maya Patel',      phone: '(732) 555-0188', email: 'mpatel.transport@gmail.com', city: 'Iselin, NJ',      years: 4,  source: 'Indeed',    stage: 'processing',  disposition: 'answered', daysIn: 1,  notes: 'MVR + PSP requested.' },
  { id: 'p9', name: 'Kevin O\'Brien',  phone: '(609) 555-0177', email: 'kobrien.driver@gmail.com',   city: 'Trenton, NJ',     years: 7,  source: 'Drive4PT',  stage: 'tickets',     disposition: 'answered', daysIn: 6,  notes: 'Flight booked Sun morning, Uber to terminal arranged.' },
  { id:'p10', name: 'Sofia Petrov',    phone: '(732) 555-0119', email: 'sofia.petrov@gmail.com',     city: 'Edison, NJ',      years: 9,  source: 'Facebook',  stage: 'enroute',     disposition: 'texted',   daysIn: 1,  notes: 'En route to NJ terminal.' },
  { id:'p11', name: 'Pavel Kowalski',  phone: '(862) 555-0107', email: 'pkowalski@gmail.com',        city: 'Clifton, NJ',     years: 22, source: 'Referral',  stage: 'active',      disposition: 'answered', daysIn: 28, notes: 'Driving Unit 02.' },
];

const STORAGE_KEY = 'pruvista-crm-v2';
const IDB_NAME    = 'pruvista-crm';
const IDB_STORE   = 'files';

/* ────────── IndexedDB helpers (real file storage in browser) ────────── */
const idb = {
  _db: null,
  open() {
    if (this._db) return Promise.resolve(this._db);
    return new Promise((resolve, reject) => {
      const req = indexedDB.open(IDB_NAME, 1);
      req.onupgradeneeded = () => req.result.createObjectStore(IDB_STORE);
      req.onsuccess = () => { this._db = req.result; resolve(this._db); };
      req.onerror = () => reject(req.error);
    });
  },
  async put(key, blob) {
    const db = await this.open();
    return new Promise((res, rej) => {
      const tx = db.transaction(IDB_STORE, 'readwrite');
      tx.objectStore(IDB_STORE).put(blob, key);
      tx.oncomplete = () => res();
      tx.onerror = () => rej(tx.error);
    });
  },
  async get(key) {
    const db = await this.open();
    return new Promise((res, rej) => {
      const tx = db.transaction(IDB_STORE, 'readonly');
      const r = tx.objectStore(IDB_STORE).get(key);
      r.onsuccess = () => res(r.result);
      r.onerror = () => rej(r.error);
    });
  },
  async del(key) {
    const db = await this.open();
    return new Promise((res, rej) => {
      const tx = db.transaction(IDB_STORE, 'readwrite');
      tx.objectStore(IDB_STORE).delete(key);
      tx.oncomplete = () => res();
      tx.onerror = () => rej(tx.error);
    });
  },
};

/* ────────── utils ────────── */
const initials   = (name) => name.split(/\s+/).filter(Boolean).map(s => s[0]).join('').slice(0,2).toUpperCase();
const stageOf    = (k) => STAGES.find(s => s.key === k) || STAGES[0];
const dispOf     = (k) => DISPOSITIONS.find(s => s.key === k) || DISPOSITIONS[0];
const cls        = (...x) => x.filter(Boolean).join(' ');
const fmtSize    = (n) => n < 1024 ? n+' B' : n < 1024*1024 ? Math.round(n/1024)+' KB' : (n/1024/1024).toFixed(1)+' MB';
const blankDocs  = () => DOC_TYPES.reduce((a, d) => (a[d.key] = { status: 'missing' }, a), {});

const Icon = ({ name, size = 16, className }) => {
  const props = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round', className };
  const paths = {
    search:  <><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></>,
    plus:    <><path d="M12 5v14M5 12h14"/></>,
    x:       <><path d="M18 6 6 18M6 6l12 12"/></>,
    arrow:   <><path d="M5 12h14M12 5l7 7-7 7"/></>,
    arrowL:  <><path d="M19 12H5M12 19l-7-7 7-7"/></>,
    check:   <><path d="M20 6 9 17l-5-5"/></>,
    trash:   <><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/></>,
    grid:    <><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></>,
    table:   <><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M3 15h18M9 3v18M15 3v18"/></>,
    upload:  <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12"/></>,
    eye:     <><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></>,
    file:    <><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></>,
  };
  return <svg {...props}>{paths[name]}</svg>;
};

/* ────────── app ────────── */
function App() {
  const [people, setPeople] = useState(() => {
    try {
      const s = JSON.parse(localStorage.getItem(STORAGE_KEY));
      if (s && Array.isArray(s) && s.length) {
        return s.map(p => ({ disposition: 'none', docs: blankDocs(), ...p, docs: { ...blankDocs(), ...(p.docs || {}) } }));
      }
    } catch {}
    return SEED.map(p => ({ ...p, docs: blankDocs() }));
  });
  const [query, setQuery]       = useState('');
  const [view, setView]         = useState('kanban'); // 'kanban' | 'table'
  const [pickedId, setPickedId] = useState(null);
  const [adding, setAdding]     = useState(false);
  const [preview, setPreview]   = useState(null); // { name, url, mime }
  const [dragId, setDragId]     = useState(null);
  const [dragOver, setDragOver] = useState(null);
  const [toasts, setToasts]     = useState([]);

  useEffect(() => { localStorage.setItem(STORAGE_KEY, JSON.stringify(people)); }, [people]);

  const toast = (msg, kind) => {
    const id = Math.random().toString(36).slice(2);
    setToasts(t => [...t, { id, msg, kind }]);
    setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), 2400);
  };

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return people;
    return people.filter(p =>
      p.name.toLowerCase().includes(q) ||
      p.phone.includes(q) ||
      p.email.toLowerCase().includes(q) ||
      (p.city || '').toLowerCase().includes(q) ||
      (p.source || '').toLowerCase().includes(q)
    );
  }, [people, query]);

  const picked = people.find(p => p.id === pickedId);

  const moveTo  = (id, stage) => {
    const p = people.find(x => x.id === id);
    setPeople(ps => ps.map(p => p.id === id ? { ...p, stage, daysIn: 0 } : p));
    if (p) toast(`${p.name} → ${stageOf(stage).label}`, 'success');
  };
  const update  = (id, patch) => setPeople(ps => ps.map(p => p.id === id ? { ...p, ...patch } : p));
  const setDoc  = (id, docKey, docPatch) => setPeople(ps => ps.map(p => p.id === id ? { ...p, docs: { ...p.docs, [docKey]: { ...p.docs[docKey], ...docPatch } } } : p));
  const remove  = (id) => {
    const p = people.find(x => x.id === id);
    if (p && p.docs) {
      DOC_TYPES.forEach(d => { const idbKey = `${id}/${d.key}`; idb.del(idbKey).catch(() => {}); });
    }
    setPeople(ps => ps.filter(x => x.id !== id));
    setPickedId(null);
    if (p) toast(`${p.name} removed`);
  };
  const add = (data) => {
    const id = 'p' + Math.random().toString(36).slice(2, 8);
    setPeople(ps => [{ id, daysIn: 0, disposition: 'none', docs: blankDocs(), ...data }, ...ps]);
    setAdding(false);
    toast(`${data.name} added`, 'success');
  };

  /* drag-and-drop */
  const onDragStart = (e, id) => { setDragId(id); e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.setData('text/plain', id); };
  const onDragEnd   = () => { setDragId(null); setDragOver(null); };
  const onDragOverCol = (e, s) => { e.preventDefault(); setDragOver(s); };
  const onDropCol = (e, s) => {
    e.preventDefault();
    const id = e.dataTransfer.getData('text/plain') || dragId;
    if (!id) return;
    const p = people.find(x => x.id === id);
    if (p && p.stage !== s) moveTo(id, s);
    setDragId(null); setDragOver(null);
  };

  /* document upload/preview */
  const uploadDoc = async (driverId, docKey, file) => {
    if (!file) return;
    if (file.size > 8 * 1024 * 1024) { toast('File too large (max 8 MB)'); return; }
    const idbKey = `${driverId}/${docKey}`;
    try {
      await idb.put(idbKey, file);
      setDoc(driverId, docKey, { status: 'received', filename: file.name, size: file.size, mime: file.type, uploadedAt: new Date().toISOString() });
      toast(`Uploaded ${file.name}`, 'success');
    } catch (e) {
      console.error(e);
      toast('Upload failed');
    }
  };
  const previewDoc = async (driverId, docKey) => {
    const idbKey = `${driverId}/${docKey}`;
    try {
      const blob = await idb.get(idbKey);
      if (!blob) { toast('File no longer available'); return; }
      const url = URL.createObjectURL(blob);
      const p = people.find(x => x.id === driverId);
      const docMeta = p && p.docs[docKey];
      setPreview({ name: (docMeta && docMeta.filename) || docKey, url, mime: blob.type });
    } catch (e) {
      console.error(e); toast('Could not open file');
    }
  };
  const removeDoc = async (driverId, docKey) => {
    const idbKey = `${driverId}/${docKey}`;
    try { await idb.del(idbKey); } catch {}
    setDoc(driverId, docKey, { status: 'missing', filename: undefined, size: undefined, mime: undefined, uploadedAt: undefined, verifiedAt: undefined });
  };
  const verifyDoc = (driverId, docKey, verified) => {
    setDoc(driverId, docKey, { status: verified ? 'verified' : 'received', verifiedAt: verified ? new Date().toISOString() : undefined });
  };

  /* stats */
  const inPipeline = people.filter(p => !['active'].includes(p.stage)).length;
  const drivingNow = people.filter(p => p.stage === 'active').length;
  const interviewsThisWeek = people.filter(p => p.stage === 'interview').length;
  const ticketsBooked = people.filter(p => p.stage === 'tickets' || p.stage === 'enroute').length;

  return (
    <>
      <header className="top">
        <div className="top-inner">
          <a href="https://pruvistatransport.com" className="brand-row">
            <img src="assets/logo.png" alt="Pruvista Transport" />
            <div className="b-title">
              <strong>Pruvista</strong>
              <span>RECRUITING</span>
            </div>
          </a>
          <div className="search">
            <Icon name="search" size={15}/>
            <input placeholder="Search name, phone, city, source…" value={query} onChange={e => setQuery(e.target.value)} />
          </div>
          <button className="btn btn-primary" onClick={() => setAdding(true)}>
            <Icon name="plus" size={15}/> Add driver
          </button>
        </div>
      </header>

      <div className="headline">
        <div>
          <h1>Drivers</h1>
          <div className="sub"><strong>{inPipeline}</strong> in pipeline · <strong>{drivingNow}</strong> driving · drag cards between columns to advance</div>
        </div>
      </div>

      <div className="stats">
        <div className="stat"><div className="k">In pipeline</div><div className="v">{inPipeline}</div><div className="sub">Active candidates</div></div>
        <div className="stat"><div className="k">Interviews</div><div className="v">{interviewsThisWeek}</div><div className="sub">Scheduled / due</div></div>
        <div className="stat"><div className="k">Onboarding</div><div className="v">{people.filter(p => ['onboarding','processing'].includes(p.stage)).length}</div><div className="sub">Docs in flight</div></div>
        <div className="stat"><div className="k">Travel booked</div><div className="v">{ticketsBooked}</div><div className="sub">Flights / Uber arranged</div></div>
        <div className="stat"><div className="k">Driving</div><div className="v">{drivingNow}</div><div className="sub">Active on the road</div></div>
      </div>

      <div className="view-bar">
        <div className="tabs">
          <button className={cls('tab', view === 'kanban' && 'active')} onClick={() => setView('kanban')}>
            <Icon name="grid" size={13}/> Kanban
          </button>
          <button className={cls('tab', view === 'table' && 'active')} onClick={() => setView('table')}>
            <Icon name="table" size={13}/> Table
          </button>
        </div>
        <span className="hint">{filtered.length} of {people.length} drivers shown</span>
      </div>

      {view === 'kanban' ? (
        <div className="kanban-wrap">
          <div className="kanban">
            {STAGES.map(s => {
              const inCol = filtered.filter(p => p.stage === s.key);
              return (
                <div
                  key={s.key}
                  className={cls('col', dragOver === s.key && 'drag-over')}
                  onDragOver={(e) => onDragOverCol(e, s.key)}
                  onDragLeave={() => setDragOver(o => o === s.key ? null : o)}
                  onDrop={(e) => onDropCol(e, s.key)}
                >
                  <div className="col-head">
                    <h3><span className="dot" style={{background: s.color}}></span>{s.label}</h3>
                    <span className="count">{inCol.length}</span>
                  </div>
                  {inCol.map(p => (
                    <Card
                      key={p.id}
                      p={p}
                      dragging={dragId === p.id}
                      onDragStart={(e) => onDragStart(e, p.id)}
                      onDragEnd={onDragEnd}
                      onPick={() => setPickedId(p.id)}
                    />
                  ))}
                  {inCol.length === 0 && <div className="col-empty">— empty —</div>}
                </div>
              );
            })}
          </div>
        </div>
      ) : (
        <TableView people={filtered} onPick={(id) => setPickedId(id)} />
      )}

      <div className="back-bar">
        <a href="https://pruvistatransport.com">← back to website</a>
      </div>

      <Drawer
        picked={picked}
        onClose={() => setPickedId(null)}
        onMove={moveTo}
        onUpdate={update}
        onRemove={remove}
        onUploadDoc={uploadDoc}
        onPreviewDoc={previewDoc}
        onRemoveDoc={removeDoc}
        onVerifyDoc={verifyDoc}
      />

      <AddModal open={adding} onClose={() => setAdding(false)} onAdd={add} />

      <PreviewModal preview={preview} onClose={() => { if (preview) URL.revokeObjectURL(preview.url); setPreview(null); }} />

      <div className="toast-area">
        {toasts.map(t => <div key={t.id} className={cls('toast', t.kind)}>{t.msg}</div>)}
      </div>
    </>
  );
}

/* ────────── Card ────────── */
const Card = ({ p, dragging, onDragStart, onDragEnd, onPick }) => {
  const disp = dispOf(p.disposition);
  const docsReceived = DOC_TYPES.filter(d => p.docs[d.key]?.status !== 'missing').length;
  const docsTotal = DOC_TYPES.length;
  const docsPct = Math.round(docsReceived / docsTotal * 100);
  return (
    <div
      className={cls('card', dragging && 'dragging')}
      draggable
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      onClick={onPick}
    >
      <div className="row1">
        <div className="av">{initials(p.name)}</div>
        <div style={{flex:1, minWidth:0}}>
          <div className="name">{p.name}</div>
        </div>
      </div>
      <div className="meta">
        <span>{p.years}yr</span>
        <span className="sep">·</span>
        <span>{p.city}</span>
      </div>
      <div className="tags">
        <span className="tag info">{p.source}</span>
        {p.disposition !== 'none' && <span className="tag" style={{borderColor: disp.color+'55', color: disp.color, background: disp.color+'12'}}>{disp.label}</span>}
        <span className={cls('tag', p.daysIn > 7 ? 'warn' : '')}>{p.daysIn}d</span>
      </div>
      {docsReceived > 0 && (
        <div className="doc-prog">
          <span>{docsReceived}/{docsTotal} docs</span>
          <div className="doc-bar"><div className="fill" style={{width: docsPct+'%'}}></div></div>
        </div>
      )}
    </div>
  );
};

/* ────────── Table view ────────── */
const TableView = ({ people, onPick }) => {
  if (people.length === 0) return <div className="table-wrap"><div className="tbl-outer" style={{padding:40, textAlign:'center', color:'var(--muted)'}}>No drivers match.</div></div>;
  return (
    <div className="table-wrap">
      <div className="tbl-outer">
        <div className="tbl-scroll">
          <table className="tbl">
            <thead>
              <tr>
                <th>Driver</th>
                <th>Stage</th>
                <th>Disposition</th>
                <th>Phone</th>
                <th>Source</th>
                <th>Yrs</th>
                <th>Days</th>
                <th title="Documents">Docs</th>
              </tr>
            </thead>
            <tbody>
              {people.map(p => {
                const stage = stageOf(p.stage);
                const disp = dispOf(p.disposition);
                return (
                  <tr key={p.id} onClick={() => onPick(p.id)}>
                    <td>
                      <div className="tbl-name">
                        <div className="av">{initials(p.name)}</div>
                        <div>
                          <strong>{p.name}</strong>
                          <div className="city">{p.city}</div>
                        </div>
                      </div>
                    </td>
                    <td><span className="tag" style={{borderColor: stage.color+'55', color: stage.color, background: stage.color+'12'}}>{stage.label}</span></td>
                    <td><span className="tag" style={{borderColor: disp.color+'55', color: disp.color, background: disp.color+'12'}}>{disp.label}</span></td>
                    <td className="mono" style={{fontSize:12}}>{p.phone}</td>
                    <td className="mono" style={{fontSize:12}}>{p.source}</td>
                    <td className="mono" style={{fontSize:12}}>{p.years}</td>
                    <td className="mono" style={{fontSize:12}}>{p.daysIn}d</td>
                    <td>
                      <div className="doc-icons">
                        {DOC_TYPES.map(d => {
                          const st = p.docs[d.key]?.status || 'missing';
                          return <span key={d.key} className={cls('doc-dot', st)} title={`${d.label}: ${st}`}>{d.label[0]}</span>;
                        })}
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
};

/* ────────── Drawer ────────── */
const Drawer = ({ picked, onClose, onMove, onUpdate, onRemove, onUploadDoc, onPreviewDoc, onRemoveDoc, onVerifyDoc }) => {
  const [notesLocal, setNotesLocal] = useState('');
  useEffect(() => { if (picked) setNotesLocal(picked.notes || ''); }, [picked?.id]);

  if (!picked) return (
    <>
      <div className="drawer-back" onClick={onClose}></div>
      <div className="drawer"></div>
    </>
  );
  const saveNotes = () => onUpdate(picked.id, { notes: notesLocal });
  const idx  = STAGES.findIndex(s => s.key === picked.stage);
  const next = idx >= 0 && idx < STAGES.length - 1 ? STAGES[idx + 1] : null;
  const back = idx > 0 ? STAGES[idx - 1] : null;

  return (
    <>
      <div className={cls('drawer-back', picked && 'open')} onClick={onClose}></div>
      <div className={cls('drawer', picked && 'open')}>
        <div className="drawer-head">
          <div className="av">{initials(picked.name)}</div>
          <div className="who">
            <h2>{picked.name}</h2>
            <div className="sub">{stageOf(picked.stage).label} · {picked.years} yrs · {picked.city}</div>
          </div>
          <button className="drawer-close" onClick={onClose}><Icon name="x" size={13}/></button>
        </div>

        <div className="drawer-body">

          <div className="drawer-section">
            <h4>Contact</h4>
            <div className="field-row"><div className="lbl">Phone</div><div className="val"><a href={`tel:${picked.phone}`}>{picked.phone}</a></div></div>
            <div className="field-row"><div className="lbl">Email</div><div className="val"><a href={`mailto:${picked.email}`}>{picked.email}</a></div></div>
            <div className="field-row"><div className="lbl">City</div><div className="val">{picked.city}</div></div>
            <div className="field-row"><div className="lbl">Source</div><div className="val">{picked.source}</div></div>
          </div>

          <div className="drawer-section">
            <h4>Disposition · last call</h4>
            <div className="disp-grid">
              {DISPOSITIONS.map(d => (
                <button key={d.key} className={cls('disp-btn', picked.disposition === d.key && 'active')} onClick={() => onUpdate(picked.id, { disposition: d.key })}>
                  <span className="ico" style={{background: d.color}}></span>
                  {d.label}
                </button>
              ))}
            </div>
          </div>

          <div className="drawer-section">
            <h4>Documents</h4>
            <div className="docs-grid">
              {DOC_TYPES.map(d => {
                const st = picked.docs[d.key] || { status: 'missing' };
                return <DocCard key={d.key} doc={d} state={st}
                  onUpload={(file) => onUploadDoc(picked.id, d.key, file)}
                  onPreview={() => onPreviewDoc(picked.id, d.key)}
                  onRemove={() => onRemoveDoc(picked.id, d.key)}
                  onVerify={(v) => onVerifyDoc(picked.id, d.key, v)}
                />;
              })}
            </div>
          </div>

          <div className="drawer-section">
            <h4>Notes</h4>
            <textarea className="notes" placeholder="Anything to remember about this driver…" value={notesLocal} onChange={e => setNotesLocal(e.target.value)} onBlur={saveNotes} />
          </div>

          <div className="drawer-section">
            <h4>Stage</h4>
            <div className="actions">
              {back && <button className="btn btn-ghost" onClick={() => onMove(picked.id, back.key)}><Icon name="arrowL" size={13}/> {back.label}</button>}
              {next && <button className="btn btn-primary" onClick={() => onMove(picked.id, next.key)}>{next.label} <Icon name="arrow" size={13}/></button>}
              {picked.stage !== 'active' && <button className="btn btn-success full" onClick={() => onMove(picked.id, 'active')}><Icon name="check" size={13}/> Mark driving</button>}
            </div>
          </div>

          <div className="drawer-section">
            <button className="btn btn-danger-ghost" onClick={() => { if (confirm(`Remove ${picked.name}?`)) onRemove(picked.id); }}>
              <Icon name="trash" size={13}/> Remove driver
            </button>
          </div>
        </div>
      </div>
    </>
  );
};

/* ────────── DocCard ────────── */
const DocCard = ({ doc, state, onUpload, onPreview, onRemove, onVerify }) => {
  const inputRef = useRef(null);
  const st = state.status || 'missing';
  return (
    <div className={cls('doc-card', st)}>
      <div className="doc-top">
        <Icon name="file" size={13} className="mono" />
        <div>
          <div className="doc-name">{doc.label}</div>
          <div className="doc-sub">{state.filename ? state.filename : doc.sub}</div>
        </div>
        <span className="doc-status">{st === 'missing' ? 'Missing' : st === 'received' ? 'Got it' : 'Verified ✓'}</span>
      </div>
      {st === 'missing' && (
        <div className="doc-actions">
          <button className="btn btn-mini-primary" onClick={() => inputRef.current?.click()}>
            <Icon name="upload" size={11}/> Upload
          </button>
          <input ref={inputRef} type="file" accept="image/*,application/pdf" style={{display:'none'}} onChange={e => onUpload(e.target.files?.[0])} />
        </div>
      )}
      {st !== 'missing' && (
        <div className="doc-actions">
          <button className="btn btn-mini-ghost" onClick={onPreview}><Icon name="eye" size={11}/> View</button>
          {st === 'received' && <button className="btn btn-mini-success" onClick={() => onVerify(true)}><Icon name="check" size={11}/> Verify</button>}
          {st === 'verified' && <button className="btn btn-mini-ghost" onClick={() => onVerify(false)}>Unverify</button>}
          <button className="btn btn-mini-danger" onClick={onRemove} title="Remove file"><Icon name="trash" size={11}/></button>
        </div>
      )}
    </div>
  );
};

/* ────────── Preview modal ────────── */
const PreviewModal = ({ preview, onClose }) => {
  const open = !!preview;
  const isImg = preview && /^image\//.test(preview.mime || '');
  const isPdf = preview && /pdf/.test(preview.mime || '');
  return (
    <div className={cls('preview-back', open && 'open')} onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="preview-inner">
        <div className="ph">
          <Icon name="file" size={14}/>
          <div className="name">{preview?.name}</div>
          <button className="drawer-close" onClick={onClose}><Icon name="x" size={13}/></button>
        </div>
        {isImg && <img src={preview.url} alt={preview.name} />}
        {isPdf && <iframe src={preview.url} title={preview.name} style={{width: '80vw', height: '78vh', border:0}}/>}
        {!isImg && !isPdf && preview && (
          <div className="fallback">
            <Icon name="file" size={28}/>
            <div style={{marginTop:10}}>Can't preview this format.</div>
            <a href={preview.url} download={preview.name} className="btn btn-ghost" style={{marginTop:14}}>Download</a>
          </div>
        )}
      </div>
    </div>
  );
};

/* ────────── Add modal ────────── */
const AddModal = ({ open, onClose, onAdd }) => {
  const [form, setForm] = useState({ name: '', phone: '', email: '', city: '', years: '', source: 'Indeed', stage: 'new', notes: '' });
  const firstRef = useRef(null);
  useEffect(() => {
    if (open) {
      setForm({ name: '', phone: '', email: '', city: '', years: '', source: 'Indeed', stage: 'new', notes: '' });
      setTimeout(() => firstRef.current?.focus(), 60);
    }
  }, [open]);
  const submit = (e) => {
    e.preventDefault();
    if (!form.name.trim()) return;
    onAdd({ ...form, name: form.name.trim(), phone: form.phone.trim(), email: form.email.trim(), city: form.city.trim() || '—', years: Number(form.years) || 0 });
  };
  return (
    <div className={cls('modal-back', open && 'open')} onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <form className="modal" onSubmit={submit}>
        <h2>Add driver</h2>
        <p className="sub">New driver lands in the stage you pick.</p>

        <div className="field">
          <label>Name</label>
          <input ref={firstRef} type="text" required value={form.name} onChange={e => setForm({...form, name: e.target.value})} placeholder="Marcus Johnson" />
        </div>
        <div className="row2">
          <div className="field">
            <label>Phone</label>
            <input type="tel" value={form.phone} onChange={e => setForm({...form, phone: e.target.value})} placeholder="(555) 555-5555" />
          </div>
          <div className="field">
            <label>Years exp</label>
            <input type="number" min="0" max="50" value={form.years} onChange={e => setForm({...form, years: e.target.value})} placeholder="5" />
          </div>
        </div>
        <div className="field">
          <label>Email</label>
          <input type="email" value={form.email} onChange={e => setForm({...form, email: e.target.value})} placeholder="driver@email.com" />
        </div>
        <div className="row2">
          <div className="field">
            <label>City</label>
            <input type="text" value={form.city} onChange={e => setForm({...form, city: e.target.value})} placeholder="Newark, NJ" />
          </div>
          <div className="field">
            <label>Source</label>
            <select value={form.source} onChange={e => setForm({...form, source: e.target.value})}>
              <option>Indeed</option><option>Referral</option><option>Facebook</option>
              <option>Drive4PT</option><option>Class A</option><option>TruckersReport</option>
              <option>Walk-in</option><option>Other</option>
            </select>
          </div>
        </div>
        <div className="field">
          <label>Start stage</label>
          <select value={form.stage} onChange={e => setForm({...form, stage: e.target.value})}>
            {STAGES.map(s => <option key={s.key} value={s.key}>{s.label}</option>)}
          </select>
        </div>

        <div className="modal-foot">
          <button type="button" className="btn btn-ghost" onClick={onClose}>Cancel</button>
          <button type="submit" className="btn btn-primary"><Icon name="plus" size={13}/> Add driver</button>
        </div>
      </form>
    </div>
  );
};

const root = document.createElement('div');
document.body.appendChild(root);
ReactDOM.createRoot(root).render(<App />);
