// ============ AUDIT LOG ============
// Global audit trail — owner/admin only.
// Merges: approvals, learnings, conversation lifecycle, team changes.

const { useState, useEffect, useCallback, useRef } = React;

// ── Event type config ──────────────────────────────────────────────────────────
const EVENT_TYPES = [
  { id: "",                    label: "All events" },
  { id: "approval",           label: "Approvals" },
  { id: "learning",           label: "Rules" },
  { id: "conversation",       label: "Conversations" },
  { id: "team",               label: "Team" },
  { id: "agent",              label: "Agents" },
  { id: "knowledge",          label: "Playbooks" },
  { id: "persona_run",        label: "Training" },
  { id: "destructive_action", label: "Destructive" },
  { id: "authorization",      label: "Authorization" },
  { id: "other",              label: "Other" },
];

function typeIcon(type) {
  switch (type) {
    case "approval":          return "✓";
    case "learning":          return "◎";
    case "conversation":      return "◷";
    case "team":              return "◈";
    case "agent":             return "◉";
    case "knowledge":         return "◻";
    case "persona_run":       return "▷";
    case "destructive_action": return "!";
    case "authorization":     return "⊛";
    default:                  return "·";
  }
}

function typeColor(type) {
  switch (type) {
    case "approval":          return "#2DAF6B";
    case "learning":          return "var(--accent)";
    case "conversation":      return "#0EA5E9";
    case "team":              return "#8B5CF6";
    case "agent":             return "#F59E0B";
    case "knowledge":         return "#06B6D4";
    case "persona_run":       return "#D97706";
    case "destructive_action": return "#C04545";
    case "authorization":     return "#6B7280";
    default:                  return "var(--ink-3)";
  }
}

function subtypeLabel(subtype) {
  const m = {
    "approval.approved":  "Approved",
    "approval.rejected":  "Rejected",
    "wrapup":             "Ended",
    "lead":               "Started",
    "learning":           "Learning",
    "learning_proposed":  "Proposed",
    "persona_run":        "Training",
    "destructive_action": "Destructive",
    "authorization":      "Auth",
    "team_audit":         "Team",
  };
  return m[subtype] || subtype || "";
}

// ── Event row ─────────────────────────────────────────────────────────────────
function AuditEventRow({ event, byId }) {
  const [open, setOpen] = useState(false);
  const color = typeColor(event.type);
  const icon  = typeIcon(event.type);
  const agent = event.agentName || (event.agentId && byId[event.agentId]?.name) || null;

  const ts = event.ts ? new Date(event.ts) : null;
  const timeStr = ts
    ? ts.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" })
    : "";

  const hasMeta = event.metadata && Object.keys(event.metadata).length > 0;

  return (
    <div
      className="al-row"
      onClick={() => hasMeta && setOpen((v) => !v)}
      style={{ cursor: hasMeta ? "pointer" : "default" }}
    >
      <div className="al-row-icon" style={{ background: `color-mix(in oklab, ${color} 15%, transparent)`, color }}>
        {icon}
      </div>
      <div className="al-row-body">
        <div className="al-row-desc">{event.description}</div>
        <div className="al-row-meta">
          {event.actor && event.actor !== "system" && <span className="al-meta-actor">{event.actor}</span>}
          {event.actor === "system" && <span className="al-meta-actor" style={{ color: "var(--ink-3)" }}>system</span>}
          {event.actorRole && event.actorRole !== "system" && event.actorRole !== "agent" && (
            <span className="al-meta-sub" style={{ fontSize: 10, opacity: 0.7 }}>{event.actorRole}</span>
          )}
          {agent && agent !== event.actor && <span className="al-meta-agent">{agent}</span>}
          <span className="al-meta-sub">{subtypeLabel(event.subtype)}</span>
        </div>
        {open && hasMeta && (
          <pre className="al-meta-json">{JSON.stringify(event.metadata, null, 2)}</pre>
        )}
      </div>
      <div className="al-row-time">{timeStr}</div>
    </div>
  );
}

// ── Day group ─────────────────────────────────────────────────────────────────
function dayLabel(iso) {
  const d = new Date(iso);
  const today = new Date();
  const yest  = new Date(today); yest.setDate(yest.getDate() - 1);
  const sameDay = (a, b) =>
    a.getFullYear() === b.getFullYear() &&
    a.getMonth()    === b.getMonth()    &&
    a.getDate()     === b.getDate();
  if (sameDay(d, today)) return "Today";
  if (sameDay(d, yest))  return "Yesterday";
  return d.toLocaleDateString([], { weekday: "long", month: "short", day: "numeric" });
}

// ── Main component ─────────────────────────────────────────────────────────────
function AuditLogTab({ authUser, agents = [] }) {
  const [events,      setEvents     ] = useState([]);
  const [loading,     setLoading    ] = useState(true);
  const [error,       setError      ] = useState(null);
  const [typeFilter,  setTypeFilter ] = useState("");
  const [agentFilter, setAgentFilter] = useState("");
  const [actorFilter, setActorFilter] = useState("");
  const [fromDate,    setFromDate   ] = useState("");
  const [toDate,      setToDate     ] = useState("");
  const [exporting,   setExporting  ] = useState(false);

  const role = authUser?.role || "member";
  const canView = ["Owner", "Admin", "MasterAdmin"].includes(role);

  const byId = React.useMemo(() => {
    const m = {};
    for (const a of agents) m[a.id] = a;
    return m;
  }, [agents]);

  const buildQs = useCallback((extra = {}) => {
    const p = new URLSearchParams();
    const t = extra.type  !== undefined ? extra.type  : typeFilter;
    const a = extra.agent !== undefined ? extra.agent : agentFilter;
    const u = extra.actor !== undefined ? extra.actor : actorFilter;
    const f = extra.from  !== undefined ? extra.from  : fromDate;
    const o = extra.to    !== undefined ? extra.to    : toDate;
    if (t) p.set("type", t);
    if (a) p.set("agentId", a);
    if (u) p.set("actorId", u);
    if (f) p.set("from", new Date(f).toISOString());
    if (o) p.set("to",   new Date(o + "T23:59:59").toISOString());
    if (extra.export) p.set("export", "csv");
    p.set("limit", "500");
    return p.toString() ? `?${p.toString()}` : "";
  }, [typeFilter, agentFilter, actorFilter, fromDate, toDate]);

  const load = useCallback(() => {
    if (!canView) return;
    setLoading(true);
    setError(null);
    fetch(`/audit-log${buildQs()}`)
      .then((r) => r.ok ? r.json() : Promise.reject(r.status))
      .then((data) => { setEvents(Array.isArray(data) ? data : []); setLoading(false); })
      .catch((e) => { setError("Failed to load audit log."); setLoading(false); });
  }, [canView, buildQs]);

  useEffect(() => { load(); }, [typeFilter, agentFilter, actorFilter, fromDate, toDate]);

  const handleExport = () => {
    setExporting(true);
    const url = `/audit-log${buildQs({ export: true })}`;
    const a = document.createElement("a");
    a.href = url;
    a.download = `citrus-audit-log-${new Date().toISOString().slice(0, 10)}.csv`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    setTimeout(() => setExporting(false), 1500);
  };

  if (!canView) {
    return (
      <div style={{ padding: "48px 32px", maxWidth: 480, margin: "0 auto", textAlign: "center" }}>
        <div style={{ fontSize: 32, marginBottom: 12, opacity: 0.4 }}>◎</div>
        <h2 style={{ fontSize: 16, fontWeight: 600, margin: "0 0 8px", color: "var(--ink)" }}>Access restricted</h2>
        <p style={{ fontSize: 13, color: "var(--ink-2)", lineHeight: 1.6 }}>
          The audit log is only available to owners and admins.
        </p>
      </div>
    );
  }

  // Group events by day
  const grouped = [];
  let lastDay = null;
  for (const e of events) {
    const day = e.ts ? dayLabel(e.ts) : "Unknown date";
    if (day !== lastDay) {
      grouped.push({ type: "day", label: day });
      lastDay = day;
    }
    grouped.push({ type: "event", event: e });
  }

  return (
    <div className="al-root">
      {/* ── Filter bar ── */}
      <div className="al-toolbar">
        <div className="al-filters">
          <select
            className="al-select"
            value={typeFilter}
            onChange={(e) => setTypeFilter(e.target.value)}
          >
            {EVENT_TYPES.map((t) => (
              <option key={t.id} value={t.id}>{t.label}</option>
            ))}
          </select>

          <select
            className="al-select"
            value={agentFilter}
            onChange={(e) => setAgentFilter(e.target.value)}
          >
            <option value="">All agents</option>
            {agents.map((a) => (
              <option key={a.id} value={a.id}>{a.name}</option>
            ))}
          </select>

          <input
            type="date"
            className="al-date"
            value={fromDate}
            onChange={(e) => setFromDate(e.target.value)}
            placeholder="From"
          />
          <input
            type="date"
            className="al-date"
            value={toDate}
            onChange={(e) => setToDate(e.target.value)}
            placeholder="To"
          />

          <input
            type="text"
            className="al-date"
            value={actorFilter}
            onChange={(e) => setActorFilter(e.target.value)}
            placeholder="Filter by actor email"
            style={{ minWidth: 160 }}
          />

          {(typeFilter || agentFilter || actorFilter || fromDate || toDate) && (
            <button
              className="btn btn-ghost btn-sm"
              onClick={() => { setTypeFilter(""); setAgentFilter(""); setActorFilter(""); setFromDate(""); setToDate(""); }}
            >
              Clear
            </button>
          )}
        </div>

        <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
          {!loading && !error && (
            <span className="al-count">{events.length} event{events.length !== 1 ? "s" : ""}</span>
          )}
          <button
            className="btn btn-ghost btn-sm"
            onClick={handleExport}
            disabled={exporting || loading}
            title="Download as CSV"
          >
            {exporting ? "Exporting…" : "Export CSV"}
          </button>
          <button className="btn btn-ghost btn-sm" onClick={load} disabled={loading}>
            {loading ? "Loading…" : "Refresh"}
          </button>
        </div>
      </div>

      {/* ── Event list ── */}
      <div className="al-list">
        {loading && (
          <div className="al-empty">Loading audit log…</div>
        )}
        {!loading && error && (
          <div className="al-empty al-empty--error">{error}</div>
        )}
        {!loading && !error && events.length === 0 && (
          <div className="al-empty">No events found for the selected filters.</div>
        )}
        {!loading && !error && grouped.map((item, i) => {
          if (item.type === "day") {
            return (
              <div key={`day-${i}`} className="al-day-label">{item.label}</div>
            );
          }
          return (
            <AuditEventRow key={`${item.event.ts}-${i}`} event={item.event} byId={byId} />
          );
        })}
      </div>
    </div>
  );
}

window.AuditLogTab = AuditLogTab;
