// Control Room: Operations + Activity & data trust (+ small Settings).
// v2: lock-fleet rows carry the property photo and open the listing, headers sort,
// the no-show report closes its loops (listing + recruiting links), and the audit
// log makes every actor and property a link to its entity.
;(function(){
const DS = window.DoorpassDesignSystem_eaad52;
const { Button, Badge, Card, ListRow, IconTile, Toggle } = DS;
const D = window.CRData;
const { CRIcon, CRPage, CRChip, CRCard, CRTh, CRRow, CRLink, CRPhoto, CRFilterPill,
        useCRSort, crSorted, crMono } = window;

/* ============ 07 · Operations ============ */

function BatteryPill({ pct }) {
  const tone = pct <= 20 ? "var(--red-600)" : pct <= 40 ? "var(--amber-700)" : "var(--green-600)";
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 7 }}>
      <span aria-hidden="true" style={{ width: 34, height: 8, borderRadius: 4, background: "var(--mist-100)", overflow: "hidden", display: "inline-block" }}>
        <span style={{ display: "block", height: "100%", width: `${pct}%`, background: tone, borderRadius: 4 }}></span>
      </span>
      <span style={crMono(12, tone)}>{pct}%</span>
    </span>
  );
}

function ConnBadge({ conn }) {
  if (conn === "ok") return <Badge tone="live" dot>Online</Badge>;
  if (conn === "weak") return <Badge tone="scheduled" dot>Weak signal</Badge>;
  return <Badge tone="neutral" dot>Unpaired</Badge>;
}

const OCOLS = "minmax(160px,1.25fr) 116px 100px 108px 122px 112px 150px";
const TONE_RANK = { bad: 0, warn: 1, good: 2 };
const OSORT = {
  addr: (l) => D.listing(l.listing).addr, device: (l) => l.device, battery: (l) => l.battery,
  tone: (l) => TONE_RANK[l.tone], checkin: (l) => l.checkin,
};

function CROperations({ go }) {
  const [sort, onSort] = useCRSort("tone", "asc");
  const rows = crSorted(D.locks, sort, OSORT);
  const maxPreset = Math.max(...D.rulePresets.map((p) => p.listings));
  return (
    <CRPage
      label="07 Operations"
      eyebrow="14 locks · Brooks Group fleet"
      title="Operations"
      sub="Hardware health paired with its consequence — the next showing it could block."
      actions={<Button variant="secondary" size="sm" leadingIcon={<CRIcon name="life-buoy" size={14} />}>Support</Button>}
    >
      <CRCard title="Lock fleet" hint={sort.key === "tone" ? "issues sorted first" : `sorted by ${sort.key}`} pad={10} style={{ marginBottom: 16 }}>
        <CRTh cols={OCOLS}
          labels={["Property", "Device", "Battery", "Connectivity", "Last check-in", "Next showing", ""]}
          aligns={["left", "left", "left", "left", "left", "left", "left"]}
          keys={["addr", "device", "battery", "tone", "checkin", null, null]}
          defs={[null, null, "battery", null, null, null, null]}
          sort={sort} onSort={onSort} />
        {rows.map((l, i) => {
          const lst = D.listing(l.listing);
          return (
            <CRRow key={l.listing} cols={OCOLS} last={i === rows.length - 1} onClick={() => go("listing", l.listing)} ariaLabel={`${lst.addr} — open listing detail`}>
              <span style={{ display: "flex", alignItems: "center", gap: 10, minWidth: 0 }}>
                <CRPhoto listing={lst} w={30} h={24} radius={6} />
                <span style={{ fontSize: 13, fontWeight: 700, color: "var(--green-950)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{lst.addr}</span>
              </span>
              <span style={{ fontSize: 12, fontWeight: 500, color: "var(--neutral-500)" }}>{l.device}</span>
              <span><BatteryPill pct={l.battery} /></span>
              <span><ConnBadge conn={l.conn} /></span>
              <span style={crMono(11.5, "var(--neutral-700)", 500)}>{l.checkin}</span>
              <span style={crMono(11.5, l.tone === "bad" ? "var(--red-600)" : "var(--neutral-700)", l.tone === "bad" ? 600 : 500)}>{l.next}</span>
              <span>{l.action
                ? <Button variant={l.tone === "bad" ? "primary" : "secondary"} size="sm" onClick={(e) => e.stopPropagation()}>{l.action}</Button>
                : <span style={{ fontSize: 11.5, fontWeight: 500, color: "var(--neutral-300)" }}>Healthy</span>}</span>
            </CRRow>
          );
        })}
      </CRCard>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
        <CRCard title="No-show report" info="noshow" hint="last 30 days · from verified entries" pad={10}>
          <CRTh cols="1.3fr 1fr 60px 60px" labels={["Listing", "Who", "Count", "Rate"]} aligns={["left", "left", "right", "right"]} />
          {D.noshows.map((n, i) => {
            const lst = D.listing(n.listing);
            return (
              <CRRow key={n.listing} cols="1.3fr 1fr 60px 60px" last={i === D.noshows.length - 1} onClick={() => go("listing", n.listing)} ariaLabel={`${lst.addr} — open listing detail`}>
                <span style={{ display: "flex", alignItems: "center", gap: 9, minWidth: 0 }}>
                  <CRPhoto listing={lst} w={28} h={22} radius={6} />
                  <span style={{ fontSize: 12.5, fontWeight: 700, color: "var(--green-950)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{lst.addr}</span>
                </span>
                <span style={{ fontSize: 12, fontWeight: 500, color: "var(--neutral-500)" }}>{n.agent}</span>
                <span style={{ ...crMono(12.5), textAlign: "right" }}>{n.count}</span>
                <span style={{ ...crMono(12.5, "var(--red-600)"), textAlign: "right" }}>{n.rate}</span>
              </CRRow>
            );
          })}
          <div style={{ padding: "10px 12px 4px", fontSize: 12, fontWeight: 500, color: "var(--neutral-700)" }}>
            A confirmed pass with no verified entry within the window counts as a no-show. Repeat offenders are flagged on the
            <CRLink onClick={() => go("recruiting")} size={12} weight={700} color="var(--green-800)"> recruiting screen</CRLink>.
          </div>
        </CRCard>

        <CRCard title="Rules performance" hint="preset · median approval time">
          <span className="sr-only">Open windows: 6 listings, 4 minute median. Approve each: 5 listings, 37 minutes. Owner confirms: 3 listings, 2.1 hours.</span>
          <div aria-hidden="true" style={{ display: "flex", flexDirection: "column", gap: 12 }}>
            {D.rulePresets.map((p) => (
              <div key={p.name} style={{ display: "grid", gridTemplateColumns: "118px 1fr 70px", gap: 10, alignItems: "center" }}>
                <span style={{ fontSize: 12.5, fontWeight: 600, color: "var(--neutral-700)" }}>{p.name}</span>
                <span style={{ height: 8, borderRadius: 4, background: "var(--mist-100)", overflow: "hidden", display: "block" }}>
                  <span style={{ display: "block", height: "100%", width: `${(p.listings / maxPreset) * 100}%`, background: p.best ? "var(--green-600)" : "var(--neutral-300)", borderRadius: 4 }}></span>
                </span>
                <span style={{ ...crMono(12, p.best ? "var(--green-800)" : "var(--neutral-700)"), textAlign: "right" }}>{p.median}</span>
              </div>
            ))}
          </div>
          <div style={{
            marginTop: 14, padding: "11px 13px", borderRadius: "var(--radius-sm)",
            background: "var(--surface-tint)", boxShadow: "inset 0 0 0 1px var(--green-300)",
            fontSize: 12.5, fontWeight: 600, color: "var(--green-900)", lineHeight: "17px",
          }}>
            Open-windows listings confirm 9× faster than owner-confirmed ones. 3 listings are candidates to switch.
          </div>
        </CRCard>
      </div>
    </CRPage>
  );
}

/* ============ 08 · Activity & data trust ============ */

const EVENT_META = {
  entry:        { icon: "door-open",   color: "var(--green-600)" },
  exit:         { icon: "door-closed", color: "var(--green-600)" },
  approval:     { icon: "check",       color: "var(--blue-500)" },
  request:      { icon: "inbox",       color: "var(--blue-500)" },
  decline:      { icon: "ban",         color: "var(--amber-700)" },
  pass:         { icon: "ticket",      color: "var(--blue-500)" },
  revoke:       { icon: "shield-x",    color: "var(--red-600)" },
  telemetry:    { icon: "cpu",         color: "var(--neutral-500)" },
  intelligence: { icon: "sparkle",     color: "var(--green-800)" },
};

function ConstitutionRule({ icon, title, body }) {
  return (
    <div style={{ display: "flex", gap: 11, alignItems: "flex-start", flex: 1, minWidth: 0 }}>
      <span style={{ width: 30, height: 30, borderRadius: 8, background: "rgba(255,255,255,0.10)", display: "grid", placeItems: "center", flex: "none" }}>
        <CRIcon name={icon} size={15} color="var(--green-300)" />
      </span>
      <span style={{ minWidth: 0 }}>
        <span style={{ display: "block", fontSize: 13, fontWeight: 700, color: "#fff" }}>{title}</span>
        <span style={{ display: "block", fontSize: 12, fontWeight: 500, color: "var(--green-300)", marginTop: 2, lineHeight: "16px" }}>{body}</span>
      </span>
    </div>
  );
}

// Actor → its entity: agents to Team, buyers to Recruiting, locks to Operations.
function AuditActor({ actor, go }) {
  const dest = actor.kind === "agent" ? () => go("team") : actor.kind === "buyer" ? () => go("recruiting") : actor.kind === "lock" ? () => go("operations") : null;
  return (
    <span style={{ display: "flex", alignItems: "baseline", gap: 6, minWidth: 0 }}>
      {dest
        ? <CRLink onClick={dest}>{actor.label}</CRLink>
        : <span style={{ fontSize: 12.5, fontWeight: 700, color: "var(--green-950)" }}>{actor.label}</span>}
      {actor.sub && <span style={{ fontSize: 11, fontWeight: 500, color: "var(--neutral-500)", whiteSpace: "nowrap" }}>{actor.sub}</span>}
    </span>
  );
}

function CRActivity({ go, initial }) {
  const [filter, setFilter] = React.useState((initial && initial.filter) || "all");
  const TYPES = ["entry", "approval", "request", "decline", "revoke", "telemetry", "intelligence"];
  const rows = D.audit.filter((e) => filter === "all" || e.type === filter || (filter === "entry" && e.type === "exit"));
  return (
    <CRPage
      label="08 Activity & trust"
      eyebrow="Immutable ledger · Brooks Group"
      title="Activity"
      sub="Every event your account produced — and the rules governing how it's used."
      actions={<Button variant="secondary" size="sm" leadingIcon={<CRIcon name="download" size={14} />}>Export CSV</Button>}
    >
      <section style={{
        background: "var(--green-900)", borderRadius: "var(--radius-lg)",
        padding: "20px 22px", marginBottom: 16, boxShadow: "var(--shadow-raised)",
      }}>
        <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 14 }}>
          <CRIcon name="shield-check" size={17} color="#fff" />
          <span style={{ fontSize: 15, fontWeight: 800, color: "#fff", letterSpacing: "-0.005em" }}>How your data is used</span>
          <span style={{ flex: 1 }}></span>
          <span style={{ fontFamily: "var(--font-mono)", fontSize: 10.5, fontWeight: 500, letterSpacing: "0.08em", color: "var(--green-300)", textTransform: "uppercase", whiteSpace: "nowrap" }}>Data constitution · v2</span>
        </div>
        <div style={{ display: "flex", gap: 22 }}>
          <ConstitutionRule icon="ban" title="Never sold" body="Your event data is never sold, rented, or shared with advertisers." />
          <ConstitutionRule icon="user-x" title="Never turned against you" body="Never used for lead generation that competes with your business." />
          <ConstitutionRule icon="eye-off" title="Identity only where earned" body="Buyer-agent names appear only where they transacted with your listings. Everywhere else: aggregates." />
          <ConstitutionRule icon="file-check" title="Consent-labeled feedback" body="Showing feedback stays labeled with the consent it was given under." />
        </div>
      </section>

      <CRCard
        title="Audit log"
        hint="append-only · all time — deviates from global period"
        pad={10}
        action={
          <div style={{ display: "flex", gap: 5 }}>
            <CRFilterPill on={filter === "all"} label="All" onClick={() => setFilter("all")} />
            {TYPES.map((t) => (
              <button key={t} className={"cr-ia cr-pill" + (filter === t ? " cr-pill-on" : "")} onClick={() => setFilter(t)} aria-pressed={filter === t} style={{
                padding: "3px 10px", borderRadius: "var(--radius-pill)", cursor: "pointer", border: "none",
                fontFamily: "var(--font-sans)", fontSize: 11.5, fontWeight: 700, textTransform: "capitalize",
                background: filter === t ? "var(--green-800)" : "var(--mist-100)",
                color: filter === t ? "#fff" : "var(--neutral-700)",
                display: "inline-flex", alignItems: "center", gap: 5,
              }}>{t}{filter === t && <CRIcon name="x" size={10} color="rgba(255,255,255,0.75)" />}</button>
            ))}
          </div>
        }
      >
        <CRTh cols="170px 30px 200px 200px 1fr" labels={["Timestamp", "", "Actor", "Property", "Event"]} aligns={["left", "left", "left", "left", "left"]} />
        {rows.map((e, i) => {
          const m = EVENT_META[e.type] || EVENT_META.telemetry;
          const lst = e.listing ? D.listing(e.listing) : null;
          // Ledger anatomy: event (sans, ink) · detail (mono, muted) — split at the first ·
          const dot = e.action.indexOf(" · ");
          const evt = dot > -1 ? e.action.slice(0, dot) : e.action;
          const det = dot > -1 ? e.action.slice(dot + 3) : null;
          const isPass = e.type === "pass";
          return (
            <CRRow key={i} cols="170px 30px 200px 200px 1fr" last={i === rows.length - 1}>
              <span style={crMono(11.5, "var(--neutral-700)", 500)}>{e.ts}</span>
              <CRIcon name={m.icon} size={14} color={m.color} />
              <AuditActor actor={e.actor} go={go} />
              <span style={{ display: "flex", alignItems: "center", gap: 8, minWidth: 0 }}>
                {isPass && lst ? (
                  /* A pass as an entity — the row-size Pass object, desktop density */
                  <window.DoorpassDesignSystem_eaad52.PassRow dense photo={lst.img ? window.CRImgSrc(lst.img) : null} name={lst.addr} window={det} statusLabel={null} status="scheduled" onClick={() => go("listing", lst.id)} style={{ width: "100%" }} />
                ) : lst ? <>
                  <CRPhoto listing={lst} w={24} h={20} radius={5} />
                  <CRLink onClick={() => go("listing", lst.id)} size={12} weight={600} color="var(--neutral-700)">{lst.addr}</CRLink>
                </> : <span style={{ fontSize: 12, color: "var(--neutral-300)" }}>—</span>}
              </span>
              <span style={{ display: "flex", alignItems: "baseline", gap: 10, minWidth: 0, flexWrap: "wrap" }}>
                <span style={{ fontSize: 12.5, fontWeight: 600, letterSpacing: "-0.005em", color: "var(--green-900)" }}>{evt}</span>
                {det && !isPass && <span style={{ ...crMono(11.5, "var(--neutral-500)", 500), minWidth: 0 }}>{det}</span>}
              </span>
            </CRRow>
          );
        })}
      </CRCard>
    </CRPage>
  );
}

/* ============ Settings — minimal, IA completeness ============ */

function CRSettings() {
  return (
    <CRPage label="Settings" eyebrow="Brooks Group" title="Settings" sub="Account, rules, and notification defaults.">
      <div style={{ maxWidth: 560 }}>
        <Card padding={6}>
          <ListRow divider leading={<IconTile tone="green"><CRIcon name="building-2" size={16} color="var(--green-800)" /></IconTile>} title="Team profile" subtitle="Brooks Group · San Antonio, TX" chevron />
          <ListRow divider leading={<IconTile><CRIcon name="users" size={16} color="var(--neutral-700)" /></IconTile>} title="Members & roles" subtitle="5 agents · 1 ops lead · 1 principal viewer" chevron />
          <ListRow divider leading={<IconTile><CRIcon name="sliders-horizontal" size={16} color="var(--neutral-700)" /></IconTile>} title="Default showing rules" subtitle="New listings start on Approve each" chevron />
          <ListRow leading={<IconTile><CRIcon name="bell" size={16} color="var(--neutral-700)" /></IconTile>} title="Monday digest email" subtitle="Sent 7:00 AM to Salena + Levi" trailing={<Toggle defaultChecked />} />
        </Card>
      </div>
    </CRPage>
  );
}

Object.assign(window, { CROperations, CRActivity, CRSettings });
})();
