// Mail module — richer pieces: coverage health strip, smart-rules panel, undo toast.
// Kept in their own file (shared global scope) so MailCoverage.jsx stays focused.

// Tiny self-contained sparkline (avoids cross-file load-order coupling).
function MailSpark({ data, color, w = 70, h = 26 }) {
  const pad = 2;
  const min = Math.min(...data), max = Math.max(...data), rng = (max - min) || 1;
  const pts = data.map((v, i) => {
    const x = pad + (i / (data.length - 1)) * (w - 2 * pad);
    const y = h - pad - ((v - min) / rng) * (h - 2 * pad);
    return `${x.toFixed(1)},${y.toFixed(1)}`;
  });
  const last = pts[pts.length - 1].split(',');
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} fill="none">
      <polyline points={pts.join(' ')} stroke={color} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" opacity="0.9" />
      <circle cx={last[0]} cy={last[1]} r="2.4" fill={color} />
    </svg>
  );
}

// ---- Coverage health strip — at-a-glance trust numbers + 7-day trend ----
function CoverageHealth({ scanned, autoSorted, neededYou, missed = 0, trend }) {
  const autoPct = scanned ? Math.round((autoSorted / scanned) * 100) : 0;
  return (
    <div className="cov-health rise">
      <div className="ch-tile">
        <div className="ch-top"><span className="ch-lbl">Reviewed</span><span className="ch-ic" style={{ background:'var(--surface-sunk)' }}><Icon name="mail-search" size={15} color="var(--fg-3)" /></span></div>
        <div className="ch-val">{scanned}</div>
        <div className="ch-sub">in this range</div>
      </div>
      <div className="ch-tile">
        <div className="ch-top"><span className="ch-lbl">Sorted by rules</span><span className="ch-ic" style={{ background:'var(--teal-50)' }}><Icon name="zap" size={15} color="var(--teal-500)" /></span></div>
        <div className="ch-val">{autoSorted}</div>
        <div className="ch-sub"><b style={{ color:'var(--teal-500)' }}>{autoPct}%</b> — no AI used</div>
      </div>
      <div className="ch-tile">
        <div className="ch-top"><span className="ch-lbl">Needed you</span><span className="ch-ic" style={{ background:'var(--gold-100)' }}><Icon name="user-check" size={15} color="var(--gold-700)" /></span></div>
        <div className="ch-val">{neededYou}</div>
        <div className="ch-spark">{trend && trend.length > 1 && <MailSpark data={trend} color="var(--gold-600)" />}</div>
      </div>
      <div className="ch-tile ch-trust">
        <div className="ch-top"><span className="ch-lbl">Handled</span><span className="ch-ic" style={{ background:'var(--green-50)' }}><Icon name="shield-check" size={15} color="var(--green-600)" /></span></div>
        <div className="ch-val" style={{ color:'var(--green-600)' }}>{missed === 0 ? '100%' : `${missed}`}</div>
        <div className="ch-sub">{missed === 0 ? 'nothing missed' : 'review needed'}</div>
      </div>
    </div>
  );
}

// ---- Smart rules — the deterministic sorters that keep AI use (and cost) low ----
// `applied` = lifetime fires this month; the point is most volume never touches a model.
const MAIL_RULES = [
  { id:'r1', scope:'Newsletters',          match:'Bulk senders with an unsubscribe footer', action:'Skip',            verb:'skip',   icon:'minus-circle', tint:'gray',   applied:1240, on:true },
  { id:'r2', scope:'Promotions',           match:'Marketing & deal senders',                action:'Skip',            verb:'skip',   icon:'tag',          tint:'gray',   applied:860,  on:true },
  { id:'r3', scope:'Social notifications', match:'LinkedIn, X & similar alert addresses',   action:'Skip',            verb:'skip',   icon:'bell-off',     tint:'gray',   applied:430,  on:true },
  { id:'r4', scope:'Bank & card statements', match:'Known bank / card sender + “statement”',action:'File to Banking', verb:'file',   icon:'landmark',     tint:'blue',   applied:128,  on:true },
  { id:'r5', scope:'Insurer & utility bills', match:'Insurer / utility sender + “due”',     action:'Create a bill',   verb:'create', icon:'dollar-sign',  tint:'gold',   applied:74,   on:true },
  { id:'r6', scope:'Shipping updates',     match:'Carrier sender + “shipped / delivery”',   action:'Track a package', verb:'track',  icon:'package',      tint:'teal',   applied:36,   on:true },
  { id:'r7', scope:'Calendar invites',     match:'.ics invite or “confirmed for” + a date', action:'Add an event',    verb:'add',    icon:'calendar',     tint:'purple', applied:52,   on:true },
];

function RulesPanel({ onClose }) {
  const [rules, setRules] = useState(MAIL_RULES);
  const toggle = id => setRules(rs => rs.map(r => r.id === id ? { ...r, on: !r.on } : r));
  const totalApplied = rules.filter(r => r.on).reduce((s, r) => s + r.applied, 0);
  return (
    <React.Fragment>
      <div className="scrim" onClick={onClose} />
      <div className="drawer zd-scroll">
        <div className="dhead">
          <span className="ic-chip" style={{ background:'var(--teal-50)', width:40, height:40, borderRadius:12, display:'grid', placeItems:'center' }}><Icon name="zap" size={19} color="var(--teal-500)" /></span>
          <div style={{ flex:1, minWidth:0 }}>
            <div style={{ fontFamily:'var(--font-display)', fontWeight:700, fontSize:17 }}>Sorting rules</div>
            <div style={{ fontSize:12.5, color:'var(--fg-3)' }}>How Zeranda sorts mail without AI</div>
          </div>
          <button className="iconbtn" onClick={onClose}><Icon name="x" size={18} /></button>
        </div>
        <div className="dbody">
          <div className="rules-note">
            <Icon name="info" size={15} color="var(--teal-500)" />
            <span>Rules do the heavy lifting — they’re instant and free. This month <b>{totalApplied.toLocaleString()}</b> emails were sorted by rules; only the handful that didn’t match any rule got a closer, AI-assisted look. More rules = less AI = lower cost.</span>
          </div>
          <div className="rules-list">
            {rules.map(r => (
              <div className={`rule-row ${r.on ? '' : 'off'}`} key={r.id}>
                <span className="rule-ic" style={{ background: tintBg(r.tint === 'gray' ? 'gold' : r.tint), opacity: r.tint === 'gray' ? .5 : 1 }}>
                  <Icon name={r.icon} size={16} color={r.tint === 'gray' ? 'var(--fg-3)' : tintFg(r.tint)} />
                </span>
                <div className="rule-meta">
                  <div className="rule-l">{r.scope} <span className="rule-arrow">→</span> <b>{r.action}</b></div>
                  <div className="rule-s">{r.match}</div>
                  <div className="rule-applied"><Icon name="repeat" size={11} color="var(--fg-4)" /> applied {r.applied.toLocaleString()}× this month</div>
                </div>
                <button className={`zswitch ${r.on ? 'on' : ''}`} role="switch" aria-checked={r.on} onClick={() => toggle(r.id)}><span className="knob" /></button>
              </div>
            ))}
          </div>
          <button className="rule-add"><Icon name="plus" size={15} /> Add a rule from a sender</button>
        </div>
      </div>
    </React.Fragment>
  );
}

// ---- Undo toast (reuses the dark convert-toast shell) ----
function UndoToast({ label, onUndo, onClose }) {
  useEffect(() => { const t = setTimeout(onClose, 5000); return () => clearTimeout(t); }, [label]);
  return (
    <div className="convert-toast" role="status">
      <span className="ct-ic" style={{ background:'var(--green-600)' }}><Icon name="check" size={18} color="#fff" /></span>
      <div className="ct-body"><div className="ct-t">{label}</div><div className="ct-s">Removed from your “needs a look” pile</div></div>
      <button className="ct-go" onClick={onUndo}><Icon name="rotate-ccw" size={14} /> Undo</button>
      <button className="iconbtn ct-x" onClick={onClose}><Icon name="x" size={16} /></button>
    </div>
  );
}

Object.assign(window, { MailSpark, CoverageHealth, RulesPanel, UndoToast, MAIL_RULES });
