// People — a relationship directory auto-built from the inbox.
// Deterministic colour avatars (no profile pictures assumed), category chips,
// search / sort, an inbox scope filter, and a detail drawer with the email
// history Zeranda has seen for each person.

// ---- Deterministic colour avatar ------------------------------------------
// No external avatar service needed: a stable hash of the address picks a hue,
// so every contact gets a distinct, repeatable two-tone gradient + initials.
function pHash(s) { let h = 0; for (const c of String(s || '')) h = (h * 31 + c.charCodeAt(0)) >>> 0; return h; }
function pInitials(name, email) {
  const src = (name || email || '?').trim();
  const parts = src.split(/\s+/).filter(Boolean);
  if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
  return src.slice(0, 2).toUpperCase();
}
function PersonAvatar({ person, size = 46, radius = '30%' }) {
  const h = pHash(person.email || person.name);
  const hue = h % 360, hue2 = (hue + 38) % 360;
  const bg = `linear-gradient(135deg, oklch(0.74 0.13 ${hue}), oklch(0.6 0.15 ${hue2}))`;
  return (
    <span className="pavatar" style={{ width: size, height: size, borderRadius: radius, background: bg, fontSize: Math.round(size * 0.36) }}>
      {person.photo ? <img src={person.photo} alt="" style={{ width: '100%', height: '100%', borderRadius: 'inherit', objectFit: 'cover' }} /> : pInitials(person.name, person.email)}
    </span>
  );
}

// ---- Relative time -------------------------------------------------------
const NOW = new Date('2026-06-24T12:00:00');
function ago(iso) {
  if (!iso) return '';
  const d = Math.floor((NOW - new Date(iso)) / 86400000);
  if (d <= 0) return 'today';
  if (d === 1) return 'yesterday';
  if (d < 7) return d + 'd ago';
  if (d < 30) return Math.floor(d / 7) + 'w ago';
  if (d < 365) return Math.floor(d / 30) + 'mo ago';
  return Math.floor(d / 365) + 'y ago';
}
function shortDate(iso) {
  if (!iso) return '';
  return new Date(iso).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
}
function catMeta(id) { return window.ZD_DATA.peopleCategories.find(c => c.id === id) || { label: id, tint: 'gold', icon: 'user' }; }

// ---- Person card (grid view) ---------------------------------------------
function PersonCard({ p, onOpen }) {
  const cm = catMeta(p.cat);
  return (
    <button className="person-card rise" onClick={() => onOpen(p)}>
      <div className="pc-top">
        <PersonAvatar person={p} size={48} />
        <div className="pc-id">
          <div className="pc-nm">{p.name}{p.vip && <Icon name="star" size={13} color="var(--gold-500)" style={{ marginLeft: 5, fill: 'var(--gold-500)' }} />}</div>
          <div className="pc-em">{p.email}</div>
        </div>
      </div>
      <div className="pc-meta">
        <span className="cat-tag"><span className="dd-dot" style={{ background: tintFg(cm.tint) }} />{cm.label}</span>
        {p.role && <span className="pc-role">{p.role}{p.org ? ` · ${p.org}` : ''}</span>}
      </div>
      <div className="pc-foot">
        <span className="pc-stat"><Icon name="mail" size={13} color="var(--fg-4)" /> {p.total} emails</span>
        <span className="pc-stat"><Icon name="clock" size={13} color="var(--fg-4)" /> {ago(p.lastISO)}</span>
        {p.needsReply && <span className="pc-reply"><Icon name="corner-up-left" size={12} /> Reply due</span>}
      </div>
    </button>
  );
}

// ---- Detail drawer -------------------------------------------------------
function PersonDrawer({ person, editing, onClose, onEdit, onSave, onToggleVip, onDelete }) {
  const D = window.ZD_DATA;
  const [form, setForm] = useState(person);
  useEffect(() => { setForm(person); }, [person]);
  if (!person) return null;
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const cm = catMeta(form.cat);
  const catOpts = D.peopleCategories.map(c => ({ value: c.id, label: c.label, icon: c.icon, tint: c.tint }));
  const respRate = form.total ? Math.round((form.sent / form.total) * 100) : 0;
  const mailto = () => { window.open('mailto:' + form.email, '_blank'); };

  return (
    <React.Fragment>
      <div className="scrim" onClick={onClose} />
      <div className="drawer zd-scroll">
        <div className="dhead">
          <PersonAvatar person={form} size={44} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 18, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{form.name}</div>
            <div style={{ fontSize: 12.5, color: 'var(--fg-3)' }}>{editing ? 'Editing contact' : (form.role ? `${form.role}${form.org ? ' · ' + form.org : ''}` : cm.label)}</div>
          </div>
          {!editing && <button className={`iconbtn ${form.vip ? 'on-gold' : ''}`} title={form.vip ? 'Remove star' : 'Mark VIP'} onClick={() => onToggleVip(form.id)}><Icon name="star" size={18} color={form.vip ? 'var(--gold-500)' : 'var(--fg-3)'} style={form.vip ? { fill: 'var(--gold-500)' } : undefined} /></button>}
          <button className="iconbtn" onClick={onClose}><Icon name="x" size={18} /></button>
        </div>

        {!editing ? (
          /* ---------- VIEW ---------- */
          <div className="dbody">
            {form.needsReply && (
              <div className="reply-banner"><Icon name="corner-up-left" size={16} color="var(--gold-700)" />
                <div><b>Waiting on your reply</b><span>Last message from {form.name.split(' ')[0]} is unanswered.</span></div>
                <button className="btn btn-primary" style={{ padding: '7px 12px' }} onClick={mailto}>Reply</button>
              </div>
            )}

            <div className="pstat-row">
              <div className="pstat"><div className="pv">{form.total}</div><div className="pk">Emails</div></div>
              <div className="pstat"><div className="pv">{form.sent}</div><div className="pk">Sent</div></div>
              <div className="pstat"><div className="pv">{form.received}</div><div className="pk">Received</div></div>
              <div className="pstat"><div className="pv">{respRate}%</div><div className="pk">From you</div></div>
            </div>

            <div className="field"><div className="k">Email</div><div className="v" style={{ display: 'flex', alignItems: 'center', gap: 8 }}><Icon name="mail" size={15} color="var(--fg-3)" /><span className="zd-mono" style={{ fontSize: 13.5 }}>{form.email}</span></div></div>
            {form.phone && <div className="field"><div className="k">Phone</div><div className="v" style={{ display: 'flex', alignItems: 'center', gap: 8 }}><Icon name="phone" size={15} color="var(--fg-3)" /><span className="zd-mono" style={{ fontSize: 13.5 }}>{form.phone}</span></div></div>}
            <div className="drow">
              <div className="field" style={{ flex: 1 }}><div className="k">Category</div><div className="v"><span className="cat-tag"><span className="dd-dot" style={{ background: tintFg(cm.tint) }} />{cm.label}</span></div></div>
              {form.org && <div className="field" style={{ flex: 1 }}><div className="k">Organisation</div><div className="v">{form.org}</div></div>}
            </div>
            <div className="drow">
              <div className="field" style={{ flex: 1 }}><div className="k">First seen</div><div className="v" style={{ fontSize: 13.5 }}>{shortDate(form.firstISO)}</div></div>
              <div className="field" style={{ flex: 1 }}><div className="k">Last contact</div><div className="v" style={{ fontSize: 13.5 }}>{shortDate(form.lastISO)} · {ago(form.lastISO)}</div></div>
            </div>

            <div className="field"><div className="k">Appears in</div>
              <div className="pmbx">{(form.mailboxes || [form.mailbox]).map(a => <MailboxBadge key={a} addr={a} variant="full" />)}</div>
            </div>

            <div className="field"><div className="k">Recent emails <span className="kn">{(form.threads || []).length}</span></div>
              <div className="thread-list">
                {(form.threads || []).map((t, i) => (
                  <button className="thread-row" key={i} onClick={() => openAttachment({ name: 'Email · ' + t.subject })}>
                    <span className={`th-dir ${t.dir}`}><Icon name={t.dir === 'out' ? 'corner-up-right' : 'corner-down-left'} size={13} /></span>
                    <div className="th-main">
                      <div className="th-subj">{t.subject}</div>
                      <div className="th-snip">{t.snippet}</div>
                      <div className="th-meta"><MailboxBadge addr={t.mailbox} variant="mini" /><span className="th-dot">·</span>{shortDate(t.dateISO)}</div>
                    </div>
                    <Icon name="chevron-right" size={15} color="var(--fg-4)" />
                  </button>
                ))}
                {(!form.threads || !form.threads.length) && <div className="card-empty" style={{ justifyContent: 'flex-start' }}><Icon name="inbox" size={18} color="var(--fg-4)" /><span>No linked emails yet.</span></div>}
              </div>
            </div>

            <div className="drawer-foot" style={{ flexWrap: 'wrap' }}>
              <Btn variant="primary" icon="send" style={{ flex: 1, justifyContent: 'center' }} onClick={mailto}>Compose email</Btn>
              <Btn variant="secondary" icon="pencil" onClick={onEdit}>Edit</Btn>
              <button className="iconbtn danger" onClick={() => onDelete(form.id)} title="Remove contact"><Icon name="trash-2" size={17} /></button>
            </div>
          </div>
        ) : (
          /* ---------- EDIT ---------- */
          <div className="dbody">
            <label className="fl">Full name</label>
            <div className="finput"><Icon name="user" size={16} color="var(--fg-4)" /><input value={form.name} onChange={e => set('name', e.target.value)} placeholder="Contact name" /></div>

            <label className="fl">Email</label>
            <div className="finput"><Icon name="mail" size={16} color="var(--fg-4)" /><input value={form.email} onChange={e => set('email', e.target.value)} placeholder="name@example.com" /></div>

            <div className="drow">
              <div style={{ flex: 1 }}>
                <label className="fl">Role <span className="fl-opt">optional</span></label>
                <div className="finput"><Icon name="id-card" size={16} color="var(--fg-4)" /><input value={form.role || ''} onChange={e => set('role', e.target.value)} placeholder="e.g. Manager" /></div>
              </div>
              <div style={{ flex: 1 }}>
                <label className="fl">Organisation <span className="fl-opt">optional</span></label>
                <div className="finput"><Icon name="building-2" size={16} color="var(--fg-4)" /><input value={form.org || ''} onChange={e => set('org', e.target.value)} placeholder="Company" /></div>
              </div>
            </div>

            <label className="fl">Phone <span className="fl-opt">optional</span></label>
            <div className="finput"><Icon name="phone" size={16} color="var(--fg-4)" /><input value={form.phone || ''} onChange={e => set('phone', e.target.value)} placeholder="+1 …" /></div>

            <label className="fl">Category</label>
            <Dropdown value={form.cat} options={catOpts} onChange={v => set('cat', v)} minWidth={'100%'} />

            <div className="toggle-row">
              <div><div className="tr-t">VIP contact</div><div className="tr-s">Star and surface this person first</div></div>
              <button className={`zswitch ${form.vip ? 'on' : ''}`} role="switch" aria-checked={!!form.vip} onClick={() => set('vip', !form.vip)}><span className="knob" /></button>
            </div>
            <div className="toggle-row">
              <div><div className="tr-t">Awaiting reply</div><div className="tr-s">Flag that you owe them a response</div></div>
              <button className={`zswitch ${form.needsReply ? 'on' : ''}`} role="switch" aria-checked={!!form.needsReply} onClick={() => set('needsReply', !form.needsReply)}><span className="knob" /></button>
            </div>

            <div className="drawer-foot">
              <Btn variant="ghost" onClick={onClose}>Cancel</Btn>
              <Btn variant="primary" icon="check" style={{ flex: 1, justifyContent: 'center' }} onClick={() => onSave(form)}>Save changes</Btn>
            </div>
          </div>
        )}
      </div>
    </React.Fragment>
  );
}

// ---- People screen -------------------------------------------------------
function People() {
  const D = window.ZD_DATA;
  const perm = usePermissions();
  const [people, setPeople] = useState(D.people);
  const [q, setQ] = useState('');
  const [cat, setCat] = useState('all');
  const [acct, setAcct] = useState('all');
  const [view, setView] = useState('grid');
  const [sortKey, setSortKey] = useState('recent');
  const [sel, setSel] = useState(null);
  const [editing, setEditing] = useState(false);
  const [page, setPage] = useState(1);
  const PAGE = view === 'grid' ? 12 : 9;

  const accounts = perm.accounts();
  const acctEmail = acct !== 'all' ? (perm.account(acct) || {}).email : null;
  const inAcct = p => !acctEmail || (p.mailboxes || [p.mailbox]).includes(acctEmail);

  const catOpts = [{ value: 'all', label: 'All categories' },
    ...D.peopleCategories.map(c => ({ value: c.id, label: c.label, icon: c.icon, tint: c.tint }))];
  const sortOpts = [
    { value: 'recent', label: 'Most recent' },
    { value: 'frequent', label: 'Most emails' },
    { value: 'name', label: 'Name (A → Z)' },
    { value: 'oldest', label: 'Oldest contact' },
  ];

  // counts per category (respecting the account scope + VIP/reply pseudo-cats)
  const scoped = people.filter(inAcct);
  const catCounts = { all: scoped.length, vip: scoped.filter(p => p.vip).length, reply: scoped.filter(p => p.needsReply).length };
  D.peopleCategories.forEach(c => { catCounts[c.id] = scoped.filter(p => p.cat === c.id).length; });
  const acctCounts = { all: people.length };
  accounts.forEach(a => { acctCounts[a.id] = people.filter(p => (p.mailboxes || [p.mailbox]).includes(a.email)).length; });

  let rows = scoped.filter(p =>
    (cat === 'all' || (cat === 'vip' ? p.vip : cat === 'reply' ? p.needsReply : p.cat === cat)) &&
    (p.name.toLowerCase().includes(q.toLowerCase()) || p.email.toLowerCase().includes(q.toLowerCase()) || (p.org || '').toLowerCase().includes(q.toLowerCase()))
  );
  rows = [...rows].sort((a, b) => {
    if (sortKey === 'name') return a.name.localeCompare(b.name);
    if (sortKey === 'frequent') return b.total - a.total;
    if (sortKey === 'oldest') return (a.firstISO || '').localeCompare(b.firstISO || '');
    return (b.lastISO || '').localeCompare(a.lastISO || '');   // recent
  });
  // VIPs float up within the default recent sort
  if (sortKey === 'recent') rows = [...rows].sort((a, b) => (b.vip ? 1 : 0) - (a.vip ? 1 : 0));

  const filtered = q || cat !== 'all' || acct !== 'all';
  const pageCount = Math.ceil(rows.length / PAGE) || 1;
  const pg = Math.min(page, pageCount);
  const paged = rows.slice((pg - 1) * PAGE, pg * PAGE);
  useEffect(() => { setPage(1); }, [q, cat, acct, sortKey, view]);

  const newPerson = () => {
    setSel({ id: 'pp' + Date.now(), name: '', email: '', cat: 'colleagues', role: '', org: '', phone: '',
      mailbox: D.user.email, mailboxes: [D.user.email], vip: false, needsReply: false,
      total: 0, sent: 0, received: 0, firstISO: '2026-06-24', lastISO: '2026-06-24', threads: [], isNew: true });
    setEditing(true);
  };
  useCreateShortcut(newPerson);

  const savePerson = u => {
    setPeople(ps => ps.some(p => p.id === u.id) ? ps.map(p => p.id === u.id ? u : p) : [{ ...u, isNew: undefined }, ...ps]);
    setSel({ ...u, isNew: undefined }); setEditing(false);
  };
  const delPerson = id => { setPeople(ps => ps.filter(p => p.id !== id)); setSel(null); setEditing(false); };
  const toggleVip = id => {
    setPeople(ps => ps.map(p => p.id === id ? { ...p, vip: !p.vip } : p));
    setSel(s => s && s.id === id ? { ...s, vip: !s.vip } : s);
  };

  const totalEmails = scoped.reduce((s, p) => s + p.total, 0);

  const CHIPS = [
    { id: 'all', label: 'All', icon: 'users' },
    { id: 'vip', label: 'VIPs', icon: 'star', tint: 'gold' },
    { id: 'reply', label: 'Reply due', icon: 'corner-up-left', tint: 'red' },
    ...D.peopleCategories.map(c => ({ id: c.id, label: c.label, icon: c.icon, tint: c.tint })),
  ];

  return (
    <div className="screen-inner">
      <div className="statrow">
        <StatCard label="Contacts" value={scoped.length} sub={`${totalEmails.toLocaleString()} emails tracked`} icon="users" tint="blue" />
        <StatCard label="VIPs" value={catCounts.vip} sub="Starred people" icon="star" tint="gold" />
        <StatCard label="Awaiting reply" value={catCounts.reply} sub={catCounts.reply ? 'You owe a response' : 'All caught up'} icon="corner-up-left" tint={catCounts.reply ? 'red' : 'green'} />
        <StatCard label="Categories" value={D.peopleCategories.length} sub="Relationship groups" icon="layers" tint="purple" />
      </div>

      <div className="card rise" style={{ overflow: 'hidden' }}>
        <div className="card-pad" style={{ paddingBottom: 0 }}>
          <SectionHeader title="People" sub="Everyone Zeranda has seen across your connected inboxes"
            actionEl={<Btn variant="primary" icon="user-plus" kbd="C" title="Add contact — press C" onClick={newPerson}>Add person</Btn>} />

          <div className="filterbar">
            <div className="search" style={{ flex: '1 1 220px' }}><Icon name="search" size={17} /><input placeholder="Search name, email or company…" value={q} onChange={e => setQ(e.target.value)} />{q && <button className="x-clear" onClick={() => setQ('')}><Icon name="x" size={14} /></button>}</div>
            <Dropdown value={cat} options={catOpts} onChange={setCat} icon="filter" minWidth={168} />
            <Dropdown value={sortKey} options={sortOpts} onChange={setSortKey} icon="arrow-up-down" minWidth={158} />
            <div className="seg view-seg">
              <button className={view === 'grid' ? 'on' : ''} onClick={() => setView('grid')} title="Grid"><Icon name="layout-grid" size={16} /></button>
              <button className={view === 'list' ? 'on' : ''} onClick={() => setView('list')} title="List"><Icon name="list" size={16} /></button>
            </div>
          </div>

          {/* category quick-chips */}
          <div className="catchips zd-scroll">
            {CHIPS.map(c => (
              <button key={c.id} className={`catchip ${cat === c.id ? 'on' : ''}`} onClick={() => setCat(c.id)}>
                <span className="cc-ic" style={{ background: c.tint ? tintBg(c.tint) : 'var(--surface-sunk)' }}><Icon name={c.icon} size={13} color={c.tint ? tintFg(c.tint) : 'var(--fg-3)'} /></span>
                {c.label}<span className="cc-n">{catCounts[c.id] || 0}</span>
              </button>
            ))}
          </div>

          {/* inbox scope */}
          <div style={{ margin: '4px 0 14px' }}>
            <AccountFilterBar accounts={accounts} value={acct} onChange={setAcct} counts={acctCounts} warnScope="contacts" warnTitle="Contacts access not granted" />
          </div>

          <div className="filtbar-2" style={{ borderTop: '1px solid var(--border)', paddingTop: 14 }}>
            <div className="result-meta" style={{ marginLeft: 0 }}>
              <span>{rows.length} {rows.length === 1 ? 'person' : 'people'}</span>
              {filtered && <button className="viewall" onClick={() => { setQ(''); setCat('all'); setAcct('all'); }}>Clear filters</button>}
            </div>
          </div>
        </div>

        {/* ---- GRID ---- */}
        {view === 'grid' && (
          <div className="people-grid">
            {paged.map(p => <PersonCard key={p.id} p={p} onOpen={x => { setSel(x); setEditing(false); }} />)}
          </div>
        )}

        {/* ---- LIST ---- */}
        {view === 'list' && (
          <table className="table">
            <thead><tr>
              <th>Name</th><th>Category</th><th style={{ textAlign: 'right' }}>Emails</th><th>Last contact</th><th style={{ width: 100, textAlign: 'right' }}>Actions</th>
            </tr></thead>
            <tbody>
              {paged.map(p => {
                const cm = catMeta(p.cat);
                return (
                  <tr key={p.id} onClick={() => { setSel(p); setEditing(false); }} style={{ cursor: 'pointer' }}>
                    <td className="cell-first"><div className="cellmain"><PersonAvatar person={p} size={38} radius="28%" /><div><div className="nm">{p.name}{p.vip && <Icon name="star" size={12} color="var(--gold-500)" style={{ marginLeft: 4, fill: 'var(--gold-500)' }} />}</div><div className="sub-acct">{p.email}<MailboxBadge addr={p.mailbox} variant="mini" />{p.needsReply && <span className="att-pin" style={{ color: 'var(--red-500)' }}><Icon name="corner-up-left" size={11} /> reply</span>}</div></div></div></td>
                    <td data-label="Category"><span className="cat-tag"><span className="dd-dot" style={{ background: tintFg(cm.tint) }} />{cm.label}</span></td>
                    <td data-label="Emails" style={{ textAlign: 'right', fontWeight: 700 }}>{p.total}</td>
                    <td className="muted" data-label="Last">{ago(p.lastISO)}</td>
                    <td data-label="Actions" style={{ textAlign: 'right' }}>
                      <div className="row-acts" onClick={e => e.stopPropagation()}>
                        <button className="iconbtn" onClick={() => toggleVip(p.id)} title={p.vip ? 'Unstar' : 'Mark VIP'}><Icon name="star" size={16} color={p.vip ? 'var(--gold-500)' : 'var(--fg-3)'} style={p.vip ? { fill: 'var(--gold-500)' } : undefined} /></button>
                        <button className="iconbtn" onClick={() => { setSel(p); setEditing(true); }} title="Edit"><Icon name="pencil" size={16} /></button>
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}

        {rows.length === 0 && <div className="table-empty" style={{ padding: '40px 20px' }}><Icon name="users" size={26} color="var(--fg-4)" /><span>No people match your filters.</span><button className="viewall" onClick={() => { setQ(''); setCat('all'); setAcct('all'); }}>Clear filters</button></div>}

        <Pager page={pg} pageCount={pageCount} total={rows.length} pageSize={PAGE} onPage={setPage} noun="people" />
      </div>

      {sel && <PersonDrawer person={sel} editing={editing} onClose={() => { setSel(null); setEditing(false); }}
        onEdit={() => setEditing(true)} onSave={savePerson} onToggleVip={toggleVip} onDelete={delPerson} />}
    </div>
  );
}
Object.assign(window, { People, PersonAvatar });
