// ATLAS Accounts Email Agent — views.jsx

// ── VerbChip — action type switcher (must be a component to use useState) ──
function VerbChip({ act, idx, isDone, actionMeta, onChangeType }) {
  const [open, setOpen] = useState(false);
  const meta = actionMeta[act.type] || actionMeta.flag;

  // Close on outside click
  useEffect(() => {
    if (!open) return;
    const handler = () => setOpen(false);
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [open]);

  return (
    <div style={{position:'relative',flexShrink:0}} onMouseDown={e=>e.stopPropagation()}>
      <button
        onClick={e=>{e.stopPropagation();setOpen(o=>!o);}}
        title="Click to change action type"
        style={{
          all:'unset', cursor:'pointer',
          padding:'8px 10px',
          borderRight:'1px solid #e2e8f0',
          background: isDone?'#dcfce7': open?'#e2e8f0':'#f1f5f9',
          fontSize:12, fontWeight:600,
          color: isDone?'#15803d':'#334155',
          whiteSpace:'nowrap', display:'flex', alignItems:'center', gap:5,
        }}>
        <span>{meta.icon}</span>
        <span style={{textDecoration:isDone?'line-through':'none'}}>{meta.verb}</span>
        <span style={{fontSize:9,color:'#94a3b8',marginLeft:1}}>▾</span>
      </button>
      {open && (
        <div style={{
          position:'absolute', top:'100%', left:0, zIndex:200, minWidth:180,
          background:'#fff', border:'1px solid #e2e8f0', borderRadius:8,
          boxShadow:'0 4px 16px rgba(0,0,0,.15)', overflow:'hidden', marginTop:2,
        }}>
          {Object.entries(actionMeta).map(([t, m]) => (
            <button key={t}
              onClick={e=>{e.stopPropagation(); onChangeType(t, m); setOpen(false);}}
              style={{
                all:'unset', display:'flex', alignItems:'flex-start', gap:8,
                width:'100%', padding:'9px 14px', cursor:'pointer', fontSize:12,
                background: t===act.type ? '#f0f9ff' : 'transparent',
                color: t===act.type ? '#0369a1' : '#1e293b',
                fontWeight: t===act.type ? 700 : 400,
                borderBottom:'1px solid #f8fafc',
                boxSizing:'border-box',
              }}
              onMouseEnter={e=>e.currentTarget.style.background='#f8fafc'}
              onMouseLeave={e=>e.currentTarget.style.background=t===act.type?'#f0f9ff':'transparent'}>
              <span style={{flexShrink:0,marginTop:1}}>{m.icon}</span>
              <div style={{flex:1,minWidth:0}}>
                <div style={{fontWeight:600}}>{m.verb}</div>
                <div style={{fontSize:10,color:'#94a3b8',fontWeight:400,marginTop:1,lineHeight:1.3}}>{m.desc}</div>
              </div>
              {t===act.type && <span style={{flexShrink:0,fontSize:11,color:'#0369a1',marginTop:1}}>✓</span>}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// ── Review Queue ──────────────────────────────────────────────────────────────
function ReviewQueueView({ queue, onRefresh, pushToast }) {
  const [confirming, setConfirming] = useState(null);
  const [overriding, setOverriding] = useState(null);
  const [overrideCat, setOverrideCat] = useState('');
  const [busy, setBusy] = useState(null);
  const [bodyItem, setBodyItem] = useState(null); // full email body modal
  const [localActions, setLocalActions] = useState({}); // itemId → actions[]

  const getActions = (item) => localActions[item.id] ?? item.actions ?? [];
  const setActions = (item, acts) => setLocalActions(prev => ({ ...prev, [item.id]: acts }));

  const handleSaveActions = async (item) => {
    try {
      await api.post('/api/review/update-actions', { id: item.id, actions: getActions(item) });
    } catch(e) { /* non-critical */ }
  };

  // Action type definitions — fixed verb, editable parameter only
  const ACTION_META = {
    flag:    { icon: '🚨', verb: 'Alert',          desc: 'Flag for attention or add a note for the reviewer', paramLabel: 'Note',          placeholder: 'e.g. Escalate to management' },
    file:    { icon: '📁', verb: 'Save to',         desc: 'Save / file this email into an Outlook folder',     paramLabel: 'Folder',        placeholder: 'e.g. Invoices/Boral/2026', isFolder: true },
    forward: { icon: '➡️', verb: 'Forward to',      desc: 'Forward this email to a team member',               paramLabel: 'Email address', placeholder: 'e.g. alison@eliteroads.com.au' },
    pay:     { icon: '💰', verb: 'Arrange payment', desc: 'Log in Urgent Payments and schedule payment',       paramLabel: 'Amount / ref',  placeholder: 'e.g. $5,839.00 — INV-95340' },
    reply:   { icon: '✉️', verb: 'Reply',            desc: 'Send a reply to the sender',                        paramLabel: 'Reply note',    placeholder: 'e.g. Acknowledge receipt' },
    folder:  { icon: '📂', verb: 'Move to folder',  desc: 'Move email to a specific Outlook folder',           paramLabel: 'Folder path',   placeholder: 'e.g. HR/Superannuation', isFolder: true },
    alert:   { icon: '🔔', verb: 'Notify',           desc: 'Send a Telegram alert to management',               paramLabel: 'Who / what',    placeholder: 'e.g. Notify Deon — overdue' },
  };
  const ACTION_TYPES = Object.entries(ACTION_META).map(([type, m]) => ({ type, ...m }));

  // Known Outlook folders for the Save to / Move to folder picker
  const KNOWN_FOLDERS = [
    'Invoices', 'Invoices/Boral', 'Invoices/Fulton Hogan', 'Invoices/Hanson',
    'Invoices/Coates Hire', 'Invoices/Aspect Personnel', 'Invoices/VicRoads',
    'Statements', 'Dockets', 'Urgent', 'Queries',
    'Fleet', 'Fleet/Registrations', 'Fleet/Fuel', 'Fleet/Repairs',
    'Tenders', 'HR', 'HR/Superannuation', 'HR/Payroll', 'Noise',
    'Suppliers/Aspect Personnel/Queries', 'Suppliers/Boral',
  ];

  const ALL_CATS = [
    'invoice','statement','docket','urgent-payment','supplier-query',
    'route-fleet','route-estimator','route-hr','route-other','noise',
  ];

  const handleApprove = async (item) => {
    setBusy(item.id);
    try {
      // Save latest local actions before approving
      const acts = getActions(item);
      if (acts.length > 0) {
        await api.post('/api/review/update-actions', { id: item.id, actions: acts }).catch(()=>{});
      }
      await api.post('/api/review/approve', { id: item.id });

      // Build toast summary of what was actioned
      const folderAct = acts.find(a => a.type === 'file' || a.type === 'folder');
      const fwdActs   = acts.filter(a => a.type === 'forward' && a.target);
      const payAct    = acts.find(a => a.type === 'pay');
      const parts = ['✅ Approved'];
      if (folderAct?.target) parts.push(`📁 Filed to ${folderAct.target}`);
      if (fwdActs.length)    parts.push(`➡️ Forwarded to ${fwdActs.map(a=>a.target).join(', ')}`);
      if (payAct)            parts.push('💰 Payment logged');
      pushToast(parts.join(' · '));
      onRefresh();
    } catch(e) { pushToast('Error: ' + e.message); }
    setBusy(null);
  };

  const handleDismiss = async (item) => {
    setBusy(item.id);
    try {
      await api.post('/api/review/dismiss', { id: item.id });
      pushToast('Dismissed');
      onRefresh();
    } catch(e) { pushToast('Error: ' + e.message); }
    setBusy(null);
    setConfirming(null);
  };

  const handleOverride = async (item) => {
    if (!overrideCat) return;
    setBusy(item.id);
    try {
      await api.post('/api/review/override', { id: item.id, category: overrideCat });
      pushToast('Category overridden → ' + fmtCatLabel(overrideCat));
      onRefresh();
    } catch(e) { pushToast('Error: ' + e.message); }
    setBusy(null);
    setOverriding(null);
  };

  const handleAddCategory = async (item) => {
    const name = item.suggestedCategoryName || '';
    if (!name) return;
    try {
      await api.post('/api/category/add', {
        key: name.toLowerCase().replace(/\s+/g, '-'),
        displayName: name,
        forwardTo: [],
        autoForward: false,
      });
      pushToast('✅ Category added: ' + name);
      onRefresh();
    } catch(e) { pushToast('Error: ' + e.message); }
  };

  if (!queue?.length) {
    return (
      <div className="main-inner">
        <div className="page-head"><div><h1 className="page-title">Review Queue</h1><p className="page-sub">Items requiring Mindy's attention</p></div></div>
        <div className="empty-state">
          <div style={{fontSize:48,marginBottom:12}}>✅</div>
          <div style={{fontSize:16,fontWeight:600,color:'var(--navy)',marginBottom:4}}>Queue is clear</div>
          <div style={{fontSize:13,color:'#6b7280'}}>All emails processed with high confidence</div>
        </div>
      </div>
    );
  }

  return (
    <div className="main-inner">
      <div className="page-head">
        <div>
          <h1 className="page-title">Review Queue</h1>
          <p className="page-sub">{queue.length} item{queue.length!==1?'s':''} needing your attention</p>
        </div>
      </div>

      {queue.map(item => {
        const cs = catStyle(item.category);
        const isRouting = item.category?.startsWith('route-');
        return (
          <div key={item.id} className="queue-card">
            {/* AI suggests new category */}
            {item.aiSuggestNewCategory && (
              <div className="ai-suggest-banner">
                <Icons.sparkle style={{width:14,height:14,flexShrink:0}}/>
                <span>AI suggests new category: <strong>{item.suggestedCategoryName}</strong></span>
                <button className="btn-sm btn-teal" onClick={() => handleAddCategory(item)}>
                  Add Category
                </button>
              </div>
            )}

            <div className="card-head">
              <Badge cat={item.category}>{fmtCatLabel(item.category)}</Badge>
              <ConfPill value={item.confidence} />
              {item.hasAttachments && (
                <span className="attach-badge"><Icons.clip style={{width:11,height:11}}/> Attachment</span>
              )}
              <span className="card-date">{fmtDate(item.emailDate || item.date)}</span>
            </div>

            <div className="card-subject" style={{cursor:'pointer',textDecoration:'underline dotted',textUnderlineOffset:3}} onClick={()=>setBodyItem(item)} title="Click to view full email">{item.subject}</div>
            <div className="card-from">From: {item.from} &lt;{item.fromEmail}&gt;</div>

            {/* Email body / snippet */}
            {item.snippet && (
              <div className="card-snippet">{item.snippet}</div>
            )}

            {/* Classification reason (why this confidence) */}
            {item.classificationReason && (
              <div style={{fontSize:12,color:'#4b5563',background:'#f0f9ff',border:'1px solid #bae6fd',borderRadius:6,padding:'6px 10px',marginBottom:8,fontStyle:'italic'}}>
                🧠 {item.classificationReason}
              </div>
            )}

            {/* Open in Outlook link */}
            {item.webLink && (
              <div style={{marginBottom:8}}>
                <a href={item.webLink} target="_blank" rel="noreferrer"
                  style={{fontSize:12,color:'#1d4ed8',fontWeight:600,textDecoration:'none'}}>
                  📧 Open in Outlook ↗
                </a>
              </div>
            )}

            <div className="card-meta">
              {item.supplierName && <span><strong>Supplier:</strong> {item.supplierName}</span>}
              {item.invoiceRef   && <span><strong>Ref:</strong> {item.invoiceRef}</span>}
              {item.invoiceAmount != null && <span><strong>Amount:</strong> {fmtAmt(item.invoiceAmount)}</span>}
              {item.suggestedFolder && <span><Icons.folder style={{width:11,height:11,marginRight:3}}/>{item.suggestedFolder}</span>}
            </div>

            {/* ⚠️ Duplicate banner */}
            {item.isDuplicate && (
              <div style={{background:'#fef2f2',border:'1px solid #fca5a5',borderRadius:6,padding:'8px 12px',marginBottom:8,fontSize:12,color:'#991b1b',display:'flex',alignItems:'flex-start',gap:6}}>
                <span style={{fontSize:14,flexShrink:0}}>⚠️</span>
                <div><strong>Possible duplicate</strong> — {item.duplicateReason || 'Similar invoice already processed'}</div>
              </div>
            )}

            {/* Multi-action checklist */}
            {(() => {
              const acts = getActions(item);
              const updateAct = (i, patch) => {
                const next = acts.map((a, idx) => idx === i ? {...a, ...patch} : a);
                setActions(item, next);
                api.post('/api/review/update-actions', { id: item.id, actions: next }).catch(()=>{});
              };
              const deleteAct = (i) => {
                const next = acts.filter((_, idx) => idx !== i);
                setActions(item, next);
                api.post('/api/review/update-actions', { id: item.id, actions: next }).catch(()=>{});
              };
              const addAct = () => {
                const next = [...acts, { type: 'flag', label: 'New action', target: '', done: false }];
                setActions(item, next);
              };
              return (
                <div style={{marginBottom:8}}>
                  <div style={{fontSize:11,fontWeight:700,textTransform:'uppercase',letterSpacing:'0.06em',color:'#6b7280',marginBottom:6}}>Actions</div>
                  {acts.length === 0 && <div style={{fontSize:12,color:'#9ca3af',fontStyle:'italic',marginBottom:6}}>No actions — add one below</div>}
                  {acts.map((act, i) => {
                    const meta = ACTION_META[act.type] || ACTION_META.flag;
                    const isDone = !!act.done;
                    // For flag/alert types, the "param" is the note text (act.label)
                    // For forward/file/pay/folder, the param is act.target
                    const isFlagType = act.type === 'flag' || act.type === 'alert' || act.type === 'reply';
                    const paramVal  = isFlagType ? act.label : (act.target || '');
                    const setParam  = (val) => isFlagType
                      ? updateAct(i, { label: val })
                      : updateAct(i, { target: val, label: `${meta.verb} ${val}` });
                    return (
                      <div key={i} style={{
                        display:'flex', alignItems:'center', gap:0, marginBottom:6,
                        borderRadius:7, border:`1px solid ${isDone?'#bbf7d0':'#e2e8f0'}`,
                        background: isDone ? '#f0fdf4' : '#fff', overflow:'hidden',
                      }}>
                        {/* Checkbox */}
                        <div style={{padding:'8px 10px',borderRight:`1px solid ${isDone?'#bbf7d0':'#e2e8f0'}`,background:isDone?'#dcfce7':'#f8fafc',display:'flex',alignItems:'center'}}>
                          <input type="checkbox" checked={isDone} onChange={e=>updateAct(i,{done:e.target.checked})}
                            style={{cursor:'pointer',width:14,height:14,accentColor:'#16a34a'}}/>
                        </div>
                        {/* Verb chip — proper component so useState works correctly */}
                        <VerbChip
                          act={act} idx={i} isDone={isDone}
                          actionMeta={ACTION_META}
                          onChangeType={(t, m) => updateAct(i, {
                            type: t,
                            label: act.target ? `${m.verb} ${act.target}` : m.verb,
                          })}
                        />
                        {/* Editable parameter — folder types get a datalist picker */}
                        {meta.isFolder ? (
                          <div style={{flex:1,position:'relative',minWidth:0}}>
                            <input
                              list={`folders-${i}`}
                              value={paramVal}
                              onChange={e => setParam(e.target.value)}
                              placeholder={meta.placeholder}
                              style={{
                                width:'100%', border:'none', background:'transparent', padding:'8px 10px',
                                fontSize:12, color: isDone?'#16a34a':'#1e293b',
                                textDecoration: isDone?'line-through':'none',
                                outline:'none', boxSizing:'border-box',
                              }}
                            />
                            <datalist id={`folders-${i}`}>
                              {KNOWN_FOLDERS.map(f => <option key={f} value={f}/>)}
                            </datalist>
                          </div>
                        ) : (
                          <input
                            value={paramVal}
                            onChange={e => setParam(e.target.value)}
                            placeholder={meta.placeholder}
                            style={{
                              flex:1, border:'none', background:'transparent', padding:'8px 10px',
                              fontSize:12, color: isDone?'#16a34a':'#1e293b',
                              textDecoration: isDone?'line-through':'none',
                              outline:'none', minWidth:0,
                            }}
                          />
                        )}
                        {/* Delete */}
                        <button onClick={()=>deleteAct(i)}
                          style={{all:'unset',cursor:'pointer',padding:'8px 10px',color:'#cbd5e1',fontSize:16,lineHeight:1,flexShrink:0}}
                          onMouseEnter={e=>e.currentTarget.style.color='#ef4444'}
                          onMouseLeave={e=>e.currentTarget.style.color='#cbd5e1'}>×</button>
                      </div>
                    );
                  })}
                  <div style={{display:'flex',gap:6,marginTop:6,flexWrap:'wrap',alignItems:'center'}}>
                    <span style={{fontSize:10,color:'#94a3b8',fontWeight:600,letterSpacing:'0.05em',marginRight:2}}>ADD:</span>
                    {Object.entries(ACTION_META).filter(([type]) => !acts.some(a => a.type === type)).map(([type, m]) => (
                      <button key={type} onClick={() => {
                        const next = [...acts, { type, label: m.verb, target: '', done: false }];
                        setActions(item, next);
                        api.post('/api/review/update-actions', { id: item.id, actions: next }).catch(()=>{});
                      }}
                      title={m.desc}
                      style={{
                        all:'unset',cursor:'pointer',fontSize:11,padding:'3px 9px',borderRadius:10,
                        border:'1px dashed #cbd5e1',color:'#64748b',background:'#f8fafc',
                        display:'inline-flex',alignItems:'center',gap:4,
                      }}
                        onMouseEnter={e=>{e.currentTarget.style.background='#e2e8f0';e.currentTarget.style.color='#1e293b';}}
                        onMouseLeave={e=>{e.currentTarget.style.background='#f8fafc';e.currentTarget.style.color='#64748b';}}>
                        {m.icon} + {m.verb}
                      </button>
                    ))}
                    {Object.entries(ACTION_META).every(([type]) => acts.some(a => a.type === type)) && (
                      <span style={{fontSize:11,color:'#94a3b8',fontStyle:'italic'}}>All actions added</span>
                    )}
                  </div>
                </div>
              );
            })()}

            <div className="card-actions">
              <button className="btn-approve" onClick={() => handleApprove(item)} disabled={busy===item.id}>
                {busy===item.id ? <Icons.spin style={{width:14,height:14}}/> : <Icons.check style={{width:14,height:14}}/>}
                Approve
              </button>
              <button className="btn-override" onClick={() => { setOverriding(item); setOverrideCat(item.category); }}>
                <Icons.edit style={{width:13,height:13}}/> Override
              </button>
              <button className="btn-dismiss" onClick={() => setConfirming(item)}>
                <Icons.trash style={{width:13,height:13}}/> Dismiss
              </button>
              <button style={{all:'unset',cursor:'pointer',fontSize:12,color:'#6b7280',padding:'4px 10px',borderRadius:5,border:'1px solid #e5e7eb',background:'#f9fafb'}}
                onClick={() => setBodyItem(item)}>
                📄 View email
              </button>
            </div>
          </div>
        );
      })}

      {/* Full email body modal */}
      {bodyItem && (
        <Modal title={bodyItem.subject} wide onClose={() => setBodyItem(null)}>
          <div style={{padding:'0 24px 24px'}}>
            <div style={{fontSize:12,color:'#6b7280',marginBottom:12,paddingTop:12,borderTop:'1px solid #f3f4f6'}}>
              <strong>From:</strong> {bodyItem.fromName || bodyItem.from} &lt;{bodyItem.fromEmail}&gt;
              &nbsp;·&nbsp; <strong>Date:</strong> {fmtDate(bodyItem.emailDate || bodyItem.date)}
              {bodyItem.hasAttachments && <span style={{marginLeft:8,background:'#f3f4f6',borderRadius:4,padding:'1px 7px',fontSize:11}}>📎 Attachment</span>}
            </div>
            {bodyItem.webLink && (
              <div style={{marginBottom:12}}>
                <a href={bodyItem.webLink} target="_blank" rel="noreferrer"
                  style={{fontSize:12,color:'#1d4ed8',fontWeight:600,textDecoration:'none'}}>
                  📧 Open in Outlook ↗
                </a>
              </div>
            )}
            {bodyItem.classificationReason && (
              <div style={{fontSize:12,color:'#4b5563',background:'#f0f9ff',border:'1px solid #bae6fd',borderRadius:6,padding:'8px 12px',marginBottom:12,fontStyle:'italic'}}>
                🧠 {bodyItem.classificationReason}
              </div>
            )}
            <div style={{background:'#f9fafb',border:'1px solid #e5e7eb',borderRadius:8,padding:'14px 16px',
              fontSize:13,lineHeight:1.65,whiteSpace:'pre-wrap',fontFamily:'inherit',maxHeight:420,overflowY:'auto',color:'#1f2937'}}>
              {(() => { try { return JSON.parse(bodyItem.raw)?.email?.body || bodyItem.snippet || '(no body available)'; } catch { return bodyItem.snippet || '(no body available)'; } })()}
            </div>
            {bodyItem.invoiceAmount != null && (
              <div style={{marginTop:12,display:'flex',gap:16,flexWrap:'wrap'}}>
                {bodyItem.supplierName && <span style={{fontSize:12}}><strong>Supplier:</strong> {bodyItem.supplierName}</span>}
                {bodyItem.invoiceRef && <span style={{fontSize:12}}><strong>Ref:</strong> {bodyItem.invoiceRef}</span>}
                <span style={{fontSize:12}}><strong>Amount:</strong> {fmtAmt(bodyItem.invoiceAmount)}</span>
              </div>
            )}
            <div style={{marginTop:16,display:'flex',gap:8,justifyContent:'flex-end'}}>
              <button className="btn-approve" onClick={()=>{handleApprove(bodyItem);setBodyItem(null);}} disabled={busy===bodyItem.id}>
                <Icons.check style={{width:14,height:14}}/> Approve
              </button>
              <button className="btn-ghost" onClick={()=>setBodyItem(null)}>Close</button>
            </div>
          </div>
        </Modal>
      )}

      {/* Override modal */}
      {overriding && (
        <Modal title="Override Category" onClose={() => setOverriding(null)}>
          <div style={{padding:'16px 24px'}}>
            <p style={{margin:'0 0 12px',fontSize:13,color:'#374151'}}>
              Change category for: <strong>{overriding.subject}</strong>
            </p>
            <select value={overrideCat} onChange={e=>setOverrideCat(e.target.value)}
              style={{width:'100%',padding:'8px 10px',borderRadius:6,border:'1px solid #d1d5db',fontSize:13,marginBottom:16}}>
              {['invoice','statement','docket','urgent-payment','supplier-query',
                'route-fleet','route-estimator','route-hr','route-other','noise'].map(c => (
                <option key={c} value={c}>{fmtCatLabel(c)}</option>
              ))}
            </select>
            <div style={{display:'flex',gap:8,justifyContent:'flex-end'}}>
              <button onClick={()=>setOverriding(null)} className="btn-ghost">Cancel</button>
              <button onClick={()=>handleOverride(overriding)} className="btn-primary">Apply Override</button>
            </div>
          </div>
        </Modal>
      )}

      {confirming && (
        <ConfirmDialog
          title="Dismiss this item?"
          body="It will be removed from the queue and marked as dismissed."
          confirmLabel="Yes, dismiss"
          danger
          onCancel={() => setConfirming(null)}
          onConfirm={() => handleDismiss(confirming)}
        />
      )}
    </div>
  );
}

// ── Processed View ────────────────────────────────────────────────────────────
function ProcessedView({ processed, onRefresh, pushToast }) {
  const [activeTab,     setActiveTab]     = useState('all');
  const [search,        setSearch]        = useState('');
  const [catFilter,     setCatFilter]     = useState('all');
  const [fromDate,      setFromDate]      = useState('');
  const [toDate,        setToDate]        = useState('');
  // Action date filter — for Daily Log tab (filters by when actioned, not email date)
  const [actionFrom,    setActionFrom]    = useState('');
  const [actionTo,      setActionTo]      = useState('');
  const [expandedId, setExpandedId] = useState(null);
  const [editFields, setEditFields] = useState({});
  const [saving,     setSaving]     = useState(null);

  const ALL_CATS = ['invoice','statement','docket','urgent-payment','supplier-query',
    'route-fleet','route-estimator','route-hr','route-other','noise'];

  const PROC_META = {
    flag:      { icon:'🚨', label:'Alert' },
    file:      { icon:'📁', label:'Saved to' },
    forward:   { icon:'➡️', label:'Forwarded to' },
    pay:       { icon:'💰', label:'Payment arranged' },
    reply:     { icon:'✉️', label:'Replied' },
    folder:    { icon:'📂', label:'Moved to' },
    alert:     { icon:'🔔', label:'Notified' },
    processed: { icon:'⚡', label:'Auto-processed' },
  };
  const IRREV = ['forward','reply','alert'];

  const parseActs = (p) => {
    try { return typeof p.actions==='string' ? JSON.parse(p.actions) : (p.actions||[]); }
    catch { return []; }
  };

  // Base filter (applies to All, Auto, Manual tabs)
  const baseFiltered = (processed || []).filter(p => {
    const q = search.toLowerCase();
    const matchSearch = !q || p.subject?.toLowerCase().includes(q) ||
      p.supplier?.toLowerCase().includes(q) || (p.fromName||p.fromEmail||'').toLowerCase().includes(q);
    const matchCat = catFilter === 'all' || p.category === catFilter;
    if (fromDate) { const d = p.emailDate||p.processedAt ? new Date(p.emailDate||p.processedAt) : null; if (!d || d < new Date(fromDate)) return false; }
    if (toDate)   { const d = p.emailDate||p.processedAt ? new Date(p.emailDate||p.processedAt) : null; if (!d || d > new Date(toDate + 'T23:59:59')) return false; }
    return matchSearch && matchCat;
  });

  const allItems      = baseFiltered;
  const botItems      = baseFiltered.filter(p => !p.approvedManually);
  const manualItems   = baseFiltered.filter(p =>  p.approvedManually);
  const cats          = ['all', ...new Set((processed||[]).map(p=>p.category).filter(Boolean))];

  // Daily log entries — use ALL processed items (not baseFiltered) so email date filter
  // doesn't hide items actioned today that have an old email date.
  // Instead, filter by actionFrom/actionTo (when actioned).
  const logEntries = useMemo(() => {
    const entries = [];
    (processed || []).forEach(p => {
      // Also apply search + category filter from main filters
      const q = search.toLowerCase();
      const matchSearch = !q || p.subject?.toLowerCase().includes(q) ||
        p.supplier?.toLowerCase().includes(q) || (p.fromName||p.fromEmail||'').toLowerCase().includes(q);
      const matchCat = catFilter === 'all' || p.category === catFilter;
      if (!matchSearch || !matchCat) return;

      const acts = parseActs(p);
      acts.filter(a => a.done && a.doneAt).forEach(a => {
        const d = new Date(a.doneAt);
        if (actionFrom && d < new Date(actionFrom)) return;
        if (actionTo   && d > new Date(actionTo + 'T23:59:59')) return;
        entries.push({ doneAt:a.doneAt, subject:p.subject, supplier:p.supplier||p.fromName||'—',
          type:a.type, target:a.target||a.label||'—', category:p.category, amount:p.invoiceAmount,
          manual:!!p.approvedManually, emailDate:p.emailDate });
      });
      if (p.processedAt) {
        const d = new Date(p.processedAt);
        if (actionFrom && d < new Date(actionFrom)) return;
        if (actionTo   && d > new Date(actionTo + 'T23:59:59')) return;
        entries.push({ doneAt:p.processedAt, subject:p.subject, supplier:p.supplier||p.fromName||'—',
          type:'processed', target: fmtCatLabel(p.category)+(p.suggestedFolder?` → ${p.suggestedFolder}`:''),
          category:p.category, amount:p.invoiceAmount, manual:!!p.approvedManually, emailDate:p.emailDate });
      }
    });
    return entries.sort((a,b) => new Date(b.doneAt)-new Date(a.doneAt));
  }, [processed, search, catFilter, actionFrom, actionTo]);

  const logByDate = useMemo(() => {
    const g = {};
    logEntries.forEach(e => {
      const day = new Date(e.doneAt).toLocaleDateString('en-AU',{weekday:'long',day:'numeric',month:'long',year:'numeric'});
      if (!g[day]) g[day] = [];
      g[day].push(e);
    });
    return g;
  }, [logEntries]);

  const TABS = [
    { key:'all',    label:'All Processed',  count: allItems.length    },
    { key:'auto',   label:'🤖 Auto',         count: botItems.length    },
    { key:'manual', label:'👤 Manual',       count: manualItems.length },
    { key:'log',    label:'📋 Daily Log',    count: logEntries.length  },
  ];

  const toggleExpand = (id) => {
    if (expandedId === id) { setExpandedId(null); return; }
    setExpandedId(id);
    const item = (processed||[]).find(p => p.id === id);
    if (item) setEditFields(f => ({ ...f, [id]: {
      category: item.category, action: item.action,
      suggestedFolder: item.suggestedFolder, forwardTo: item.forwardTo,
      actions: parseActs(item),
    }}));
  };

  const handleSave = async (item) => {
    setSaving(item.id);
    try {
      await api.post('/api/processed/update', { id: item.id, ...editFields[item.id] });
      pushToast('✅ Updated');
      onRefresh();
      setExpandedId(null);
    } catch(e) { pushToast('Error: ' + e.message); }
    setSaving(null);
  };

  const handleRequeue = async (item) => {
    setSaving(item.id);
    try {
      await api.post('/api/processed/requeue', { id: item.id });
      pushToast('↩ Moved back to Review Queue');
      onRefresh();
      setExpandedId(null);
    } catch(e) { pushToast('Error: ' + e.message); }
    setSaving(null);
  };

  const exportCSV = (items) => {
    const rows = [
      ['Date','Supplier','Subject','Category','Confidence','Reason','Folder','Amount','Method'],
      ...items.map(p => [
        p.emailDate ? new Date(p.emailDate).toLocaleString('en-AU') : p.processedAt?.slice(0,10)||'—',
        p.supplier||'', p.subject||'', p.category||'',
        p.confidence!=null?p.confidence+'%':'—',
        (p.classificationReason||'').replace(/,/g,';'),
        p.suggestedFolder||'', p.invoiceAmount!=null?p.invoiceAmount:'',
        p.approvedManually?'Manual':'Bot',
      ])
    ];
    const csv = rows.map(r=>r.map(c=>`"${String(c).replace(/"/g,'""')}"`).join(',')).join('\n');
    const blob = new Blob([csv],{type:'text/csv'});
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a'); a.href=url;
    a.download=`accounts-processed-${new Date().toISOString().slice(0,10)}.csv`;
    a.click(); URL.revokeObjectURL(url);
  };

  const renderItem = (p) => {
    const isExpanded = expandedId === p.id;
    const ef = editFields[p.id] || {};
    return (
      <div key={p.id} style={{border:`1px solid ${p.isDuplicate?'#fca5a5':'#e5e7eb'}`,borderRadius:8,marginBottom:6,overflow:'hidden'}}>
        <div onClick={() => toggleExpand(p.id)} style={{
          display:'grid', gridTemplateColumns:'1fr auto auto auto auto',
          gap:8, alignItems:'center', padding:'10px 14px',
          background: isExpanded?'#f0f9ff': p.isDuplicate?'#fff5f5':'#fff',
          cursor:'pointer',
        }}>
          <div style={{minWidth:0}}>
            <div style={{fontWeight:600,fontSize:13,color:'var(--navy)',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
              {p.isDuplicate && <span style={{fontSize:11,marginRight:5}}>⚠️</span>}
              {p.subject}
            </div>
            <div style={{fontSize:11,color:'#6b7280',marginTop:1}}>{p.supplier||p.fromName||'—'} · {fmtDate(p.emailDate||p.processedAt)}</div>
          </div>
          <Badge cat={p.category}>{fmtCatLabel(p.category)}</Badge>
          <ConfPill value={p.confidence}/>
          <span style={{fontSize:11,color:'#6b7280',whiteSpace:'nowrap'}}>{fmtAmt(p.invoiceAmount)}</span>
          <span style={{fontSize:11,color:'#9ca3af'}}>{isExpanded?'▲':'▼'}</span>
        </div>

        {isExpanded && (
          <div style={{padding:'14px 16px',borderTop:'1px solid #e5e7eb',background:'#f9fafb'}}>
            {p.isDuplicate && (
              <div style={{background:'#fef2f2',border:'1px solid #fca5a5',borderRadius:6,padding:'6px 10px',marginBottom:12,fontSize:12,color:'#991b1b'}}>
                ⚠️ <strong>Duplicate:</strong> {p.duplicateReason}
              </div>
            )}
            {/* Actions checklist */}
            {(() => {
              const acts = ef.actions !== undefined ? ef.actions : parseActs(p);
              if (!acts || acts.length === 0) return null;
              const setActs = (next) => setEditFields(f=>({...f,[p.id]:{...(f[p.id]||{}),actions:next}}));
              return (
                <div style={{marginBottom:14}}>
                  <div style={{fontSize:11,fontWeight:700,textTransform:'uppercase',letterSpacing:'0.06em',color:'#6b7280',marginBottom:8}}>Actions</div>
                  {acts.map((act,i) => {
                    const m = PROC_META[act.type]||PROC_META.flag;
                    const irrev = IRREV.includes(act.type);
                    const isDone = !!act.done;
                    return (
                      <div key={i} style={{display:'flex',alignItems:'center',gap:0,marginBottom:5,borderRadius:7,
                        border:`1px solid ${isDone?'#bbf7d0':'#e2e8f0'}`,background:isDone?'#f0fdf4':'#fff',overflow:'hidden'}}>
                        <div style={{padding:'7px 10px',borderRight:`1px solid ${isDone?'#bbf7d0':'#e2e8f0'}`,background:isDone?'#dcfce7':'#f8fafc',display:'flex',alignItems:'center'}}>
                          <input type="checkbox" checked={isDone}
                            onChange={e=>{
                              const next=acts.map((a,idx)=>idx===i?{...a,done:e.target.checked,doneAt:e.target.checked?new Date().toISOString():null}:a);
                              setActs(next);
                            }} style={{cursor:'pointer',width:14,height:14,accentColor:'#16a34a'}}/>
                        </div>
                        <div style={{padding:'7px 10px',borderRight:`1px solid ${isDone?'#bbf7d0':'#e2e8f0'}`,background:isDone?'#f0fdf4':'#f1f5f9',
                          fontSize:12,fontWeight:600,color:isDone?'#15803d':'#334155',whiteSpace:'nowrap',display:'flex',alignItems:'center',gap:5,flexShrink:0}}>
                          {m.icon} {m.label}
                        </div>
                        <div style={{flex:1,padding:'7px 10px',fontSize:12,color:isDone?'#16a34a':'#374151',textDecoration:isDone?'line-through':'none',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>
                          {act.target||act.label||'—'}
                        </div>
                        {irrev && <span title="Cannot be undone" style={{fontSize:10,color:'#f59e0b',padding:'0 8px',flexShrink:0,cursor:'help'}}>⚠ irreversible</span>}
                        {act.doneAt && <span style={{fontSize:10,color:'#94a3b8',padding:'0 8px',flexShrink:0,whiteSpace:'nowrap'}}>✓ {new Date(act.doneAt).toLocaleTimeString('en-AU',{hour:'2-digit',minute:'2-digit'})}</span>}
                      </div>
                    );
                  })}
                </div>
              );
            })()}
            <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:10,marginBottom:10}}>
              <div>
                <label style={{fontSize:11,fontWeight:600,color:'#6b7280',display:'block',marginBottom:3}}>CATEGORY</label>
                <select value={ef.category||''} onChange={e=>setEditFields(f=>({...f,[p.id]:{...(f[p.id]||{}),category:e.target.value}}))}
                  style={{width:'100%',fontSize:12,padding:'5px 8px',borderRadius:6,border:'1px solid #d1d5db'}}>
                  {ALL_CATS.map(c=><option key={c} value={c}>{fmtCatLabel(c)}</option>)}
                </select>
              </div>
              <div>
                <label style={{fontSize:11,fontWeight:600,color:'#6b7280',display:'block',marginBottom:3}}>FOLDER</label>
                <input list="proc-folders" value={ef.suggestedFolder||''} onChange={e=>setEditFields(f=>({...f,[p.id]:{...(f[p.id]||{}),suggestedFolder:e.target.value}}))}
                  style={{width:'100%',fontSize:12,padding:'5px 8px',borderRadius:6,border:'1px solid #d1d5db',boxSizing:'border-box'}}/>
                <datalist id="proc-folders">
                  {['Invoices','Invoices/Boral','Invoices/Hanson','Invoices/Fulton Hogan','Invoices/Coates Hire','Statements','Dockets','Urgent','Fleet','Tenders','HR','HR/Superannuation','Queries','Noise'].map(f=><option key={f} value={f}/>)}
                </datalist>
              </div>
            </div>
            <div style={{marginBottom:10}}>
              <label style={{fontSize:11,fontWeight:600,color:'#6b7280',display:'block',marginBottom:3}}>ACTION / NOTES</label>
              <textarea value={ef.action||''} onChange={e=>setEditFields(f=>({...f,[p.id]:{...(f[p.id]||{}),action:e.target.value}}))}
                rows={2} style={{width:'100%',fontSize:12,padding:'5px 8px',borderRadius:6,border:'1px solid #d1d5db',resize:'vertical',boxSizing:'border-box'}}/>
            </div>
            {p.webLink && <div style={{marginBottom:10}}><a href={p.webLink} target="_blank" rel="noreferrer" style={{fontSize:12,color:'#1d4ed8',fontWeight:600,textDecoration:'none'}}>📧 Open in Outlook ↗</a></div>}
            <div style={{display:'flex',gap:8,flexWrap:'wrap'}}>
              <button className="btn-approve" onClick={()=>handleSave(p)} disabled={saving===p.id}>
                <Icons.check style={{width:13,height:13}}/> {saving===p.id?'Saving…':'Save changes'}
              </button>
              <button className="btn-override" onClick={()=>handleRequeue(p)} disabled={saving===p.id}>↩ Move back to Queue</button>
              <button className="btn-ghost" onClick={()=>setExpandedId(null)}>Cancel</button>
            </div>
          </div>
        )}
      </div>
    );
  };

  const renderLogTab = () => (
    <div>
      {/* Print-only header */}
      <div style={{display:'none'}} className="print-only">
        <h2 style={{margin:'0 0 4px',fontSize:14}}>Elite Roads Accounts — Daily Action Log</h2>
        <p style={{margin:'0 0 12px',fontSize:11,color:'#666'}}>Printed: {new Date().toLocaleString('en-AU')} · Mindy (Accountant)</p>
      </div>
      <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:16,flexWrap:'wrap',gap:8}} className="no-print">
        <div style={{fontSize:13,color:'#6b7280'}}>{logEntries.length} total actions · includes auto + manual</div>
        <button className="btn-ghost" onClick={()=>window.print()}>🖨 Print Daily Summary</button>
      </div>
      {Object.keys(logByDate).length === 0 ? (
        <div className="empty-state"><div style={{fontSize:13,color:'#6b7280'}}>No logged actions yet — tick off actions on processed items to see them here</div></div>
      ) : Object.entries(logByDate).map(([day, entries]) => (
        <div key={day} style={{marginBottom:24}}>
          <div style={{fontSize:12,fontWeight:700,color:'#6b7280',textTransform:'uppercase',letterSpacing:'0.06em',
            marginBottom:8,paddingBottom:4,borderBottom:'1px solid #e5e7eb',display:'flex',alignItems:'center',gap:8}}>
            {day} — {entries.length} action{entries.length!==1?'s':''}
            <span style={{fontWeight:400,fontSize:11,color:'#94a3b8'}}>
              {entries.filter(e=>!e.manual).length} auto · {entries.filter(e=>e.manual).length} manual
            </span>
          </div>
          <table style={{width:'100%',borderCollapse:'collapse',fontSize:12}}>
            <thead>
              <tr style={{background:'#f9fafb'}}>
                {['Action Time','Action','Email / Subject','Email Date','Supplier','Amount','✓'].map((h,i) => (
                  <th key={h} style={{padding:'6px 10px',textAlign:i===4?'right':i===5?'center':'left',
                    fontWeight:600,color:'#6b7280',fontSize:11,borderBottom:'1px solid #e5e7eb',whiteSpace:'nowrap'}}>{h}</th>
                ))}
              </tr>
            </thead>
            <tbody>
              {entries.map((e,i) => {
                const m = PROC_META[e.type]||PROC_META.processed;
                return (
                  <tr key={i} style={{borderBottom:'1px solid #f3f4f6',background:i%2===0?'#fff':'#fafafa'}}>
                    <td style={{padding:'7px 10px',fontFamily:'var(--mono)',fontSize:11,color:'#6b7280',whiteSpace:'nowrap'}}>
                      {new Date(e.doneAt).toLocaleTimeString('en-AU',{hour:'2-digit',minute:'2-digit'})}
                    </td>
                    <td style={{padding:'7px 10px'}}>
                      <span style={{display:'inline-flex',alignItems:'center',gap:4,fontSize:12}}>
                        <span>{m.icon}</span>
                        <span style={{fontWeight:600,color:'#334155'}}>{m.label}</span>
                        {e.target&&e.target!=='—'&&<span style={{color:'#6b7280',fontSize:11}}>→ {e.target}</span>}
                        <span style={{fontSize:9,padding:'1px 5px',borderRadius:4,marginLeft:2,
                          background:e.manual?'#fef9ee':'#eff6ff',
                          color:e.manual?'#92400e':'#1d4ed8',fontWeight:700}}>
                          {e.manual?'manual':'auto'}
                        </span>
                      </span>
                    </td>
                    <td style={{padding:'7px 10px',fontSize:12,color:'#1f2937',maxWidth:220,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{e.subject}</td>
                    <td style={{padding:'7px 10px',fontSize:12,color:'#374151',fontWeight:500,whiteSpace:'nowrap'}}>{e.supplier}</td>
                    <td style={{padding:'7px 10px',fontFamily:'var(--mono)',fontSize:11,color:'#94a3b8',whiteSpace:'nowrap'}}>{e.emailDate?fmtDate(e.emailDate):'—'}</td>
                    <td style={{padding:'7px 10px',fontFamily:'var(--mono)',fontSize:12,textAlign:'right',color:'#1f2937',whiteSpace:'nowrap'}}>{e.amount!=null?fmtAmt(e.amount):'—'}</td>
                    <td style={{padding:'7px 10px',textAlign:'center'}}>
                      <span style={{display:'inline-block',width:14,height:14,border:'1px solid #d1d5db',borderRadius:3}}/>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
          {/* Print signature */}
          <div style={{display:'none',marginTop:12,paddingTop:8,borderTop:'1px solid #e5e7eb'}} className="print-only">
            <p style={{fontSize:10,color:'#666',margin:0}}>Reviewed: _________________________ &nbsp; Sign: _________________________ &nbsp; Date: _______________</p>
          </div>
        </div>
      ))}
    </div>
  );

  const renderListTab = (items, emptyMsg) => (
    items.length === 0
      ? <div className="empty-state"><div style={{fontSize:13,color:'#6b7280'}}>{emptyMsg}</div></div>
      : items.map(renderItem)
  );

  return (
    <div className="main-inner">
      {/* Print header */}
      <div style={{display:'none'}} className="print-only">
        <h1 style={{margin:0}}>Elite Roads Accounts — Processed Email Report</h1>
        <p style={{margin:'4px 0 0',color:'#666'}}>Generated: {new Date().toLocaleString('en-AU')}</p>
      </div>

      {/* Page header */}
      <div className="page-head no-print">
        <div>
          <h1 className="page-title">Processed</h1>
          <p className="page-sub">{allItems.length} of {processed?.length||0} emails</p>
        </div>
        <div style={{display:'flex',gap:8}}>
          <button className="btn-ghost" onClick={()=>exportCSV(allItems)}>↧ Export CSV</button>
        </div>
      </div>

      {/* Filters — always visible */}
      <div className="no-print" style={{background:'#f9fafb',borderRadius:8,border:'1px solid #e5e7eb',marginBottom:0}}>
        {/* Row 1: Email date + search + category */}
        <div style={{display:'flex',gap:10,flexWrap:'wrap',padding:'10px 14px',borderBottom: activeTab==='log'?'1px solid #e5e7eb':'none'}}>
          <div style={{display:'flex',flexDirection:'column',gap:2}}>
            <label style={{fontSize:11,fontWeight:600,color:'#6b7280'}}>EMAIL DATE FROM</label>
            <input type="date" value={fromDate} onChange={e=>setFromDate(e.target.value)} style={{fontSize:12,padding:'4px 8px',borderRadius:6,border:'1px solid #d1d5db'}}/>
          </div>
          <div style={{display:'flex',flexDirection:'column',gap:2}}>
            <label style={{fontSize:11,fontWeight:600,color:'#6b7280'}}>TO</label>
            <input type="date" value={toDate} onChange={e=>setToDate(e.target.value)} style={{fontSize:12,padding:'4px 8px',borderRadius:6,border:'1px solid #d1d5db'}}/>
          </div>
          <div style={{display:'flex',flexDirection:'column',gap:2,flex:1,minWidth:150}}>
            <label style={{fontSize:11,fontWeight:600,color:'#6b7280'}}>SEARCH</label>
            <input className="search-input" placeholder="Supplier, subject…" value={search} onChange={e=>setSearch(e.target.value)} style={{margin:0}}/>
          </div>
          <div style={{display:'flex',flexDirection:'column',gap:2}}>
            <label style={{fontSize:11,fontWeight:600,color:'#6b7280'}}>CATEGORY</label>
            <select className="cat-select" value={catFilter} onChange={e=>setCatFilter(e.target.value)} style={{margin:0}}>
              {cats.map(c=><option key={c} value={c}>{c==='all'?'All categories':fmtCatLabel(c)}</option>)}
            </select>
          </div>
          {(fromDate||toDate||search||catFilter!=='all') && (
            <div style={{display:'flex',alignItems:'flex-end'}}>
              <button className="btn-ghost" style={{fontSize:12,padding:'4px 10px'}}
                onClick={()=>{setFromDate('');setToDate('');setSearch('');setCatFilter('all');}}>× Clear</button>
            </div>
          )}
        </div>
        {/* Row 2: Action date filter — only shown on Daily Log tab */}
        {activeTab === 'log' && (
          <div style={{display:'flex',gap:10,flexWrap:'wrap',padding:'8px 14px',alignItems:'center',background:'#f0f9ff'}}>
            <span style={{fontSize:11,fontWeight:700,color:'#0369a1',whiteSpace:'nowrap'}}>📋 ACTION DATE:</span>
            <div style={{display:'flex',flexDirection:'column',gap:2}}>
              <label style={{fontSize:10,fontWeight:600,color:'#6b7280'}}>FROM</label>
              <input type="date" value={actionFrom} onChange={e=>setActionFrom(e.target.value)} style={{fontSize:12,padding:'4px 8px',borderRadius:6,border:'1px solid #bae6fd',background:'#fff'}}/>
            </div>
            <div style={{display:'flex',flexDirection:'column',gap:2}}>
              <label style={{fontSize:10,fontWeight:600,color:'#6b7280'}}>TO</label>
              <input type="date" value={actionTo} onChange={e=>setActionTo(e.target.value)} style={{fontSize:12,padding:'4px 8px',borderRadius:6,border:'1px solid #bae6fd',background:'#fff'}}/>
            </div>
            <div style={{display:'flex',alignItems:'flex-end',gap:6}}>
              <button style={{all:'unset',cursor:'pointer',fontSize:11,padding:'4px 10px',borderRadius:6,border:'1px solid #bae6fd',background:'#fff',color:'#0369a1',fontWeight:600}}
                onClick={()=>{const t=new Date().toISOString().slice(0,10);setActionFrom(t);setActionTo(t);}}>Today</button>
              <button style={{all:'unset',cursor:'pointer',fontSize:11,padding:'4px 10px',borderRadius:6,border:'1px solid #bae6fd',background:'#fff',color:'#0369a1',fontWeight:600}}
                onClick={()=>{const t=new Date();const mon=new Date(t);mon.setDate(t.getDate()-t.getDay()+1);setActionFrom(mon.toISOString().slice(0,10));setActionTo(t.toISOString().slice(0,10));}}>This week</button>
              {(actionFrom||actionTo) && (
                <button className="btn-ghost" style={{fontSize:11,padding:'4px 8px'}} onClick={()=>{setActionFrom('');setActionTo('');}}>× Clear</button>
              )}
            </div>
            <span style={{fontSize:11,color:'#94a3b8',fontStyle:'italic'}}>Filters log by when actioned — not email date</span>
          </div>
        )}
      </div>

      {/* Summary counts */}
      <div style={{display:'flex',gap:10,margin:'12px 0',flexWrap:'wrap'}}>
        {[
          {label:'Total',        value:allItems.length,    color:'#1f2937'},
          {label:'🤖 Auto',      value:botItems.length,    color:'#1d4ed8'},
          {label:'👤 Manual',    value:manualItems.length, color:'#92400e'},
          {label:'⚠️ Duplicate', value:allItems.filter(p=>p.isDuplicate).length, color:'#dc2626'},
        ].map(s=>(
          <div key={s.label} style={{padding:'7px 14px',background:'#fff',border:'1px solid #e5e7eb',borderRadius:8,textAlign:'center',minWidth:90}}>
            <div style={{fontSize:18,fontWeight:700,color:s.color}}>{s.value}</div>
            <div style={{fontSize:11,color:'#6b7280',marginTop:1}}>{s.label}</div>
          </div>
        ))}
      </div>

      {/* Tabs */}
      <div className="no-print" style={{display:'flex',gap:0,borderBottom:'2px solid #e5e7eb',marginBottom:16}}>
        {TABS.map(t => (
          <button key={t.key} onClick={()=>setActiveTab(t.key)} style={{
            all:'unset', cursor:'pointer', padding:'9px 18px', fontSize:13, fontWeight:activeTab===t.key?700:400,
            color: activeTab===t.key?'#00263A':'#6b7280',
            borderBottom: activeTab===t.key?'2px solid #00263A':'2px solid transparent',
            marginBottom:-2, display:'flex', alignItems:'center', gap:6, whiteSpace:'nowrap',
          }}>
            {t.label}
            <span style={{fontSize:11,fontWeight:600,padding:'1px 6px',borderRadius:10,
              background:activeTab===t.key?'#00263A':'#e5e7eb',
              color:activeTab===t.key?'#fff':'#6b7280'}}>
              {t.count}
            </span>
          </button>
        ))}
      </div>

      {/* Tab content */}
      {activeTab === 'all'    && renderListTab(allItems,    'No processed emails — run a scan to populate')}
      {activeTab === 'auto'   && renderListTab(botItems,    'No auto-processed emails in this range')}
      {activeTab === 'manual' && renderListTab(manualItems, 'No manually approved emails in this range')}
      {activeTab === 'log'    && renderLogTab()}
    </div>
  );
}
// ── Urgent Payments View ──────────────────────────────────────────────────────
function UrgentPaymentsView({ paymentLog, onRefresh, pushToast }) {
  const [showAdd, setShowAdd] = useState(false);
  const [form, setForm] = useState({ supplier:'', invoiceRef:'', amount:'', dueDate:'', notes:'' });
  const [saving, setSaving] = useState(false);

  const STATUSES = ['Pending','Queried','Approved','Paid','Disputed'];

  const handleStatusChange = async (id, status) => {
    try {
      await api.post('/api/payment-log/update', { id, status });
      onRefresh();
    } catch(e) { pushToast('Error: ' + e.message); }
  };

  const handleAdd = async () => {
    if (!form.supplier.trim()) return;
    setSaving(true);
    try {
      await api.post('/api/payment-log/add', form);
      pushToast('Entry added');
      setForm({ supplier:'', invoiceRef:'', amount:'', dueDate:'', notes:'' });
      setShowAdd(false);
      onRefresh();
    } catch(e) { pushToast('Error: ' + e.message); }
    setSaving(false);
  };

  const handleExport = async () => {
    try {
      window.location.href = '/api/payment-log/export';
      pushToast('Downloading Excel…');
    } catch(e) { pushToast('Export failed: ' + e.message); }
  };

  const outstanding = (paymentLog||[]).filter(p=>p.status !== 'Paid');
  const overdue     = outstanding.filter(p => p.dueDate && new Date(p.dueDate) < new Date());
  const totalAmt    = outstanding.reduce((s,p)=>s+(parseFloat(p.amount)||0),0);

  return (
    <div className="main-inner">
      <div className="page-head">
        <div>
          <h1 className="page-title">Urgent Payments</h1>
          <p className="page-sub">{outstanding.length} outstanding · {fmtAmt(totalAmt)} at risk · {overdue.length} overdue</p>
        </div>
        <div style={{display:'flex',gap:8}}>
          <button className="btn-ghost" onClick={handleExport}><Icons.download style={{width:14,height:14}}/> Export Excel</button>
          <button className="btn-primary" onClick={()=>setShowAdd(s=>!s)}><Icons.plus style={{width:14,height:14}}/> Add Entry</button>
        </div>
      </div>

      {showAdd && (
        <div className="add-form">
          <div className="form-row">
            <input placeholder="Supplier name *" value={form.supplier} onChange={e=>setForm(f=>({...f,supplier:e.target.value}))}/>
            <input placeholder="Invoice ref" value={form.invoiceRef} onChange={e=>setForm(f=>({...f,invoiceRef:e.target.value}))}/>
            <input placeholder="Amount $" type="number" value={form.amount} onChange={e=>setForm(f=>({...f,amount:e.target.value}))}/>
            <input placeholder="Due date" type="date" value={form.dueDate} onChange={e=>setForm(f=>({...f,dueDate:e.target.value}))}/>
          </div>
          <input placeholder="Notes" value={form.notes} onChange={e=>setForm(f=>({...f,notes:e.target.value}))} style={{width:'100%',marginBottom:8}}/>
          <div style={{display:'flex',gap:8}}>
            <button className="btn-primary" onClick={handleAdd} disabled={saving||!form.supplier.trim()}>{saving?'Saving…':'Add Entry'}</button>
            <button className="btn-ghost" onClick={()=>setShowAdd(false)}>Cancel</button>
          </div>
        </div>
      )}

      {(!paymentLog||paymentLog.length===0)
        ? <div className="empty-state"><div style={{fontSize:13,color:'#6b7280'}}>No urgent payment entries yet</div></div>
        : (
          <div className="table-wrap">
            <table className="data-table">
              <thead><tr>
                <th>Received</th><th>Supplier</th><th>Invoice Ref</th>
                <th>Amount</th><th>Due Date</th><th>Days Overdue</th>
                <th>Status</th><th>Notes</th>
              </tr></thead>
              <tbody>
                {(paymentLog||[]).map(p => {
                  const daysOver = p.dueDate
                    ? Math.max(0, Math.floor((Date.now()-new Date(p.dueDate))/(1000*86400)))
                    : 0;
                  const isOver = daysOver > 0 && p.status !== 'Paid';
                  return (
                    <tr key={p.id} style={{background: isOver ? '#fff7f7' : undefined}}>
                      <td style={{fontFamily:'var(--mono)',fontSize:11}}>{fmtDate(p.dateReceived)}</td>
                      <td style={{fontWeight:600}}>{p.supplier}</td>
                      <td style={{fontFamily:'var(--mono)',fontSize:12}}>{p.invoiceRef||'—'}</td>
                      <td style={{fontFamily:'var(--mono)',fontSize:12,fontWeight:600}}>{fmtAmt(p.amount)}</td>
                      <td style={{fontFamily:'var(--mono)',fontSize:11}}>{fmtDate(p.dueDate)}</td>
                      <td style={{color: isOver?'#dc2626':'#16a34a',fontWeight:700,fontFamily:'var(--mono)',fontSize:12}}>
                        {isOver ? `${daysOver}d` : '—'}
                      </td>
                      <td>
                        <select value={p.status} onChange={e=>handleStatusChange(p.id,e.target.value)}
                          style={{fontSize:12,padding:'3px 6px',borderRadius:4,border:'1px solid #d1d5db',
                            background: p.status==='Paid'?'#f0fdf4':p.status==='Disputed'?'#fef2f2':'#fff'}}>
                          {STATUSES.map(s=><option key={s}>{s}</option>)}
                        </select>
                      </td>
                      <td style={{fontSize:12,color:'#6b7280',maxWidth:160}}>{p.notes||'—'}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )
      }
    </div>
  );
}

// ── Summary View ──────────────────────────────────────────────────────────────
function SummaryView({ state, onScan, scanning }) {
  const stats    = state?.stats || {};
  const activity = state?.recentActivity || [];
  const payments = state?.paymentLog || [];
  const processed = state?.processed || [];

  const outstanding = payments.filter(p=>p.status!=='Paid');
  const overdue     = outstanding.filter(p=>p.dueDate&&new Date(p.dueDate)<new Date());
  const totalAmt    = outstanding.reduce((s,p)=>s+(parseFloat(p.amount)||0),0);

  // Category breakdown
  const catCounts = {};
  processed.forEach(p => { catCounts[p.category] = (catCounts[p.category]||0)+1; });
  const catEntries = Object.entries(catCounts).sort((a,b)=>b[1]-a[1]);
  const maxCount = Math.max(...catEntries.map(([,v])=>v), 1);

  return (
    <div className="main-inner">
      <div className="page-head">
        <div><h1 className="page-title">Summary</h1><p className="page-sub">Accounts inbox intelligence</p></div>
        <button className="btn-primary" onClick={onScan} disabled={scanning}>
          {scanning ? <><Icons.spin style={{width:14,height:14}}/> Scanning…</> : <><Icons.refresh style={{width:14,height:14}}/> Scan Now</>}
        </button>
      </div>

      {/* KPI Cards */}
      <div className="kpi-grid">
        <div className="kpi-card">
          <div className="kpi-label">Processed</div>
          <div className="kpi-value">{stats.processed||0}</div>
          <div className="kpi-sub">auto-filed today</div>
        </div>
        <div className="kpi-card kpi-warn">
          <div className="kpi-label">Review Queue</div>
          <div className="kpi-value">{state?.queue?.length||0}</div>
          <div className="kpi-sub">awaiting Mindy</div>
        </div>
        <div className="kpi-card kpi-danger">
          <div className="kpi-label">Urgent Payments</div>
          <div className="kpi-value">{outstanding.length}</div>
          <div className="kpi-sub">{fmtAmt(totalAmt)} outstanding</div>
        </div>
        <div className="kpi-card kpi-red">
          <div className="kpi-label">Overdue</div>
          <div className="kpi-value" style={{color:'#dc2626'}}>{overdue.length}</div>
          <div className="kpi-sub">past due date</div>
        </div>
      </div>

      <div className="summary-grid">
        {/* Category breakdown */}
        <div className="summary-card">
          <h3>Category Breakdown</h3>
          {catEntries.length === 0
            ? <div style={{color:'#9ca3af',fontSize:13}}>No data yet — run a scan</div>
            : catEntries.map(([cat, count]) => {
              const cs = catStyle(cat);
              return (
                <div key={cat} style={{marginBottom:8}}>
                  <div style={{display:'flex',justifyContent:'space-between',marginBottom:3}}>
                    <span style={{fontSize:12,fontWeight:600,color:cs.color}}>{fmtCatLabel(cat)}</span>
                    <span style={{fontSize:12,fontFamily:'var(--mono)',color:'#374151'}}>{count}</span>
                  </div>
                  <div style={{height:6,borderRadius:3,background:'#f3f4f6'}}>
                    <div style={{height:'100%',borderRadius:3,background:cs.color,width:`${(count/maxCount)*100}%`}}/>
                  </div>
                </div>
              );
            })
          }
        </div>

        {/* Recent Activity */}
        <div className="summary-card">
          <h3>Recent Activity</h3>
          {activity.length === 0
            ? <div style={{color:'#9ca3af',fontSize:13}}>No activity yet</div>
            : activity.slice(0,10).map((a,i) => (
              <div key={i} className="activity-item">
                <span className="activity-dot"/>
                <div>
                  <div style={{fontSize:12,fontWeight:600,color:'#1f2937'}}>{a.msg}</div>
                  <div style={{fontSize:11,color:'#9ca3af',fontFamily:'var(--mono)'}}>{fmtDate(a.ts)}</div>
                </div>
              </div>
            ))
          }
        </div>
      </div>
    </div>
  );
}

// ── Settings View ─────────────────────────────────────────────────────────────
function SettingsView({ settings, onRefresh, pushToast }) {
  const [cats, setCats]           = useState(settings?.categories || []);
  const [general, setGeneral]     = useState(settings?.general || { scanInterval:30, confidenceThreshold:85 });
  const [showAddCat, setShowAddCat] = useState(false);
  const [editingCat, setEditingCat] = useState(null);
  const [newCat, setNewCat]       = useState({ key:'', displayName:'', forwardTo:'', autoForward:false });
  const [saving, setSaving]       = useState(false);

  useEffect(() => {
    setCats(settings?.categories || []);
    setGeneral(settings?.general || { scanInterval:30, confidenceThreshold:85 });
  }, [settings]);

  const handleSaveGeneral = async () => {
    setSaving(true);
    try {
      await api.post('/api/settings', { categories: cats, general });
      pushToast('Settings saved');
      onRefresh();
    } catch(e) { pushToast('Error: ' + e.message); }
    setSaving(false);
  };

  const handleAddCat = async () => {
    if (!newCat.key.trim() || !newCat.displayName.trim()) return;
    const cat = {
      key: newCat.key.toLowerCase().replace(/\s+/g,'-'),
      displayName: newCat.displayName,
      forwardTo: newCat.forwardTo.split(',').map(e=>e.trim()).filter(Boolean),
      autoForward: newCat.autoForward,
      emailFolder: `Accounts/Routed/${newCat.displayName}`,
    };
    const updated = [...cats, cat];
    try {
      await api.post('/api/settings', { categories: updated, general });
      setCats(updated);
      setShowAddCat(false);
      setNewCat({ key:'', displayName:'', forwardTo:'', autoForward:false });
      pushToast('Category added: ' + cat.displayName);
      onRefresh();
    } catch(e) { pushToast('Error: ' + e.message); }
  };

  const handleDeleteCat = async (key) => {
    const updated = cats.filter(c=>c.key!==key);
    try {
      await api.post('/api/settings', { categories: updated, general });
      setCats(updated);
      pushToast('Category removed');
      onRefresh();
    } catch(e) { pushToast('Error: ' + e.message); }
  };

  const handleSaveCat = async (cat) => {
    const updated = cats.map(c => c.key===cat.key ? cat : c);
    try {
      await api.post('/api/settings', { categories: updated, general });
      setCats(updated);
      setEditingCat(null);
      pushToast('Category updated');
      onRefresh();
    } catch(e) { pushToast('Error: ' + e.message); }
  };

  return (
    <div className="main-inner">
      <div className="page-head">
        <div><h1 className="page-title">Settings</h1><p className="page-sub">Configure routing categories and scan behaviour</p></div>
      </div>

      {/* Categories */}
      <div className="settings-section">
        <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:16}}>
          <h2 className="section-title">Routing Categories</h2>
          <button className="btn-primary" onClick={()=>setShowAddCat(s=>!s)}>
            <Icons.plus style={{width:13,height:13}}/> Add Category
          </button>
        </div>

        {showAddCat && (
          <div className="add-form" style={{marginBottom:16}}>
            <div className="form-row">
              <input placeholder="Key (e.g. route-legal)" value={newCat.key}
                onChange={e=>setNewCat(f=>({...f,key:e.target.value}))}/>
              <input placeholder="Display name (e.g. → Legal)" value={newCat.displayName}
                onChange={e=>setNewCat(f=>({...f,displayName:e.target.value}))}/>
            </div>
            <input placeholder="Forward to emails (comma-separated)" value={newCat.forwardTo}
              onChange={e=>setNewCat(f=>({...f,forwardTo:e.target.value}))}
              style={{width:'100%',marginBottom:8}}/>
            <label style={{display:'flex',alignItems:'center',gap:6,fontSize:13,marginBottom:12}}>
              <input type="checkbox" checked={newCat.autoForward}
                onChange={e=>setNewCat(f=>({...f,autoForward:e.target.checked}))}/>
              Auto-forward at ≥85% confidence
            </label>
            <div style={{display:'flex',gap:8}}>
              <button className="btn-primary" onClick={handleAddCat}>Add</button>
              <button className="btn-ghost" onClick={()=>setShowAddCat(false)}>Cancel</button>
            </div>
          </div>
        )}

        <div className="table-wrap">
          <table className="data-table">
            <thead><tr><th>Key</th><th>Display Name</th><th>Forward To</th><th>Auto-Forward</th><th>Actions</th></tr></thead>
            <tbody>
              {cats.map(cat => (
                <tr key={cat.key}>
                  {editingCat?.key === cat.key ? (
                    <>
                      <td><code style={{fontSize:11}}>{cat.key}</code></td>
                      <td><input value={editingCat.displayName} onChange={e=>setEditingCat(c=>({...c,displayName:e.target.value}))} style={{width:'100%'}}/></td>
                      <td><input value={(editingCat.forwardTo||[]).join(', ')}
                        onChange={e=>setEditingCat(c=>({...c,forwardTo:e.target.value.split(',').map(x=>x.trim()).filter(Boolean)}))}
                        style={{width:'100%'}} placeholder="email1@, email2@"/></td>
                      <td><input type="checkbox" checked={editingCat.autoForward}
                        onChange={e=>setEditingCat(c=>({...c,autoForward:e.target.checked}))}/></td>
                      <td>
                        <button className="btn-sm btn-primary" onClick={()=>handleSaveCat(editingCat)}>Save</button>
                        <button className="btn-sm btn-ghost" onClick={()=>setEditingCat(null)} style={{marginLeft:4}}>Cancel</button>
                      </td>
                    </>
                  ) : (
                    <>
                      <td><code style={{fontSize:11,color:'#6b7280'}}>{cat.key}</code></td>
                      <td style={{fontWeight:600}}>{cat.displayName}</td>
                      <td style={{fontSize:12}}>
                        {(cat.forwardTo||[]).length
                          ? (cat.forwardTo||[]).map(e=><span key={e} className="email-tag">{e}</span>)
                          : <span style={{color:'#9ca3af'}}>—</span>}
                      </td>
                      <td>{cat.autoForward ? '✅' : '—'}</td>
                      <td>
                        <button className="btn-sm btn-ghost" onClick={()=>setEditingCat({...cat})}><Icons.edit style={{width:12,height:12}}/></button>
                        <button className="btn-sm btn-ghost" style={{color:'#dc2626',marginLeft:4}}
                          onClick={()=>handleDeleteCat(cat.key)}><Icons.trash style={{width:12,height:12}}/></button>
                      </td>
                    </>
                  )}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>

      {/* General Settings */}
      <div className="settings-section">
        <h2 className="section-title">General</h2>
        <div className="general-grid">
          <div>
            <label className="field-label">Scan Interval (minutes)</label>
            <input type="number" value={general.scanInterval} min={5} max={120}
              onChange={e=>setGeneral(g=>({...g,scanInterval:parseInt(e.target.value)}))}
              style={{width:100}}/>
          </div>
          <div>
            <label className="field-label">Confidence Threshold (%)</label>
            <div style={{display:'flex',alignItems:'center',gap:12}}>
              <input type="range" min={50} max={99} value={general.confidenceThreshold}
                onChange={e=>setGeneral(g=>({...g,confidenceThreshold:parseInt(e.target.value)}))}
                style={{width:140}}/>
              <span style={{fontWeight:700,color:'var(--navy)',fontFamily:'var(--mono)'}}>{general.confidenceThreshold}%</span>
            </div>
          </div>
          <div>
            <label className="field-label">Mode</label>
            <span style={{display:'inline-flex',alignItems:'center',gap:6,padding:'6px 12px',background:'#dbeafe',color:'#1d4ed8',borderRadius:6,fontSize:12,fontWeight:600}}>
              ● Mock Mode Active
            </span>
            <div style={{fontSize:11,color:'#9ca3af',marginTop:4}}>Real Graph API — connect when ready</div>
          </div>
        </div>
        <button className="btn-primary" onClick={handleSaveGeneral} disabled={saving} style={{marginTop:16}}>
          {saving?'Saving…':'Save Settings'}
        </button>
      </div>
    </div>
  );
}

Object.assign(window, { ReviewQueueView, ProcessedView, UrgentPaymentsView, SummaryView, SettingsView });
