// Control Room: Overview (Monday morning) + Day-one cold start + Listings board.
// v2: every stat drills to its evidence, density gradient (primary zone dense,
// right rail recedes), live Today strip, sortable/searchable listings table with
// removable filter chips, photo-per-property, honest day-one chapter state.
;(function(){
const DS = window.DoorpassDesignSystem_eaad52;
const { Button, Avatar } = DS;
const D = window.CRData;
const { CRIcon, CRPage, CRStat, CRChip, CRSpark, CRCard, CRTh, CRRow, CRLink, CRPhoto,
        CRFilterPill, CRSearch, CREmpty, usePeriod, useCRSort, crSorted, crMono } = window;

/* ============ 01 · Overview — Monday morning ============ */

function AttentionItem({ icon, tone, title, body, cta, onClick, last, evidence, evidenceDef, extra, action, onDismiss, dismissLabel }) {
  const T = {
    bad:  { color: "var(--red-600)",   bg: "#FBEEED" },
    warn: { color: "var(--amber-700)", bg: "var(--cream-100)" },
    good: { color: "var(--green-800)", bg: "var(--surface-tint)" },
  }[tone] || { color: "var(--amber-700)", bg: "var(--cream-100)" };
  return (
    <div className="cr-att" style={{ display: "flex", gap: 12, padding: "12px 0", borderBottom: last ? "none" : "1px solid var(--line-200)" }}>
      <span style={{ width: 32, height: 32, borderRadius: 9, background: T.bg, display: "grid", placeItems: "center", flex: "none" }}>
        <CRIcon name={icon} size={15} color={T.color} />
      </span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13.5, fontWeight: 700, color: "var(--green-950)" }}>{title}</div>
        <div style={{ fontSize: 12.5, fontWeight: 500, color: "var(--neutral-700)", marginTop: 2, lineHeight: "17px", display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
          <span style={{ minWidth: 0 }}>{body}</span>
          {extra}
        </div>
        {/* Evidence stated inline — the spark glyph + sourced line is the brand of intelligence here. */}
        {evidence && <window.CREvidence def={evidenceDef} style={{ marginTop: 5 }}>{evidence}</window.CREvidence>}
      </div>
      <span style={{ display: "flex", alignItems: "flex-start", gap: 4, flex: "none" }}>
        {action || <Button variant="secondary" size="sm" onClick={onClick}>{cta}</Button>}
        {onDismiss && (
          <button className="cr-ia cr-def-btn cr-att-x" onClick={onDismiss} aria-label={dismissLabel || "Dismiss — fewer like this"} title={dismissLabel || "Dismiss — fewer like this"} style={{ padding: 7 }}>
            <CRIcon name="x" size={13} color="currentColor" />
          </button>
        )}
      </span>
    </div>
  );
}

// Wins recede (right rail) — quieter than the attention list, but each drills.
function WinItem({ title, body, onClick, last }) {
  return (
    <CRRow cols="22px 1fr 14px" onClick={onClick} last={last} ariaLabel={`${title} — open listing`}>
      <CRIcon name="trending-up" size={14} color="var(--green-600)" />
      <span style={{ minWidth: 0 }}>
        <span style={{ display: "block", fontSize: 12.5, fontWeight: 700, color: "var(--green-950)" }}>{title}</span>
        <span style={{ display: "block", fontSize: 11.5, fontWeight: 500, color: "var(--neutral-500)", marginTop: 1, lineHeight: "15px" }}>{body}</span>
      </span>
      <span className="cr-row-ch"><CRIcon name="chevron-right" size={13} color="var(--neutral-300)" /></span>
    </CRRow>
  );
}

// Today strip — each scheduled showing is a pass: the row-size Pass object,
// desktop density. Past dims, in-progress carries the live dot, upcoming waits.
function TodayChip({ s, go }) {
  const DSx = window.DoorpassDesignSystem_eaad52;
  const l = D.listing(s.listing);
  const past = s.status === "done", now = s.status === "now";
  return (
    <DSx.PassRow
      dense
      photo={l.img ? window.CRImgSrc(l.img) : null}
      name={l.addr}
      window={`${s.t} · ${s.who}`}
      status={past ? "done" : now ? "live" : "scheduled"}
      statusLabel={past ? "Done" : now ? "Now" : s.warn ? null : "Upcoming"}
      onClick={() => go("listing", s.listing)}
      trailing={s.warn ? <span style={{ fontSize: 10.5, fontWeight: 700, color: "var(--cream-100)", background: "var(--amber-600)", borderRadius: "var(--radius-pill)", padding: "2px 8px", whiteSpace: "nowrap" }}>{s.warn}</span> : null}
      style={{ width: "auto", opacity: past ? 0.6 : 1 }}
    />
  );
}

function CROverview({ go }) {
  const { period } = usePeriod();
  const stats = D.overviewStats[period.dataKey];
  const share = D.shareStats[period.dataKey];
  // Intelligence layer state — evidence panel + per-card dismissals (logged to the ledger).
  const [panel, setPanel] = React.useState(false);
  const [dismissed, setDismissed] = React.useState({});
  const watch = window.useCRWatch();
  const okafor = D.byId("okafor");
  const dismiss = (id, action) => { setDismissed((d) => ({ ...d, [id]: true })); D.logIntel(action, id === "brixton" ? "brixton" : null); };
  const attnCount = 4 - (dismissed.brixton ? 1 : 0) - (dismissed.whitfield ? 1 : 0);
  // Drill targets: each number lands on its evidence.
  const drill = {
    showings: () => go("activity", { filter: "entry" }),
    requests: () => go("activity", { filter: "request" }),
    response: () => go("team", { sort: "latency" }),
    repeats:  () => go("listings", { filter: "hot" }),
    noshow:   () => go("operations"),
  };
  const COUNT_WORDS = { 2: "Two", 3: "Three", 4: "Four" };
  // Comparison lens — count metrics map to their rate equivalents (requests has none).
  const BENCH_FOR = { showings: "perListing", requests: "reqPerListing", response: "response", repeats: "repeatRate", noshow: "noshowRate" };
  return (
    <CRPage
      label="01 Overview"
      display
      eyebrow="Mon · Jun 8, 2026"
      title="Good morning, Salena"
      sub={`48 verified showings ${period.id === "week" || period.id === "custom" ? "last week" : period.label.toLowerCase()} across 14 listings. ${COUNT_WORDS[attnCount] || attnCount} things need you this morning.`}
      actions={<Button variant="secondary" size="sm" leadingIcon={<CRIcon name="file-down" size={14} />}>Weekly digest</Button>}
    >
      {/* Stat strip — every number paired with a comparison, every tile drills */}
      <div style={{ display: "flex", gap: 12, marginBottom: 16 }}>
        {stats.map((s) => (
          <CRStat key={s.k} label={s.label} value={s.v} unit={s.unit} delta={s.delta} good={s.good} note={s.note} info={s.k} onClick={drill[s.k]} benchKey={BENCH_FOR[s.k]} />
        ))}
      </div>

      {/* Density gradient: dense primary zone (attention) · receding right rail */}
      <div style={{ display: "grid", gridTemplateColumns: "1.25fr 1fr", gap: 16, marginBottom: 16 }}>
        <CRCard title="Needs attention" hint="ranked by consequence">
          {/* B1 · The hero: price-cut early warning. Click opens the evidence panel, not a page. */}
          {!dismissed.brixton && (
            <AttentionItem icon="trending-down" tone="bad" title="104 Brixton Ln matches the price-cut cohort signature"
              body="Velocity −60% vs comps by week 8 — 78% of this cohort cut price within 21 days. 47 days on market."
              evidence="from 41 cohort listings · anonymized L1 aggregate" evidenceDef="cohort"
              cta="Evidence" onClick={() => setPanel(true)}
              onDismiss={() => dismiss("brixton", "intelligence.card dismissed · price-cut early warning (fewer like this)")} />
          )}
          <AttentionItem icon="battery-low" tone="bad" title="9 Eagle Crest — lock battery at 12%"
            body="Next showing today at 2:30 PM. A dead lock turns a confirmed showing into a no-show." cta="Fix" onClick={() => go("operations")} />
          {/* A9 · Latency drift — trend inline, CTA opens the coach drill pre-focused on latency. */}
          <AttentionItem icon="clock" tone="warn" title="D. Okafor — approvals at 24 min median, rising 8 weeks"
            body="3× the team median — est. 2 showings lost last week."
            extra={<CRSpark data={okafor.latencyTrend} w={70} h={20} color="var(--red-600)" baseline={9} />}
            evidence="from request → decision pairs · 8 wks" evidenceDef="drift"
            cta="Coach" onClick={() => go("team", { open: "okafor", focus: "latency" })}
            last={dismissed.whitfield} />
          {/* A10 · Recruiting trigger — lower tier; the action syncs with the Recruiting screen. */}
          {!dismissed.whitfield && (
            <AttentionItem icon="user-plus" tone="good" title="K. Whitfield — 14 verified tours on your listings · 27% conversion"
              body="Top conversion among co-broke agents this period. Recruiting-grade signal."
              evidence="from the recruiting board · verified entries only" evidenceDef="conversion"
              action={
                <Button variant={watch["K. Whitfield"] ? "secondary" : "primary"} size="sm"
                  leadingIcon={<CRIcon name={watch["K. Whitfield"] ? "check" : "plus"} size={13} />}
                  onClick={() => {
                    if (!watch["K. Whitfield"]) D.logIntel("intelligence.card acted · recruiting trigger → K. Whitfield added to watchlist");
                    window.CRIntelWatch.toggle("K. Whitfield");
                  }}>{watch["K. Whitfield"] ? "Watching" : "Add to watchlist"}</Button>
              }
              onDismiss={() => dismiss("whitfield", "intelligence.card dismissed · recruiting trigger (fewer like this)")} last />
          )}
        </CRCard>

        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <CRCard title="Wins" hint="from verified events" pad={12}>
            <WinItem title="3 repeat visits at 412 Oakmont Dr" body="Same buyer-agents returning within 7 days. Offer probability now 78%." onClick={() => go("listing", "oakmont")} />
            <WinItem title="88 Cypress Bend running 52% above comps" body="8 verified showings in week 4. Hold price; the demand is real." onClick={() => go("listing", "cypress")} last />
          </CRCard>

          {/* Levi's one glance — drills to the pipeline behind it */}
          <CRCard title="Share of metro showings" info="share" hint={period.label.toLowerCase()} pad={12}
            action={<CRLink onClick={() => go("pipeline")} size={11.5} weight={700} color="var(--green-800)">Pipeline →</CRLink>}>
            <div style={{ display: "flex", alignItems: "center", gap: 16 }}>
              <div>
                <div style={{ display: "flex", alignItems: "baseline", gap: 6 }}>
                  <span style={{ ...crMono(26), fontWeight: 600 }}>{share.v}</span>
                  <span style={{ ...crMono(12, "var(--green-600)"), whiteSpace: "nowrap" }}>{share.delta}</span>
                </div>
                <div style={{ fontSize: 11.5, fontWeight: 500, color: "var(--neutral-500)", marginTop: 3, lineHeight: "15px" }}>
                  of verified buyer attention in your comp set went to Brooks Group listings.
                </div>
              </div>
              <CRSpark data={share.spark} w={110} h={36} />
            </div>
          </CRCard>
        </div>
      </div>

      {/* Today — the only live surface; chips carry state */}
      <CRCard title="Today" hint="6 showings scheduled · 1 in progress">
        <div style={{ display: "flex", gap: 10, flexWrap: "wrap" }}>
          {D.today.map((s, i) => <TodayChip key={i} s={s} go={go} />)}
        </div>
      </CRCard>

      {/* B1 · evidence slide-over — data → cohort → recommendation, every stat ⓘ-traceable */}
      {panel && <window.CRBrixtonPanel onClose={() => setPanel(false)} go={go} />}
    </CRPage>
  );
}

/* ============ 01b · Day one — honest cold start ============ */

function DayOneStep({ done, title, sub, last }) {
  return (
    <div style={{ display: "flex", gap: 12, padding: "11px 0", borderBottom: last ? "none" : "1px solid var(--line-200)", alignItems: "flex-start" }}>
      <span style={{ width: 26, height: 26, borderRadius: 8, flex: "none", display: "grid", placeItems: "center", background: done ? "var(--surface-tint)" : "var(--mist-100)", boxShadow: done ? "inset 0 0 0 1px var(--green-300)" : "inset 0 0 0 1px var(--line-200)" }}>
        <CRIcon name={done ? "check" : "circle-dashed"} size={13} color={done ? "var(--green-800)" : "var(--neutral-500)"} />
      </span>
      <span style={{ minWidth: 0 }}>
        <span style={{ display: "block", fontSize: 13, fontWeight: 700, color: done ? "var(--green-950)" : "var(--neutral-700)" }}>{title}</span>
        <span style={{ display: "block", fontSize: 12, fontWeight: 500, color: "var(--neutral-500)", marginTop: 1, lineHeight: "16px" }}>{sub}</span>
      </span>
    </div>
  );
}

function CRDayOne({ go }) {
  return (
    <CRPage
      label="01b Day one"
      eyebrow="Tue · Apr 14, 2026 — chapter state: first listing live"
      title="Welcome, Salena"
      sub="One listing live. Here's what's measurable today — and what unlocks as your metro fills in."
    >
      <div style={{ display: "flex", gap: 12, marginBottom: 16 }}>
        <CRStat label="Showings completed" value="0" note="first one typically lands within 48h" info="showings" />
        <CRStat label="Requests received" value="2" delta="+2" good note="since going live" info="requests" />
        <CRStat label="Median response" value="—" note="measurable after ~5 requests" info="response" />
        <CRStat label="Repeat visits" value="—" note="measurable after first showings" info="repeats" />
        <CRStat label="No-shows" value="—" note="measurable after first passes" info="noshow" />
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.25fr 1fr", gap: 16 }}>
        <CRCard title="Measurable from day one" hint="519 Mistletoe Ave">
          <DayOneStep done title="Lock paired and reporting" sub="Yale Assure 2 · battery 100% · daily telemetry check-ins started." />
          <DayOneStep done title="Showing windows set" sub="Approve each · Mon–Sat 9 AM – 7 PM. Every request will be timestamped against them." />
          <DayOneStep done title="First requests arriving" sub="2 showing requests in the queue — response latency starts measuring with your first decision." />
          <DayOneStep title="First verified showing" sub="Entry/exit events unlock true durations, the showing log, and the conversion ladder." last />
        </CRCard>

        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <CRCard title="What unlocks later" hint="benchmark density" pad={14}>
            <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginBottom: 6 }}>
              <span style={crMono(22)}>14<span style={{ color: "var(--neutral-500)", fontWeight: 500 }}> / ~50</span></span>
              <span style={{ fontSize: 11.5, fontWeight: 500, color: "var(--neutral-500)" }}>active listings in your metro comp set</span>
            </div>
            <span style={{ display: "block", height: 8, borderRadius: 4, background: "var(--mist-100)", overflow: "hidden", marginBottom: 10 }}>
              <span style={{ display: "block", height: "100%", width: "28%", borderRadius: 4, background: "var(--green-600)" }}></span>
            </span>
            <div style={{ fontSize: 12.5, fontWeight: 500, color: "var(--neutral-700)", lineHeight: "17px" }}>
              Comp-set velocity bands and share-of-metro unlock at ~50 listings in your metro. Until then, every number shown is measured from your own verified events — nothing is modeled.
            </div>
          </CRCard>
          <CRCard pad={14} style={{ background: "var(--surface-tint)", boxShadow: "inset 0 0 0 1px var(--green-300)" }}>
            <div style={{ display: "flex", gap: 10, alignItems: "flex-start" }}>
              <CRIcon name="badge-check" size={16} color="var(--green-800)" style={{ marginTop: 1 }} />
              <span style={{ fontSize: 12.5, fontWeight: 600, color: "var(--green-900)", lineHeight: "17px" }}>
                This is the same Control Room you'll run 14 listings from — nothing here is a different product. <CRLink onClick={() => go("overview")} size={12.5} weight={700} color="var(--green-800)">See it at full density →</CRLink>
              </span>
            </div>
          </CRCard>
        </div>
      </div>
    </CRPage>
  );
}

/* ============ 02 · Listings — health board ============ */

const LCOLS = "minmax(184px,1.35fr) 102px 60px 84px 158px 64px 72px minmax(130px,1fr)";
const LSORT = {
  addr: (l) => l.addr, agent: (l) => D.byId(l.agent).name, days: (l) => l.days,
  wk: (l) => l.wk, vsComp: (l) => l.vsComp, repeats: (l) => l.repeats, noshow: (l) => l.noshow,
};

function CRListings({ go, initial }) {
  const [filter, setFilter] = React.useState((initial && initial.filter) || "all");
  const [q, setQ] = React.useState("");
  const [sort, onSort] = useCRSort("days", "asc");
  const FILTERS = [
    { id: "risk", label: "At risk · 2" },
    { id: "hot", label: "Hot · 2" },
    { id: "new", label: "New · 2" },
    { id: "uc", label: "Under contract · 1" },
  ];
  const ql = q.trim().toLowerCase();
  const rows = crSorted(
    D.listings
      .filter((l) => filter === "all" || l.cat === filter)
      .filter((l) => !ql || (l.addr + " " + l.hood + " " + D.byId(l.agent).name).toLowerCase().includes(ql)),
    sort, LSORT,
  );
  return (
    <CRPage
      label="02 Listings"
      eyebrow="14 active · Brooks Group"
      title="Listings"
      sub="Health from verified events — velocity vs comp set, repeats, no-shows, forecast."
      actions={<CRSearch value={q} onChange={setQ} placeholder="Filter listings…" />}
    >
      {/* Filter chips — removable ✕, All resets; treat as application state */}
      <div style={{ display: "flex", gap: 6, marginBottom: 12, alignItems: "center" }}>
        <CRFilterPill on={filter === "all" && !ql} label="All · 14" onClick={() => { setFilter("all"); setQ(""); }} />
        {FILTERS.map((f) => (
          <CRFilterPill key={f.id} on={filter === f.id} label={f.label} onClick={() => setFilter(f.id)} onClear={() => setFilter("all")} />
        ))}
        {ql && <CRFilterPill on label={`“${q}”`} onClear={() => setQ("")} />}
        <span style={{ flex: 1 }}></span>
        <span style={{ fontSize: 11.5, fontWeight: 500, color: "var(--neutral-500)" }}>sorted by {sort.key === "days" ? "days on market" : sort.key} · click headers to re-sort</span>
      </div>

      {/* Comparison lens — portfolio rates vs the same categories at the selected scope */}
      <window.CRBenchBand keys={["perListing", "repeatRate", "noshowRate"]} style={{ marginBottom: 12 }} />

      <CRCard pad={10}>
        <CRTh cols={LCOLS}
          labels={["Listing", "Agent", "Days", "Showings", "Velocity vs comps", "Repeats", "No-show", "Forecast"]}
          aligns={["left", "left", "right", "right", "left", "right", "right", "left"]}
          keys={["addr", "agent", "days", "wk", "vsComp", "repeats", "noshow", null]}
          defs={[null, null, "days", "showings", "velocity", "repeats", "noshow", null]}
          sort={sort} onSort={onSort} />
        {rows.length === 0 && (
          filter === "risk"
            ? <CREmpty icon="party-popper" title="No at-risk listings — nice problem to have" body="Velocity on every active listing is tracking at or above its comp set." />
            : <CREmpty title={ql ? `No listings match “${q}”` : "No listings in this view"} body="Clear the filter to see all 14 active listings."
                action={<Button variant="secondary" size="sm" onClick={() => { setQ(""); setFilter("all"); }}>Show all</Button>} />
        )}
        {rows.map((l, i) => {
          const a = D.byId(l.agent);
          const over = l.vsComp > 10, under = l.vsComp < -10;
          return (
            <CRRow key={l.id} cols={LCOLS} last={i === rows.length - 1} onClick={() => go("listing", l.id)} ariaLabel={`${l.addr} — open listing detail`}>
              <span style={{ display: "flex", alignItems: "center", gap: 10, minWidth: 0 }}>
                <CRPhoto listing={l} />
                <span style={{ minWidth: 0 }}>
                  <span style={{ display: "block", fontSize: 13, fontWeight: 700, color: "var(--green-950)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{l.addr}</span>
                  <span style={{ display: "block", fontSize: 11, fontWeight: 500, color: "var(--neutral-500)" }}>{l.hood} · {l.price}</span>
                </span>
              </span>
              <span style={{ display: "flex", alignItems: "center", gap: 7, minWidth: 0 }}>
                <Avatar name={a.name} size={22} />
                <span style={{ fontSize: 12, fontWeight: 600, color: "var(--neutral-700)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.name.split(" ")[0]}</span>
              </span>
              <span style={{ ...crMono(12.5), textAlign: "right" }}>{l.days}</span>
              <span style={{ ...crMono(12.5), textAlign: "right" }}>{l.wk} <span style={{ color: "var(--neutral-500)", fontWeight: 500 }}>/ {l.total}</span></span>
              <span style={{ display: "flex", alignItems: "center", gap: 8 }}>
                <CRSpark data={l.velo} w={64} h={20} color={under ? "var(--red-600)" : "var(--green-600)"} />
                {l.velo.length > 1 && (
                  <span style={{ ...crMono(11.5, under ? "var(--red-600)" : over ? "var(--green-600)" : "var(--neutral-500)") }}>
                    {l.vsComp > 0 ? "+" : ""}{l.vsComp}%
                  </span>
                )}
              </span>
              <span style={{ ...crMono(12.5), textAlign: "right", color: l.repeats > 1 ? "var(--green-800)" : "var(--green-950)" }}>{l.repeats || "—"}</span>
              <span style={{ ...crMono(12.5, l.noshow >= 10 ? "var(--red-600)" : "var(--neutral-700)", 500), textAlign: "right" }}>{l.noshow ? l.noshow + "%" : "—"}</span>
              <span style={{ display: "flex", alignItems: "center", gap: 6 }}>
                <CRChip tone={l.forecast.tone}>{l.forecast.label}</CRChip>
                <span className="cr-row-ch"><CRIcon name="chevron-right" size={13} color="var(--neutral-300)" /></span>
              </span>
            </CRRow>
          );
        })}
      </CRCard>
      <div style={{ marginTop: 10, fontSize: 11.5, fontWeight: 500, color: "var(--neutral-500)", display: "flex", alignItems: "center", gap: 6 }}>
        <CRIcon name="badge-check" size={13} color="var(--neutral-500)" />
        Velocity and no-show rates are measured from verified entry/exit events — not feedback forms.
      </div>
    </CRPage>
  );
}

Object.assign(window, { CROverview, CRDayOne, CRListings });
})();
