/* SkyOps — Notification center (bell) + audit log. Every confirmed action (toast) is audited with who/role/when;
   outgoing communications (reminders, invitations, deliveries) are listed as "Sent". */

const NT_KEY = "skyops_audit_v1", NT_READ = "skyops_notif_read_v1";
const ntStore = {
  log: (() => { try { return JSON.parse(localStorage.getItem(NT_KEY) || "[]"); } catch { return []; } })(),
  read: (() => { try { return JSON.parse(localStorage.getItem(NT_READ) || "{}"); } catch { return {}; } })(),
  subs: new Set(),
  emit() { this.subs.forEach(s => s({})); },
  add(e) { this.log = [e, ...this.log].slice(0, 400); try { localStorage.setItem(NT_KEY, JSON.stringify(this.log)); } catch {} this.emit(); },
  mark(ids) { ids.forEach(id => this.read[id] = 1); try { localStorage.setItem(NT_READ, JSON.stringify(this.read)); } catch {} this.emit(); },
};
const ntNow = () => { const d = new Date(); return `${window.SKY_TODAY} ${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`; };
const NT_SENT = /reminder|invitation|delivered|sent to|link copied/i;
function skyAudit(scope, text) { ntStore.add({ id: "EV-" + Date.now().toString(36) + Math.random().toString(36).slice(2, 5), at: ntNow(), who: window.__personaName || "You", role: window.skyRole ? window.skyRole() : "", scope, text, sent: NT_SENT.test(text) }); }
window.addEventListener("skyops:toast", (e) => { const t = typeof e.detail === "string" ? e.detail : e.detail?.text; if (t && !/^Not allowed/.test(t)) skyAudit((window.__inCtx && window.__inCtx.route) || "app", t); });
function useNt() { const [, f] = React.useState(0); React.useEffect(() => { const h = () => f(x => x + 1); ntStore.subs.add(h); return () => ntStore.subs.delete(h); }, []); return ntStore; }

function ntInbox() {
  const al = window.alBuild ? window.alBuild().map(a => ({ ...a, ...((window.alStore && window.alStore.v[a.id]) || {}) })).filter(a => a.status === "new" && ["critical", "high", "medium"].includes(a.sev)) : [];
  const certs = window.crIssues && window.resStore ? window.crIssues(window.resStore.data.people).filter(x => x.st === "expired" || x.st === "crit").slice(0, 6) : [];
  return [
    ...al.map(a => ({ id: a.id, sev: a.sev, title: a.title, sub: a.detail, at: a.at, go: "alerts" })),
    ...certs.map(x => ({ id: "CERT-" + x.p.id + (x.c ? x.c[0] : x.missing.label), sev: x.st === "expired" || x.st === "missing" ? "high" : "medium", title: `${x.p.name} · ${x.c ? x.c[0] : x.missing.label}`, sub: x.st === "missing" ? "Required certificate missing" : x.days < 0 ? `Expired ${x.c[1]}` : `Expires in ${x.days} days`, at: "", go: "fleet" })),
  ];
}

function NotificationBell({ go }) {
  const s = useNt();
  const [open, setOpen] = React.useState(false);
  const [tab, setTab] = React.useState("inbox");
  React.useEffect(() => { if (!open) return; const c = (e) => { if (!e.target.closest(".nt-wrap")) setOpen(false); }; const k = (e) => e.key === "Escape" && setOpen(false); document.addEventListener("mousedown", c); document.addEventListener("keydown", k); return () => { document.removeEventListener("mousedown", c); document.removeEventListener("keydown", k); }; }, [open]);
  const inbox = ntInbox();
  const unread = inbox.filter(n => !s.read[n.id]);
  const sent = s.log.filter(e => e.sent).slice(0, 30);
  const nav = (r) => { setOpen(false); go(r); };
  return <span className="tb-pop-wrap nt-wrap">
    <button className={`tb-icon-btn ${open ? "on" : ""}`} aria-label={`Notifications${unread.length ? ` · ${unread.length} unread` : ""}`} title="Notifications" onClick={() => setOpen(!open)}>
      <Icon name="bell" size={15}/>{unread.length > 0 && <span className="nt-badge">{unread.length > 9 ? "9+" : unread.length}</span>}
    </button>
    {open && <div className="tb-pop nt-pop" role="dialog" aria-label="Notifications">
      <div className="nt-hd"><b>Notifications</b><span className="grow"/>{tab === "inbox" && unread.length > 0 && <button className="btn btn-ghost btn-xs" onClick={() => s.mark(inbox.map(n => n.id))}>Mark all read</button>}</div>
      <div className="nt-tabs">{[["inbox", `Inbox${unread.length ? " · " + unread.length : ""}`], ["sent", "Sent"], ["activity", "Activity"]].map(([k, l]) => <button key={k} className={tab === k ? "on" : ""} onClick={() => setTab(k)}>{l}</button>)}</div>
      <div className="nt-list">
        {tab === "inbox" && (inbox.length ? inbox.map(n => <button key={n.id} className={`nt-it ${s.read[n.id] ? "" : "unread"}`} onClick={() => { s.mark([n.id]); nav(n.go); }}>
          <i className={`nt-sev nt-sev-${n.sev}`}/><span><b>{n.title}</b><em>{n.sub}</em></span><span className="mono nt-at">{n.at ? String(n.at).slice(5, 16) : ""}</span></button>) : <div className="nt-empty">You're all caught up.</div>)}
        {tab === "sent" && (sent.length ? sent.map(e => <div key={e.id} className="nt-it"><Icon name="send" size={11}/><span><b>{e.text}</b><em>{e.who} · {e.at}</em></span></div>) : <div className="nt-empty">No outgoing messages yet. Reminders, invitations and report deliveries appear here.</div>)}
        {tab === "activity" && (s.log.length ? s.log.slice(0, 25).map(e => <div key={e.id} className="nt-it"><Icon name="history" size={11}/><span><b>{e.text}</b><em>{e.who}{e.role ? ` (${e.role})` : ""} · {e.scope} · {e.at}</em></span></div>) : <div className="nt-empty">No activity recorded yet.</div>)}
      </div>
      <div className="nt-ft"><button className="btn btn-ghost btn-xs" onClick={() => nav("alerts")}>All alerts</button><button className="btn btn-ghost btn-xs" onClick={() => { localStorage.setItem("skyops_admin_tab", "audit"); nav("admin"); }}>Audit log</button><span className="grow"/><button className="btn btn-ghost btn-xs" onClick={() => nav("profile")}><Icon name="settings" size={11}/>Preferences</button></div>
    </div>}
  </span>;
}

function AuditLog() {
  const s = useNt();
  const [q, setQ] = React.useState("");
  const rows = s.log.filter(e => !q || (e.text + e.who + e.scope).toLowerCase().includes(q.toLowerCase()));
  const pgA = usePaged(rows, "audit", 50);
  const exp = () => { window.skyDownload(`skyops-audit-${window.SKY_TODAY}.csv`, window.skyCsv([["timestamp", "user", "role", "area", "event"], ...s.log.map(e => [e.at, e.who, e.role, e.scope, e.text])]), "text/csv"); };
  return <div className="card">
    <div className="card-hd">Audit log<span className="sub">{s.log.length} events · kept 400 most recent on this device</span>
      <div className="actions"><label className="cr-search"><Icon name="search" size={12}/><input value={q} onChange={e => setQ(e.target.value)} placeholder="Filter events"/></label><button className="btn btn-secondary btn-xs" data-perm="data.export" onClick={exp}><Icon name="download" size={11}/>Export CSV</button></div></div>
    <table className="tbl"><thead><tr><th>When</th><th>User</th><th>Role</th><th>Area</th><th>Event</th></tr></thead>
      <tbody>{pgA.rows.map(e => <tr key={e.id}><td className="mono sec" style={{ fontSize: 11, whiteSpace: "nowrap" }}>{e.at}</td><td>{e.who}</td><td className="sec">{e.role}</td><td className="sec">{e.scope}</td><td>{e.text}</td></tr>)}
        {!rows.length && <tr><td colSpan={5} className="sec" style={{ textAlign: "center", padding: 24 }}>No events yet. Actions you confirm in the app are recorded here.</td></tr>}</tbody></table><Pager pg={pgA} label="events"/>
  </div>;
}

Object.assign(window, { skyAudit, ntStore, NotificationBell, AuditLog });
