/* global React, SUPPLIERS, CATEGORIES, catOf, fmtTHB,
   Avatar, StatusPill, CategoryTag, RatingBar,
   COMPLIANCE_META,
   IconShield, IconClock, IconChart, IconCheck, IconX, IconDownload, IconUpload,
   IconCal, IconChevron, IconChevronDn, IconDots, IconSearch, IconFile,
   IconFilter, IconArrow, IconExt, IconPlus, IconEye, IconBank, IconBuilding,
   IconReceipt, IconUsers
*/
const { useState: useStateAdm, useMemo: useMemoAdm } = React;

/* ============================================================
   SHARED — tiny inline SVG charts
   ============================================================ */
function BarChart({ data, height = 140, accentIndex = -1 }) {
  const max = Math.max(...data.map(d => d.v));
  const W = 480, H = height, pad = 24;
  const bw = (W - pad * 2) / data.length;
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{display:"block"}}>
      {[0, 1, 2, 3].map(i => {
        const y = pad + ((H - pad * 2) / 3) * i;
        return <line key={i} x1={pad} x2={W - pad} y1={y} y2={y} stroke="var(--border-subtle)" strokeWidth="1"/>;
      })}
      {data.map((d, i) => {
        const h = ((H - pad * 2) * d.v) / max;
        const x = pad + bw * i + 4;
        const y = H - pad - h;
        const w = bw - 8;
        const isAccent = i === accentIndex;
        return (
          <g key={i}>
            <rect x={x} y={y} width={w} height={h} rx="3"
              fill={isAccent ? "var(--accent)" : "var(--border-default)"}/>
            <text x={x + w/2} y={H - pad + 14} fontSize="10" textAnchor="middle"
              fill="var(--text-tertiary)" fontFamily="var(--font-mono)">{d.l}</text>
          </g>
        );
      })}
    </svg>
  );
}

function AreaChart({ data, height = 160, color = "var(--accent)" }) {
  const max = Math.max(...data.map(d => d.v)) * 1.1;
  const W = 720, H = height, pad = 28;
  const innerW = W - pad * 2;
  const innerH = H - pad * 2;
  const pts = data.map((d, i) => {
    const x = pad + (innerW * i) / (data.length - 1);
    const y = pad + innerH - (innerH * d.v) / max;
    return [x, y];
  });
  const path = "M " + pts.map(p => p.join(",")).join(" L ");
  const fill = path + ` L ${pts[pts.length-1][0]},${pad + innerH} L ${pts[0][0]},${pad + innerH} Z`;
  return (
    <svg viewBox={`0 0 ${W} ${H}`} width="100%" style={{display:"block"}}>
      <defs>
        <linearGradient id="ac-grad" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0" stopColor={color} stopOpacity="0.3"/>
          <stop offset="1" stopColor={color} stopOpacity="0"/>
        </linearGradient>
      </defs>
      {[0, 1, 2, 3, 4].map(i => {
        const y = pad + (innerH / 4) * i;
        return <line key={i} x1={pad} x2={W - pad} y1={y} y2={y} stroke="var(--border-subtle)" strokeWidth="1"/>;
      })}
      <path d={fill} fill="url(#ac-grad)"/>
      <path d={path} fill="none" stroke={color} strokeWidth="2"/>
      {pts.map((p, i) => (
        <circle key={i} cx={p[0]} cy={p[1]} r="2.5" fill={color}/>
      ))}
      {data.map((d, i) => (
        <text key={i} x={pts[i][0]} y={H - 8} fontSize="10" textAnchor="middle"
          fill="var(--text-tertiary)" fontFamily="var(--font-mono)">{d.l}</text>
      ))}
    </svg>
  );
}

function DonutChart({ data, size = 180 }) {
  const total = data.reduce((a, b) => a + b.v, 0);
  const r = size / 2 - 14;
  const cx = size / 2, cy = size / 2;
  const c = 2 * Math.PI * r;
  let offset = 0;
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size} style={{display:"block"}}>
      <circle cx={cx} cy={cy} r={r} fill="none" stroke="var(--border-subtle)" strokeWidth="20"/>
      {data.map((d, i) => {
        const len = (d.v / total) * c;
        const el = (
          <circle key={i} cx={cx} cy={cy} r={r} fill="none"
            stroke={d.color} strokeWidth="20"
            strokeDasharray={`${len} ${c - len}`}
            strokeDashoffset={-offset}
            transform={`rotate(-90 ${cx} ${cy})`}
            strokeLinecap="butt"/>
        );
        offset += len;
        return el;
      })}
      <text x={cx} y={cy - 4} textAnchor="middle" fontSize="22" fontWeight="600"
        fill="var(--text-primary)" fontFamily="var(--font-en)">
        {fmtTHB(total).replace("฿", "฿")}
      </text>
      <text x={cx} y={cy + 14} textAnchor="middle" fontSize="10"
        fill="var(--text-tertiary)" fontFamily="var(--font-mono)" letterSpacing="0.08em">
        TOTAL SPEND
      </text>
    </svg>
  );
}

function MiniSpark({ data, color = "var(--accent)", width = 80, height = 24 }) {
  const max = Math.max(...data);
  const min = Math.min(...data);
  const range = max - min || 1;
  const pts = data.map((v, i) => {
    const x = (i / (data.length - 1)) * width;
    const y = height - ((v - min) / range) * height;
    return `${x},${y.toFixed(1)}`;
  }).join(" ");
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} style={{display:"block"}}>
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.5"/>
    </svg>
  );
}

/* ============================================================
   SCREEN — COMPLIANCE
   ============================================================ */
const COMPLIANCE_ROWS = SUPPLIERS.map((s, i) => {
  // Synthesise document expiry data per supplier
  const seed = i + 1;
  const expiresIn = (seed * 37) % 360 - 30; // -30 to 330 days
  return {
    ...s,
    docs: {
      bizReg:    { state: "verified", expires: ((seed * 19) % 600) + 60 },
      vat:       { state: i === 3 ? "expired" : (i === 11 ? "expiring" : "verified"), expires: i === 3 ? -8 : (i === 11 ? 12 : 220) },
      bank:      { state: i === 12 ? "missing" : "verified", expires: 480 },
      insurance: { state: i % 5 === 0 ? "expiring" : "verified", expires: i % 5 === 0 ? 22 : 180 },
      msa:       { state: "verified", expires: 730 },
    },
    kycLast: ["3 days ago", "2 weeks ago", "1 month ago", "3 months ago", "5 months ago", "9 months ago"][i % 6],
    nextReview: i % 4 === 0 ? "Overdue" : ((i * 13) % 90 + 15) + " days",
    riskScore: ((i * 11) % 100),
  };
});

function ScreenCompliance() {
  const [tab, setTab] = useStateAdm("all");

  const filtered = useMemoAdm(() => {
    if (tab === "expiring") return COMPLIANCE_ROWS.filter(r =>
      Object.values(r.docs).some(d => d.state === "expiring" || d.state === "expired"));
    if (tab === "kyc") return COMPLIANCE_ROWS.filter(r => r.compliance === "kyc-pending");
    if (tab === "black") return COMPLIANCE_ROWS.filter(r => r.compliance === "rejected" || r.status === "blacklist");
    return COMPLIANCE_ROWS;
  }, [tab]);

  const docCell = (d) => {
    const map = {
      verified:  { icon: <IconCheck size={11}/>, color: "var(--success)" },
      expiring:  { icon: "!", color: "var(--warning)" },
      expired:   { icon: <IconX size={11}/>, color: "var(--danger)" },
      missing:   { icon: "?", color: "var(--text-tertiary)" },
    };
    const m = map[d.state] || map.missing;
    return (
      <span style={{
        display: "inline-flex", alignItems: "center", gap: 6,
        fontSize: 11, color: m.color, fontFamily: "var(--font-mono)",
      }}>
        <span style={{
          width: 14, height: 14, borderRadius: "50%",
          background: `color-mix(in oklab, ${m.color} 18%, transparent)`,
          display: "inline-flex", alignItems: "center", justifyContent: "center",
          fontWeight: 600, fontSize: 10,
        }}>{m.icon}</span>
        {d.state === "verified" ? "OK" :
         d.state === "expiring" ? `${d.expires}d` :
         d.state === "expired" ? "EXP" :
         "—"}
      </span>
    );
  };

  return (
    <div className="page">
      <div className="page-header">
        <div className="page-title-group">
          <h1>Compliance</h1>
          <div className="sub">KYC, document expiry &amp; blacklist monitoring · last audit run 4 hours ago</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-secondary btn-sm"><IconDownload size={14}/> Export audit pack</button>
          <button className="btn btn-primary btn-sm"><IconShield size={14}/> Run re-verification</button>
        </div>
      </div>

      <div className="stat-row">
        <div className="stat-tile">
          <div className="label">Verified</div>
          <div className="val tnum" style={{color: "var(--success)"}}>134</div>
          <div className="delta">94.4% of active vendors</div>
        </div>
        <div className="stat-tile">
          <div className="label">KYC pending</div>
          <div className="val tnum" style={{color: "var(--warning)"}}>3</div>
          <div className="delta">Avg 12 days outstanding</div>
        </div>
        <div className="stat-tile">
          <div className="label">Docs expiring (30d)</div>
          <div className="val tnum" style={{color: "var(--warning)"}}>8</div>
          <div className="delta">VAT certs · insurance</div>
        </div>
        <div className="stat-tile">
          <div className="label">Blacklisted</div>
          <div className="val tnum" style={{color: "var(--danger)"}}>1</div>
          <div className="delta down">Drayage Express · Mar 18</div>
        </div>
      </div>

      <div className="tabs">
        {[
          ["all",      "All vendors",     COMPLIANCE_ROWS.length],
          ["expiring", "Docs expiring",   8],
          ["kyc",      "KYC pending",     3],
          ["black",    "Blacklist",       1],
          ["history",  "Re-verification log", null],
        ].map(([id, lbl, n]) => (
          <button key={id} className={"tab " + (tab === id ? "active" : "")} onClick={() => setTab(id)}>
            {lbl} {n !== null && <span className="muted" style={{marginLeft: 6, fontSize: 11}}>{n}</span>}
          </button>
        ))}
      </div>

      <div className="toolbar">
        <button className="chip"><IconFilter size={12}/> Filters</button>
        <button className="chip">Category</button>
        <button className="chip">Risk score</button>
        <button className="chip">Owner</button>
        <button className="chip">Last reviewed</button>
        <div className="toolbar-right">
          <div className="topbar-search" style={{maxWidth: 220, margin: 0}}>
            <IconSearch size={14} className="icon"/>
            <input placeholder="Search vendors…"/>
          </div>
          <button className="chip"><IconCal size={12}/> Last 30 days</button>
        </div>
      </div>

      <div className="tbl-wrap">
        <table className="tbl">
          <colgroup>
            <col style={{width: 260}}/>
            <col style={{width: 130}}/>
            <col style={{width: 110}}/>
            <col style={{width: 80}}/>
            <col style={{width: 80}}/>
            <col style={{width: 80}}/>
            <col style={{width: 90}}/>
            <col style={{width: 80}}/>
            <col style={{width: 120}}/>
            <col style={{width: 120}}/>
            <col style={{width: 90}}/>
          </colgroup>
          <thead>
            <tr>
              <th>Vendor</th>
              <th>Category</th>
              <th>Status</th>
              <th>Biz reg</th>
              <th>VAT cert</th>
              <th>Bank ltr</th>
              <th>Insurance</th>
              <th>MSA</th>
              <th>Last KYC</th>
              <th>Next review</th>
              <th className="right">Risk</th>
            </tr>
          </thead>
          <tbody>
            {filtered.map(r => (
              <tr key={r.id}>
                <td>
                  <div style={{display:"flex", alignItems:"center", gap:10}}>
                    <Avatar name={r.name} size="sm"/>
                    <div style={{minWidth:0}}>
                      <div className="ellipsis" style={{fontSize: 13}}>{r.name}</div>
                      <div className="mono muted" style={{fontSize: 11}}>{r.id}</div>
                    </div>
                  </div>
                </td>
                <td><CategoryTag id={r.cat}/></td>
                <td><StatusPill meta={COMPLIANCE_META[r.compliance]}/></td>
                <td>{docCell(r.docs.bizReg)}</td>
                <td>{docCell(r.docs.vat)}</td>
                <td>{docCell(r.docs.bank)}</td>
                <td>{docCell(r.docs.insurance)}</td>
                <td>{docCell(r.docs.msa)}</td>
                <td className="muted" style={{fontSize: 12}}>{r.kycLast}</td>
                <td>
                  <span className="mono" style={{
                    fontSize: 12,
                    color: r.nextReview === "Overdue" ? "var(--danger)" : "var(--text-secondary)"
                  }}>{r.nextReview}</span>
                </td>
                <td className="right">
                  <span style={{
                    display: "inline-flex", alignItems: "center", gap: 6,
                    fontFamily: "var(--font-mono)", fontSize: 12,
                    color: r.riskScore > 70 ? "var(--danger)" : r.riskScore > 40 ? "var(--warning)" : "var(--success)",
                  }}>
                    <span style={{
                      width: 30, height: 4, background: "var(--interactive-secondary)",
                      borderRadius: 2, position: "relative", overflow: "hidden",
                    }}>
                      <span style={{
                        position: "absolute", left: 0, top: 0, bottom: 0,
                        width: r.riskScore + "%",
                        background: r.riskScore > 70 ? "var(--danger)" : r.riskScore > 40 ? "var(--warning)" : "var(--success)",
                      }}></span>
                    </span>
                    {r.riskScore}
                  </span>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <div className="status-bar">
        <span>{filtered.length} of {COMPLIANCE_ROWS.length} vendors</span>
        <span>·</span>
        <span>Next batch re-verification scheduled May 24</span>
        <span style={{marginLeft:"auto"}}>Last sync: 4h ago · PDPA-compliant</span>
      </div>
    </div>
  );
}

/* ============================================================
   SCREEN — AUDIT LOG
   ============================================================ */
const AUDIT_ACTIONS = [
  { id: "approve",  label: "Approved",        color: "var(--success)", icon: <IconCheck size={11}/> },
  { id: "reject",   label: "Rejected",        color: "var(--danger)",  icon: <IconX size={11}/> },
  { id: "create",   label: "Created",         color: "var(--accent)",  icon: <IconPlus size={11}/> },
  { id: "edit",     label: "Edited",          color: "var(--info)",    icon: "✎" },
  { id: "view",     label: "Viewed",          color: "var(--text-tertiary)", icon: <IconEye size={11}/> },
  { id: "upload",   label: "Uploaded",        color: "var(--info)",    icon: <IconUpload size={11}/> },
  { id: "login",    label: "Signed in",       color: "var(--text-tertiary)", icon: "→" },
];

const AUDIT_EVENTS = [
  { t: "10:42:18", date: "Today",      actor: "Ananda V.",       role: "Finance",    action: "approve", entity: "INV-2026-0418", target: "Tinker Post Bangkok", note: "Verified bank match. Approved for payment.", ip: "203.150.18.42", before: "Finance verify", after: "Approved for payment" },
  { t: "10:31:04", date: "Today",      actor: "Ploy V.",         role: "PM",         action: "approve", entity: "INV-2026-0418", target: "Tinker Post Bangkok", note: "PO matches. Final mix delivered on time.", ip: "203.150.18.11", before: "PM review", after: "Finance verify" },
  { t: "09:58:22", date: "Today",      actor: "system",          role: "OCR",        action: "create",  entity: "INV-2026-0518", target: "Tinker Post Bangkok", note: "Invoice received via portal. OCR confidence 98.4%.", ip: "—", before: null, after: "PM review" },
  { t: "09:48:11", date: "Today",      actor: "Tinker Post BKK", role: "Vendor",     action: "upload",  entity: "INV-2026-0518.pdf", target: "Portal", note: "1.8 MB · 3 line items detected", ip: "171.96.224.18", before: null, after: null },
  { t: "08:42:00", date: "Today",      actor: "Ploy V.",         role: "PM",         action: "login",   entity: "Vendor OS", target: "—", note: "Web · Chrome 124 · BKK", ip: "203.150.18.11", before: null, after: null },
  { t: "17:14:08", date: "Yesterday",  actor: "Tee S.",          role: "PM",         action: "create",  entity: "VND-1313",      target: "Citylight Banners Ltd.", note: "New supplier registration submitted to Procurement queue.", ip: "203.150.18.55", before: null, after: "Pending approval" },
  { t: "16:51:24", date: "Yesterday",  actor: "Aim K.",          role: "Procurement",action: "edit",    entity: "VND-1042",      target: "Tinker Post Bangkok", note: "Credit terms changed.", ip: "203.150.18.78", before: "NET 30",  after: "NET 45" },
  { t: "15:02:18", date: "Yesterday",  actor: "Win C.",          role: "AE",         action: "view",    entity: "VND-1248",      target: "Bright Lens Productions", note: "Profile viewed.", ip: "203.150.18.40", before: null, after: null },
  { t: "11:18:44", date: "Yesterday",  actor: "Ananda V.",       role: "Finance",    action: "reject",  entity: "INV-2026-0501", target: "Krungsri auto loan", note: "PO line items don't reconcile. Returned to vendor with comments.", ip: "203.150.18.42", before: "Finance verify", after: "Rejected" },
  { t: "09:11:00", date: "May 14",     actor: "Aim K.",          role: "Procurement",action: "approve", entity: "VND-1314",      target: "Reverb Sound Stage", note: "All KYC checks cleared. Vendor active.", ip: "203.150.18.78", before: "Pending approval", after: "Active" },
  { t: "16:24:31", date: "May 13",     actor: "system",          role: "Cron",       action: "edit",    entity: "VND-1212",      target: "Drayage Express", note: "Auto-flagged on quality threshold (score 2.4).", ip: "—", before: "Active", after: "Under review" },
  { t: "14:08:12", date: "May 13",     actor: "Mod K.",          role: "BD",         action: "edit",    entity: "VND-1051",      target: "Aurora Media Group", note: "Bank account updated.", ip: "203.150.18.33", before: "xxx-x-x3491-x", after: "xxx-x-x4781-x" },
  { t: "11:52:48", date: "May 13",     actor: "Earth P.",        role: "PM",         action: "upload",  entity: "msa-signed.pdf", target: "Tinker Post Bangkok", note: "MSA 2026 countersigned.", ip: "203.150.18.91", before: null, after: null },
];

function ScreenAudit() {
  const [openIdx, setOpenIdx] = useStateAdm(0);
  const [actionFilter, setActionFilter] = useStateAdm(new Set());

  const filtered = AUDIT_EVENTS.filter(e =>
    actionFilter.size === 0 || actionFilter.has(e.action)
  );

  const groups = filtered.reduce((acc, e) => {
    (acc[e.date] = acc[e.date] || []).push(e);
    return acc;
  }, {});

  const open = filtered[openIdx] || filtered[0];

  const toggleAction = (id) => {
    const n = new Set(actionFilter);
    n.has(id) ? n.delete(id) : n.add(id);
    setActionFilter(n);
  };

  const actionMeta = (id) => AUDIT_ACTIONS.find(a => a.id === id) || AUDIT_ACTIONS[0];

  return (
    <div className="page">
      <div className="page-header">
        <div className="page-title-group">
          <h1>Audit log</h1>
          <div className="sub">Every action across vendors, invoices and accounts · retained 7 years</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-secondary btn-sm"><IconCal size={14}/> Last 30 days</button>
          <button className="btn btn-secondary btn-sm"><IconDownload size={14}/> Export CSV</button>
        </div>
      </div>

      <div className="toolbar">
        <span className="muted" style={{fontSize: 11, textTransform: "uppercase", letterSpacing: "0.08em"}}>Action</span>
        {AUDIT_ACTIONS.map(a => (
          <button key={a.id}
            className={"chip " + (actionFilter.has(a.id) ? "active" : "")}
            onClick={() => toggleAction(a.id)}>
            <span style={{
              width: 12, height: 12, borderRadius: "50%",
              background: `color-mix(in oklab, ${a.color} 22%, transparent)`,
              color: a.color, display: "inline-flex", alignItems: "center", justifyContent: "center",
              fontSize: 9,
            }}>{a.icon}</span>
            {a.label}
          </button>
        ))}
        <div className="toolbar-right">
          <div className="topbar-search" style={{maxWidth: 240, margin: 0}}>
            <IconSearch size={14} className="icon"/>
            <input placeholder="Search actor, entity, IP…"/>
          </div>
        </div>
      </div>

      <div style={{display: "grid", gridTemplateColumns: "1fr 420px", flex: 1, overflow: "hidden"}}>
        <div style={{overflowY: "auto", borderRight: "1px solid var(--border-subtle)"}}>
          {Object.entries(groups).map(([date, events]) => (
            <div key={date}>
              <div style={{
                position: "sticky", top: 0, zIndex: 2,
                background: "var(--bg-primary)",
                padding: "10px 24px 8px",
                fontSize: 11, textTransform: "uppercase", letterSpacing: "0.08em",
                color: "var(--text-tertiary)",
                borderBottom: "1px solid var(--border-subtle)",
                fontFamily: "var(--font-mono)",
              }}>
                {date} <span style={{marginLeft: 8}}>{events.length} events</span>
              </div>
              {events.map((e, i) => {
                const idx = filtered.indexOf(e);
                const a = actionMeta(e.action);
                return (
                  <div key={i}
                    onClick={() => setOpenIdx(idx)}
                    style={{
                      display: "grid",
                      gridTemplateColumns: "70px 22px 1fr auto",
                      gap: 12,
                      alignItems: "center",
                      padding: "10px 24px",
                      borderBottom: "1px solid var(--border-subtle)",
                      cursor: "pointer",
                      background: idx === openIdx ? "var(--accent-soft)" : "transparent",
                      borderLeft: idx === openIdx ? "3px solid var(--accent)" : "3px solid transparent",
                    }}>
                    <span className="mono muted" style={{fontSize: 11}}>{e.t}</span>
                    <span style={{
                      width: 22, height: 22, borderRadius: "50%",
                      background: `color-mix(in oklab, ${a.color} 22%, transparent)`,
                      color: a.color, display: "inline-flex", alignItems: "center", justifyContent: "center",
                    }}>{a.icon}</span>
                    <div style={{minWidth: 0, fontSize: 13, display: "flex", alignItems: "center", gap: 6, flexWrap: "wrap"}}>
                      <span style={{color: "var(--text-primary)"}}>{e.actor}</span>
                      <span className="muted">{a.label.toLowerCase()}</span>
                      <span className="mono" style={{fontSize: 12, color: "var(--text-secondary)"}}>{e.entity}</span>
                      <span className="muted">·</span>
                      <span className="muted ellipsis" style={{fontSize: 12, minWidth: 0}}>{e.target}</span>
                    </div>
                    <Avatar name={e.actor === "system" ? "SY" : e.actor} size="sm"/>
                  </div>
                );
              })}
            </div>
          ))}
        </div>

        <div style={{overflowY: "auto", padding: 20, background: "var(--bg-secondary)"}}>
          {open && (() => {
            const a = actionMeta(open.action);
            return (
              <div style={{display: "flex", flexDirection: "column", gap: 14}}>
                <div style={{display: "flex", alignItems: "center", gap: 12}}>
                  <span style={{
                    width: 40, height: 40, borderRadius: "50%",
                    background: `color-mix(in oklab, ${a.color} 22%, transparent)`,
                    color: a.color, display: "inline-flex", alignItems: "center", justifyContent: "center",
                  }}>{a.icon}</span>
                  <div>
                    <div style={{fontSize: 16, fontWeight: 500}}>{a.label} <span className="mono">{open.entity}</span></div>
                    <div className="muted" style={{fontSize: 12}}>{open.date} · {open.t} · {open.target}</div>
                  </div>
                </div>

                <dl className="kv" style={{gridTemplateColumns: "100px 1fr"}}>
                  <dt>Actor</dt>
                  <dd style={{display:"flex", alignItems:"center", gap: 8}}>
                    <Avatar name={open.actor === "system" ? "SY" : open.actor} size="sm"/>
                    {open.actor} <span className="muted">· {open.role}</span>
                  </dd>
                  <dt>Action</dt><dd>{a.label}</dd>
                  <dt>Entity</dt><dd className="mono">{open.entity}</dd>
                  <dt>Timestamp</dt><dd className="mono">{open.date}, {open.t} ICT</dd>
                  <dt>IP</dt><dd className="mono">{open.ip}</dd>
                  <dt>Session</dt><dd className="mono">sess_8f2a91e3</dd>
                </dl>

                {(open.before || open.after) && (
                  <div>
                    <div style={{fontSize: 11, textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--text-tertiary)", marginBottom: 8}}>State change</div>
                    <div style={{
                      display: "grid",
                      gridTemplateColumns: "1fr 24px 1fr",
                      gap: 8,
                      alignItems: "center",
                    }}>
                      <div style={{
                        padding: 10,
                        borderRadius: "var(--radius-md)",
                        border: "1px solid var(--border-subtle)",
                        fontFamily: "var(--font-mono)",
                        fontSize: 12,
                        color: "var(--text-tertiary)",
                        background: "var(--bg-primary)",
                        textDecoration: open.before ? "line-through" : "none",
                      }}>
                        {open.before || <span className="muted" style={{fontStyle: "italic", textDecoration: "none"}}>(none)</span>}
                      </div>
                      <div style={{textAlign: "center", color: "var(--text-tertiary)"}}><IconArrow size={14}/></div>
                      <div style={{
                        padding: 10,
                        borderRadius: "var(--radius-md)",
                        border: "1px solid var(--accent)",
                        background: "var(--accent-soft)",
                        fontFamily: "var(--font-mono)",
                        fontSize: 12,
                        color: "var(--text-primary)",
                      }}>
                        {open.after || <span className="muted" style={{fontStyle: "italic"}}>(none)</span>}
                      </div>
                    </div>
                  </div>
                )}

                <div>
                  <div style={{fontSize: 11, textTransform: "uppercase", letterSpacing: "0.08em", color: "var(--text-tertiary)", marginBottom: 8}}>Note</div>
                  <div style={{
                    padding: 12, borderRadius: "var(--radius-md)",
                    background: "var(--bg-primary)",
                    border: "1px solid var(--border-subtle)",
                    fontSize: 13, lineHeight: 1.5, color: "var(--text-secondary)",
                  }}>{open.note}</div>
                </div>

                <div className="hr"></div>

                <div style={{display: "flex", gap: 8}}>
                  <button className="btn btn-secondary btn-sm">Open {open.entity}</button>
                  <button className="btn btn-ghost btn-sm">Reverse action</button>
                  <button className="btn btn-ghost btn-sm" style={{marginLeft: "auto"}}>Copy event ID</button>
                </div>
              </div>
            );
          })()}
        </div>
      </div>
    </div>
  );
}

/* ============================================================
   SCREEN — REPORTS
   ============================================================ */
function ScreenReports() {
  const monthly = [
    {l:"Jun", v: 1200000},
    {l:"Jul", v: 1480000},
    {l:"Aug", v: 1620000},
    {l:"Sep", v: 1340000},
    {l:"Oct", v: 1820000},
    {l:"Nov", v: 2010000},
    {l:"Dec", v: 2240000},
    {l:"Jan", v: 1980000},
    {l:"Feb", v: 2180000},
    {l:"Mar", v: 2640000},
    {l:"Apr", v: 2810000},
    {l:"May", v: 3120000},
  ];

  const byCategory = CATEGORIES.map(c => {
    const s = SUPPLIERS.filter(s => s.cat === c.id).reduce((a,b) => a+b.spend, 0);
    return { l: c.label, v: s, color: c.color };
  }).filter(d => d.v > 0).sort((a,b) => b.v - a.v);

  const topVendors = [...SUPPLIERS].sort((a,b) => b.spend - a.spend).slice(0, 6);

  return (
    <div className="page">
      <div className="page-header">
        <div className="page-title-group">
          <h1>Reports</h1>
          <div className="sub">Spend, payment cycle &amp; supplier performance · MotionReach × Brandstorm consolidated</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-secondary btn-sm"><IconCal size={14}/> Last 12 months</button>
          <button className="btn btn-secondary btn-sm">Filter: Both brands</button>
          <button className="btn btn-secondary btn-sm"><IconDownload size={14}/> Export PDF</button>
          <button className="btn btn-primary btn-sm"><IconPlus size={14}/> Save view</button>
        </div>
      </div>

      <div className="stat-row" style={{gridTemplateColumns: "repeat(5, 1fr)"}}>
        <div className="stat-tile">
          <div className="label">Total spend YTD</div>
          <div className="val tnum">฿24.6M</div>
          <div className="delta">+18% vs prior period</div>
        </div>
        <div className="stat-tile">
          <div className="label">Active vendors</div>
          <div className="val tnum">142</div>
          <div className="delta">+12 this quarter</div>
        </div>
        <div className="stat-tile">
          <div className="label">Avg days to pay</div>
          <div className="val tnum">3.4<span style={{fontSize:18, color:"var(--text-tertiary)"}}>d</span></div>
          <div className="delta">Faster than NET 30</div>
        </div>
        <div className="stat-tile">
          <div className="label">Approval SLA</div>
          <div className="val tnum">94<span style={{fontSize:18, color:"var(--text-tertiary)"}}>%</span></div>
          <div className="delta">Within 24h target</div>
        </div>
        <div className="stat-tile">
          <div className="label">Dispute rate</div>
          <div className="val tnum">2.1<span style={{fontSize:18, color:"var(--text-tertiary)"}}>%</span></div>
          <div className="delta down">+0.3pt vs prior</div>
        </div>
      </div>

      <div style={{padding: "0 24px 24px", display: "grid", gridTemplateColumns: "2fr 1fr", gap: 16}}>
        <div className="section">
          <div className="section-head">
            <h3>Monthly spend</h3>
            <div style={{display: "flex", gap: 8, alignItems: "center"}}>
              <span className="muted" style={{fontSize: 11}}>Trailing 12 months · THB</span>
              <button className="btn btn-ghost btn-sm">Bar</button>
              <button className="btn btn-secondary btn-sm">Area</button>
            </div>
          </div>
          <div className="section-body" style={{paddingTop: 8}}>
            <AreaChart data={monthly} height={200}/>
            <div style={{display: "flex", justifyContent: "space-between", marginTop: 12, fontSize: 12}}>
              <div>
                <div className="muted" style={{fontSize: 11}}>This month (run rate)</div>
                <div className="tnum" style={{fontSize: 20, fontWeight: 500, color: "var(--text-accent)"}}>{fmtTHB(3120000)}</div>
              </div>
              <div>
                <div className="muted" style={{fontSize: 11}}>vs prior month</div>
                <div className="tnum" style={{fontSize: 14, color: "var(--success)", fontFamily: "var(--font-mono)"}}>+11.0%</div>
              </div>
              <div>
                <div className="muted" style={{fontSize: 11}}>Peak month</div>
                <div className="tnum" style={{fontSize: 14, fontFamily: "var(--font-mono)"}}>May · {fmtTHB(3120000)}</div>
              </div>
              <div>
                <div className="muted" style={{fontSize: 11}}>Forecast Jun</div>
                <div className="tnum" style={{fontSize: 14, fontFamily: "var(--font-mono)"}}>{fmtTHB(3340000)}</div>
              </div>
            </div>
          </div>
        </div>

        <div className="section">
          <div className="section-head"><h3>Spend by category</h3>
            <button className="btn btn-ghost btn-sm">Year</button>
          </div>
          <div className="section-body" style={{display: "flex", gap: 18, alignItems: "center"}}>
            <DonutChart data={byCategory}/>
            <div style={{display: "flex", flexDirection: "column", gap: 8, minWidth: 0, flex: 1}}>
              {byCategory.slice(0, 6).map(d => {
                const total = byCategory.reduce((a, b) => a + b.v, 0);
                return (
                  <div key={d.l} style={{display: "flex", alignItems: "center", gap: 8, fontSize: 12}}>
                    <span style={{width: 8, height: 8, borderRadius: 2, background: d.color, flexShrink: 0}}></span>
                    <span className="ellipsis" style={{flex: 1, minWidth: 0}}>{d.l}</span>
                    <span className="tnum mono muted" style={{fontSize: 11}}>{Math.round(d.v / total * 100)}%</span>
                  </div>
                );
              })}
            </div>
          </div>
        </div>

        <div className="section">
          <div className="section-head"><h3>Top vendors by spend</h3>
            <button className="btn btn-ghost btn-sm">View all</button>
          </div>
          <div className="section-body" style={{padding: 0}}>
            <table className="tbl" style={{tableLayout: "auto"}}>
              <thead>
                <tr>
                  <th>Vendor</th>
                  <th>Category</th>
                  <th>Trend</th>
                  <th className="right">Spend YTD</th>
                  <th className="right">Share</th>
                </tr>
              </thead>
              <tbody>
                {topVendors.map((v, i) => {
                  const sparkData = Array.from({length: 12}, (_, j) =>
                    Math.round((v.spend / 12) * (0.6 + Math.random() * 0.8 + j * 0.04))
                  );
                  const total = topVendors.reduce((a,b) => a+b.spend, 0);
                  return (
                    <tr key={v.id}>
                      <td>
                        <div style={{display:"flex", alignItems:"center", gap: 10}}>
                          <span style={{
                            width: 22, height: 22, borderRadius: 4,
                            display: "inline-flex", alignItems: "center", justifyContent: "center",
                            background: "var(--interactive-secondary)",
                            fontFamily: "var(--font-mono)", fontSize: 10, color: "var(--text-tertiary)",
                          }}>#{i+1}</span>
                          {v.name}
                        </div>
                      </td>
                      <td><CategoryTag id={v.cat}/></td>
                      <td><MiniSpark data={sparkData} color="var(--accent)"/></td>
                      <td className="num right tnum">{fmtTHB(v.spend)}</td>
                      <td className="num right muted">{Math.round(v.spend / total * 100)}%</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>

        <div className="section">
          <div className="section-head"><h3>Payment cycle time</h3>
            <span className="muted" style={{fontSize: 11}}>Days from invoice submission to paid</span>
          </div>
          <div className="section-body">
            <BarChart accentIndex={5} data={[
              {l:"PM",  v: 0.8},
              {l:"Fin", v: 1.2},
              {l:"Apr", v: 0.4},
              {l:"Sch", v: 0.6},
              {l:"Pay", v: 0.4},
              {l:"Avg", v: 3.4},
            ]}/>
            <div style={{display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 12, marginTop: 16, fontSize: 12}}>
              <div>
                <div className="muted" style={{fontSize: 11}}>Fastest stage</div>
                <div className="tnum" style={{fontSize: 14, fontFamily: "var(--font-mono)"}}>Approval · 0.4d</div>
              </div>
              <div>
                <div className="muted" style={{fontSize: 11}}>Slowest stage</div>
                <div className="tnum" style={{fontSize: 14, fontFamily: "var(--font-mono)", color: "var(--warning)"}}>Finance · 1.2d</div>
              </div>
              <div>
                <div className="muted" style={{fontSize: 11}}>vs target</div>
                <div className="tnum" style={{fontSize: 14, fontFamily: "var(--font-mono)", color: "var(--success)"}}>-26.6%</div>
              </div>
            </div>
          </div>
        </div>

        <div className="section" style={{gridColumn: "1 / -1"}}>
          <div className="section-head"><h3>Performance — by category</h3>
            <button className="btn btn-ghost btn-sm">Configure benchmarks</button>
          </div>
          <table className="tbl" style={{tableLayout: "auto"}}>
            <thead>
              <tr>
                <th>Category</th>
                <th className="right">Vendors</th>
                <th className="right">Spend YTD</th>
                <th className="right">Avg quality</th>
                <th className="right">On-time %</th>
                <th className="right">Avg cycle (d)</th>
                <th className="right">Dispute rate</th>
                <th className="right">YoY</th>
              </tr>
            </thead>
            <tbody>
              {CATEGORIES.slice(0, 8).map((c, i) => {
                const s = SUPPLIERS.filter(s => s.cat === c.id);
                const spend = s.reduce((a,b) => a+b.spend, 0);
                const avgRating = s.length ? (s.reduce((a,b) => a+b.rating, 0) / s.length).toFixed(1) : "—";
                const onTime = 85 + (i * 3) % 12;
                const cycle = (2.4 + (i * 0.4) % 3.2).toFixed(1);
                const dispute = (0.8 + (i * 0.6) % 4).toFixed(1);
                const yoy = (i % 3 === 0 ? "-" : "+") + ((i * 7) % 24 + 2) + "%";
                return (
                  <tr key={c.id}>
                    <td><CategoryTag id={c.id}/></td>
                    <td className="num right tnum">{s.length || "—"}</td>
                    <td className="num right tnum">{spend ? fmtTHB(spend) : "—"}</td>
                    <td className="right tnum mono">{avgRating}</td>
                    <td className="right tnum mono" style={{color: onTime > 90 ? "var(--success)" : "var(--text-secondary)"}}>{onTime}%</td>
                    <td className="right tnum mono">{cycle}</td>
                    <td className="right tnum mono" style={{color: parseFloat(dispute) > 3 ? "var(--warning)" : "var(--text-secondary)"}}>{dispute}%</td>
                    <td className="right tnum mono" style={{color: yoy.startsWith("+") ? "var(--success)" : "var(--danger)"}}>{yoy}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ScreenCompliance, ScreenAudit, ScreenReports });
