/* home.jsx, the dashboard. Reads top→bottom:
   header · net worth + live sparkline · allocation · quick actions ·
   what's pending (top proposal) · recent activity · automations. */

/* net-worth across horizons. 1D reuses the live intraday series (so the
   agent-action markers line up); the rest are generated to hit a plausible
   period return ending at today's balance. */
const NW_RANGES = ["1D", "1M", "6M", "YTD", "1Y", "5Y", "All"];
const NW_META = {
  "1D": { pct: DAY_PCT, label: "today", len: 34, vol: 0.0016, markers: true },
  "1M": { pct: 3.6, label: "past month", len: 32, vol: 0.007, seed: 222 },
  "6M": { pct: 14.6, label: "past 6 months", len: 48, vol: 0.014, seed: 226 },
  "YTD": { pct: 9.8, label: "year to date", len: 44, vol: 0.013, seed: 232 },
  "1Y": { pct: 22.4, label: "past year", len: 52, vol: 0.017, seed: 230 },
  "5Y": { pct: 96.2, label: "past 5 years", len: 64, vol: 0.03, seed: 244 },
  "All": { pct: 142.0, label: "all time", len: 72, vol: 0.034, seed: 240 }
};
const buildNW = (range) => {
  const m = NW_META[range];
  if (range === "1D") return { data: NW_SERIES, abs: DAY_ABS, pct: DAY_PCT, label: m.label, markers: NW_MARKERS };
  const start = NET_WORTH / (1 + m.pct / 100);
  return { data: series(m.seed, m.len, start, NET_WORTH, m.vol), abs: NET_WORTH - start, pct: m.pct, label: m.label, markers: [] };
};

const ACTIVITY_FILTERS = [
["all", "All"], ["automations", "Automations"], ["spending", "Spending"],
["investments", "Investments"], ["transfers", "Transfers"], ["income", "Income"]];


/* forward-looking schedule — shown above recent activity in one endless feed */
const COMING_UP = [
{ icon: "bolt", cat: "automations", autoId: "a1", title: "Weekly investing · VTI", sub: "Automation", when: "Fri · Jun 5", amount: 500, tone: "out" },
{ icon: "card", cat: "spending", title: "Netflix", sub: "Subscription · Yoshi card ••4417", when: "Sun · Jun 8", amount: 24.99, tone: "out" },
{ icon: "bank", cat: "income", title: "Pay day", sub: "Direct deposit to Yoshi brokerage ••3456", when: "Mon · Jun 15", amount: 8200, tone: "in" }];


/* clearer feed section header — sentence case, legible, replaces the tiny
   tracked eyebrow so category titles read at a glance. */
const SecTitle = ({ children, color = "var(--ink)" }) => (
  <div style={{ fontFamily: "var(--f-display)", fontSize: 14, fontWeight: 700, letterSpacing: "-0.005em", color, display: "inline-flex", alignItems: "center" }}>{children}</div>
);

const Home = ({ nav, proposals, completed, onApprove, onSeeStream, onBell }) => {
  const [marker, setMarker] = useState(null);
  const [scrubVal, setScrubVal] = useState(null);
  const [page, setPage] = useState(0);
  const [range, setRange] = useState("1D");
  const [filter, setFilter] = useState("all");
  const [searchOpen, setSearchOpen] = useState(false);
  const [query, setQuery] = useState("");

  const nw = useMemo(() => buildNW(range), [range]);

  // recent activity = freshly-approved agent moves prepended onto the ledger
  const txns = useMemo(() => {
    const fresh = completed.filter((c) => String(c.id).startsWith("ex_")).map((c) => ({
      id: c.id, icon: "bolt", title: c.title, detail: `${c.detail} · ${c.by}`, when: c.when, net: c.net
    }));
    return [...fresh, ...TRANSACTIONS];
  }, [completed]);

  // one feed: transactions with automation events woven in, each tagged with a
  // category so the filter chips can narrow the combined list.
  const feed = useMemo(() => {
    const txCat = { receipt: "spending", down: "income", swap: "transfers", trade: "investments", bolt: "automations" };
    const autos = AUTOMATIONS.map((a) => ({ kind: "auto", a, id: "f_" + a.id, cat: "automations" }));
    const tx = txns.map((t) => ({ kind: "txn", t, id: "f_" + t.id, cat: txCat[t.icon] || "spending" }));
    const out = [];
    let ai = 0;
    tx.forEach((item, i) => {
      out.push(item);
      if (i % 2 === 1 && ai < autos.length) out.push(autos[ai++]);
    });
    while (ai < autos.length) out.push(autos[ai++]);
    return out;
  }, [txns]);

  const shownFeed = useMemo(() => {
    const q = query.trim().toLowerCase();
    return feed.filter((f) => {
      if (filter !== "all" && f.cat !== filter) return false;
      if (!q) return true;
      const hay = f.kind === "auto" ? `${f.a.name} ${f.a.measure}` : `${f.t.title} ${f.t.detail}`;
      return hay.toLowerCase().includes(q);
    });
  }, [feed, filter, query]);

  const shownComing = useMemo(() => {
    const q = query.trim().toLowerCase();
    return COMING_UP.filter((c) => {
      if (filter !== "all" && c.cat !== filter) return false;
      if (!q) return true;
      return `${c.title} ${c.sub}`.toLowerCase().includes(q);
    });
  }, [filter, query]);

  const display = scrubVal != null ? scrubVal : NET_WORTH;

  return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column", minHeight: 0 }}>
      {/* header strip */}
      <div style={{ flex: "none", padding: "4px 18px 2px", display: "flex", alignItems: "center", gap: 9 }}>
        <YouButton nav={nav} />
        <button className="press" onClick={onBell || (() => nav.sheet({ type: "briefs" }))} aria-label="Alerts" title="Alerts"
        style={{ marginLeft: "auto", marginRight: -6, position: "relative", background: "none", border: "none", padding: 6, display: "grid", placeItems: "center", color: "var(--ink)", cursor: "pointer" }}>
          <Icon name="bell" size={21} stroke={1.6} />
          <span style={{ position: "absolute", top: 3, right: 4, width: 10, height: 10, borderRadius: 999, background: "#e5301c", border: "2px solid var(--bg)", boxShadow: "0 0 0 0.5px rgba(0,0,0,0.08)" }} />
        </button>
      </div>

      <div className="scroll">
        {/* BAND 1 · net worth + sparkline */}
        <section style={{ padding: "6px 18px 4px" }}>
          <Eyebrow>{scrubVal != null ? "Earlier" : "Yoshi balance"}</Eyebrow>
          <div style={{ marginTop: 5, lineHeight: 1 }}>
            <Money value={display} size={38} weight={500} />
          </div>
          <div style={{ marginTop: 7, display: "flex", alignItems: "baseline", gap: 7 }}>
            <Delta abs={nw.abs} pct={nw.pct} size={13} />
            <span style={{ fontFamily: "var(--f-display)", fontSize: 12, color: "var(--ink-3)" }}>{nw.label.charAt(0).toUpperCase() + nw.label.slice(1)}</span>
          </div>

          <div style={{ marginTop: -2 }}>
            <Chart data={nw.data} height={70} accent="var(--chart-line)" fillColor="var(--chart-fill)" markers={nw.markers} activeMarker={marker} onPickMarker={setMarker}
            scrub onScrub={(idx) => setScrubVal(idx == null ? null : nw.data[idx])} />
          </div>

          {/* horizon toggle, understated text buttons, no heavy chrome */}
          <div style={{ display: "flex", gap: 3, marginTop: 2 }}>
            {NW_RANGES.map((r) => {
              const on = r === range;
              return (
                <button key={r} className="press" onClick={() => {setRange(r);setMarker(null);setScrubVal(null);}} style={{
                  flex: 1, padding: "3px 0", background: on ? "var(--bg-2)" : "transparent", border: "none", borderRadius: 7,
                  fontFamily: "var(--f-mono)", fontSize: 11, fontWeight: 500, letterSpacing: "0.02em",
                  color: on ? "var(--ink)" : "var(--ink-3)", cursor: "pointer", fontVariantNumeric: "tabular-nums"
                }}>{r}</button>);

            })}
          </div>

          {/* marker tooltip, tap to open the automation in Stream */}
          {marker != null && nw.markers[marker] &&
          <div style={{ marginTop: 10 }}>
              <button className="press" onClick={() => nw.markers[marker].autoId && nav.automation(nw.markers[marker].autoId)} style={{
              width: "100%", textAlign: "left", padding: "9px 11px", background: "var(--bg-2)", border: "none", borderRadius: 10,
              display: "flex", alignItems: "center", gap: 8, cursor: "pointer"
            }}>
                <span style={{ fontFamily: "var(--f-mono)", fontSize: 11, color: "var(--accent)" }}>{nw.markers[marker].time}</span>
                <span style={{ fontFamily: "var(--f-display)", fontSize: 12, fontWeight: 600 }}>{nw.markers[marker].name}</span>
                <span style={{ marginLeft: "auto", display: "inline-flex", alignItems: "center", gap: 5, fontFamily: "var(--f-display)", fontSize: 11, color: "var(--ink-3)" }}>
                  {nw.markers[marker].detail}
                  <Icon name="back" size={14} color="var(--ink-3)" style={{ transform: "scaleX(-1)" }} />
                </span>
              </button>
            </div>
          }
        </section>

        {/* allocation row */}
        <Allocation nav={nav} />

        {/* quick actions */}
        <section style={{ padding: "4px 18px 4px", display: "flex", justifyContent: "center", gap: 10 }}>
          <QuickAction icon="swap" label="Transfer" onClick={() => nav.sheet({ type: "transfer" })} />
          <QuickAction icon="trade" label="Trade" onClick={() => nav.sheet({ type: "trade" })} />
          <QuickAction icon="easel" label="Agents" onClick={() => nav.sheet({ type: "connect" })} />
        </section>

        {/* BAND 2 · pending, a scroll-snap carousel of proposals */}
        <section style={{ padding: "6px 0 6px" }}>
          <div style={{ display: "flex", alignItems: "baseline", marginBottom: 5, padding: "0 18px" }}>
            {proposals.length === 0 ?
            <SecTitle color="var(--accent-pos)"><Icon name="check" size={13} stroke={2.2} color="var(--accent-pos)" style={{ display: "inline-block", verticalAlign: "-2px" }} /> &nbsp;You're caught up</SecTitle> :
            <SecTitle color="var(--accent)"><LiveDot /> &nbsp;Needs you</SecTitle>}
          </div>
          {proposals.length === 0 ? null : proposals.length === 1 ?
          <div style={{ padding: "0 18px" }}><PendingCard p={proposals[0]} onReview={() => onApprove(proposals[0].id)} /></div> :

          <>
              <PendingWheel key={proposals.length} proposals={proposals} onReview={onApprove} onActive={setPage} />
              <div style={{ display: "flex", justifyContent: "center", gap: 6, marginTop: 6 }}>
                {proposals.map((_, i) =>
              <span key={i} style={{ width: i === Math.min(page, proposals.length - 1) ? 16 : 6, height: 6, borderRadius: 999, background: i === Math.min(page, proposals.length - 1) ? "var(--accent)" : "var(--rule-2)", transition: "width 200ms var(--ease), background 200ms" }} />
              )}
              </div>
            </>
          }
        </section>

        {/* BAND 3 · Stream — sticky header (title + pills + search), then
             Coming up and Recent activity as sub-sections in one endless scroll. */}
        <section style={{ padding: "8px 0 0", minHeight: "100%" }}>
          {/* sticky header: Stream title · filter pills · search */}
          <div style={{ position: "sticky", top: 0, zIndex: 6, background: "var(--bg)", borderBottom: "1px solid var(--rule)", paddingBottom: 10 }}>
            <div style={{ padding: "2px 18px 0", display: "flex", alignItems: "center", gap: 8 }}>
              <span style={{ fontFamily: "var(--f-display)", fontSize: onSeeStream ? 12.5 : 17, fontWeight: onSeeStream ? 500 : 600, letterSpacing: "-0.01em", color: onSeeStream ? "var(--ink-2)" : "var(--ink)" }}>{onSeeStream ? "Recent activity" : "Stream"}</span>
              {onSeeStream && <button className="press" onClick={onSeeStream} aria-label="Open Stream" style={{ marginLeft: "auto", display: "inline-flex", alignItems: "center", gap: 4, background: "none", border: "none", cursor: "pointer", fontFamily: "var(--f-display)", fontSize: 12, fontWeight: 600, color: "var(--ink-3)" }}><Icon name="back" size={14} color="var(--ink-3)" style={{ transform: "scaleX(-1)" }} /></button>}
            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 9 }}>
              <div className="hcar" style={{ display: "flex", gap: 7, overflowX: "auto", padding: "0 0 0 18px", flex: 1, minWidth: 0 }}>
                {ACTIVITY_FILTERS.map(([k, l]) => {
                  const on = filter === k;
                  return <button key={k} className="press" onClick={() => setFilter(k)} style={{ flex: "none", padding: "5px 11px", borderRadius: 999, background: on ? "color-mix(in srgb, var(--ink) 15%, var(--bg-2))" : "var(--bg-2)", color: on ? "var(--ink)" : "var(--ink-2)", border: `1px solid ${on ? "color-mix(in srgb, var(--ink) 15%, var(--rule-2))" : "var(--rule-2)"}`, fontFamily: "var(--f-display)", fontSize: 11.5, fontWeight: 600, whiteSpace: "nowrap", cursor: "pointer" }}>{l}</button>;
                })}
              </div>
              <button className="press" onClick={() => {setSearchOpen((o) => {if (o) setQuery("");return !o;});}}
              aria-label="Search activity"
              style={{ flex: "none", marginRight: 18, background: "none", border: "none", padding: 2, display: "flex", color: searchOpen ? "var(--ink)" : "var(--ink-3)", cursor: "pointer" }}>
                <Icon name={searchOpen ? "close" : "search"} size={18} stroke={1.6} />
              </button>
            </div>
            {searchOpen &&
            <div style={{ display: "flex", alignItems: "center", gap: 9, padding: "9px 12px", margin: "10px 18px 0", background: "var(--bg-2)", border: "1px solid var(--rule-2)", borderRadius: 10 }}>
                <Icon name="search" size={15} color="var(--ink-3)" stroke={1.5} />
                <input autoFocus value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search activity"
              style={{ flex: 1, border: "none", background: "transparent", outline: "none", color: "var(--ink)", fontFamily: "var(--f-display)", fontSize: 13.5 }} />
                {query && <button className="press" onClick={() => setQuery("")} style={{ background: "none", border: "none", display: "flex", color: "var(--ink-3)", padding: 0 }}><Icon name="close" size={14} /></button>}
              </div>
            }
          </div>

          {/* COMING UP */}
          {shownComing.length > 0 &&
          <div style={{ padding: "16px 18px 4px" }}>
              <SecTitle>Coming up</SecTitle>
              <div style={{ marginTop: 8 }}>
                {shownComing.map((c, i) => <ComingRow key={i} c={c} last={i === shownComing.length - 1} nav={nav} />)}
              </div>
            </div>
          }

          {/* RECENT ACTIVITY */}
          <div style={{ padding: "18px 18px 4px" }}>
            <SecTitle>Recent activity</SecTitle>
            <div style={{ marginTop: 8 }}>
              {shownFeed.length ? shownFeed.map((item, i) => item.kind === "auto" ?
              <FeedAutoRow key={item.id} a={item.a} last={i === shownFeed.length - 1} onOpen={() => nav.sheet({ type: "automation", id: item.a.id })} /> :
              <TxnRow key={item.id} t={item.t} last={i === shownFeed.length - 1} nav={nav} />) :
              <div style={{ padding: "26px 0", textAlign: "center", fontFamily: "var(--f-display)", fontSize: 12.5, color: "var(--ink-3)" }}>{query.trim() ? `No activity matches "${query}".` : "Nothing in this filter yet."}</div>}
            </div>
          </div>
        </section>
        <div style={{ height: 14 }} />
      </div>
    </div>);

};

const QuickAction = ({ icon, logo, label, onClick }) =>
<button className="press" onClick={onClick} style={{
  background: "var(--bg-card)", border: "1px solid var(--rule)", borderRadius: 10, padding: "9px 6px 8px",
  width: 92, flex: "none",
  display: "flex", flexDirection: "column", alignItems: "center", gap: 5, cursor: "pointer"
}}>
    {logo ? <Logo size={19} /> : <Icon name={icon} size={19} stroke={1.5} color="var(--ink)" />}
    <span style={{ fontFamily: "var(--f-display)", fontSize: 11, fontWeight: 600, letterSpacing: "0.01em" }}>{label}</span>
  </button>;


const Allocation = ({ nav }) => {
  const segs = [
  ["Cash", CASH_TOTAL, "var(--alloc-cash)", false, "cash"],
  ["Stocks", INVEST_TOTAL, "var(--alloc-invest)", false, "investments"],
  ["Crypto", CRYPTO_TOTAL, "var(--alloc-crypto)", false, "investments"]];

  const total = segs.reduce((s, x) => s + x[1], 0);
  return (
    <section style={{ padding: "4px 18px 9px" }}>
      <div style={{ display: "flex", height: 6, gap: 2, marginBottom: 6 }}>
        {segs.map(([l, v, c]) => <div key={l} style={{ background: c, width: `${v / total * 100}%` }} />)}
      </div>
      <div style={{ display: "flex", gap: 2 }}>
        {segs.map(([l, v, c, debt, sv]) =>
          <button key={l} className="press" onClick={() => nav.studio(sv)}
            style={{ background: "none", border: "none", cursor: "pointer", width: `${v / total * 100}%`, display: "flex", flexDirection: "column", alignItems: "center", padding: 0 }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 5 }}>
              <span style={{ width: 7, height: 7, background: c, flex: "none" }} />
              <span style={{ fontFamily: "var(--f-display)", fontSize: 11.5, fontWeight: 600, color: "var(--ink-2)" }}>{l}</span>
            </div>
            <span style={{ fontFamily: "var(--f-mono)", fontSize: 11, color: "var(--ink-3)", marginTop: 2 }}>{(v / total * 100).toFixed(0)}%</span>
          </button>
        )}
      </div>
    </section>);

};

const PendingCard = ({ p, onReview, fill }) =>
<div style={{ border: "1px solid var(--accent)", background: "var(--bg-card)", padding: "11px 12px 12px", borderRadius: 12, boxShadow: "0 0 0 4px color-mix(in srgb, var(--accent) 13%, transparent)", width: "100%", height: fill ? "100%" : undefined, boxSizing: "border-box", display: "flex", flexDirection: "column" }}>
    <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
      <span style={{ width: 6, height: 6, borderRadius: 999, flex: "none", background: /^yoshi/i.test(p.agent) ? "var(--accent)" : "transparent", border: /^yoshi/i.test(p.agent) ? "none" : "1.5px solid var(--ink-3)" }} />
      <span style={{ fontFamily: "var(--f-display)", fontSize: 9, fontWeight: 600, letterSpacing: "0.06em", color: "var(--ink-3)" }}>{p.agent}</span>
    </div>
    <div style={{ fontFamily: "var(--f-display)", fontSize: 15, fontWeight: 600, letterSpacing: "-0.02em", marginTop: 6 }}>{p.title}</div>
    <div style={{ fontFamily: "var(--f-display)", fontSize: 11.5, color: "var(--ink-2)", marginTop: 4, lineHeight: 1.45 }}>{p.why}</div>
    <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginTop: "auto", paddingTop: 8, borderTop: "1px dashed var(--rule)" }}>
      <span style={{ fontFamily: "var(--f-display)", fontSize: 9, fontWeight: 600, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--ink-3)" }}>Net</span>
      <Money value={p.net} size={13} sign color={p.net >= 0 ? "var(--accent-pos)" : "var(--ink)"} dim="var(--ink-3)" />
    </div>
    <Btn full onClick={onReview} style={{ marginTop: 9, borderRadius: 9 }}>Review <Icon name="arrow" size={15} color="var(--accent-ink)" /></Btn>
  </div>;


/* ---- pending wheel · a flat 2D carousel of proposals ----------------------
   Cards slide horizontally; drag to scroll, neighbours peek in slightly scaled
   and dimmed at the edges, the active card sits centred. Snaps on release. */
const WHEEL_W = 264;
/* A native horizontal scroll-snap carousel, scroll/swipe left or right to move
   between proposals; each card snaps to centre. Neighbours peek, scaled + dimmed
   by their distance from centre. Cards stretch to equal height so the CTA always fits. */
const PendingWheel = ({ proposals, onReview, onActive }) => {
  const N = proposals.length;
  const ref = useRef(null);
  const [sx, setSx] = useState(0);
  const STRIDE = WHEEL_W + 14;

  const onScroll = () => {
    const el = ref.current;if (!el) return;
    setSx(el.scrollLeft);
    onActive && onActive(Math.max(0, Math.min(N - 1, Math.round(el.scrollLeft / STRIDE))));
  };

  return (
    <div ref={ref} className="hcar" onScroll={onScroll}
    style={{ display: "flex", gap: 14, overflowX: "auto", scrollSnapType: "x mandatory", alignItems: "stretch", padding: `8px calc(50% - ${WHEEL_W / 2}px)`, WebkitOverflowScrolling: "touch" }}>
      {proposals.map((p, i) => {
        const off = i - sx / STRIDE;
        const ao = Math.min(1, Math.abs(off));
        return (
          <div key={p.id} style={{
            flex: "none", width: WHEEL_W, scrollSnapAlign: "center",
            transform: `scale(${1 - ao * 0.07})`, opacity: 1 - ao * 0.42,
            transition: "transform 160ms linear, opacity 160ms linear"
          }}>
            <PendingCard p={p} onReview={() => onReview(p.id)} fill />
          </div>);

      })}
    </div>);

};

const NothingPending = ({ last }) =>
<div style={{ border: "1px solid var(--rule)", background: "var(--bg-2)", padding: "14px" }}>
    <Eyebrow>All clear · last move</Eyebrow>
    <div style={{ fontFamily: "var(--f-display)", fontSize: 15, fontWeight: 600, marginTop: 5 }}>{last.title}</div>
    <div style={{ fontFamily: "var(--f-display)", fontSize: 12, color: "var(--ink-2)", marginTop: 3 }}>{last.detail} · {last.when}</div>
  </div>;


/* ---- coming-up row (forward-looking schedule, no icon) ------------------- */
/* ---- leading category icon · helps scan the feed by type -----------------
   Agent/automation rows carry the Yoshi mark; everything else gets a schematic
   category glyph in a quiet hairline tile. */
const RowIcon = ({ icon, auto }) => {
  const yoshi = auto || icon === "bolt";
  const p = useTheme();
  return (
    <span style={{ width: 24, height: 24, flex: "none", display: "grid", placeItems: "center", color: "var(--ink-2)", opacity: yoshi && p === "graphite" ? 0.72 : 1 }}>
      {yoshi ? <Logo size={15} /> : <Icon name={icon || "receipt"} size={17} stroke={1.5} color="var(--ink-2)" />}
    </span>
  );
};

const ComingRow = ({ c, last, nav }) => {
  const isAuto = !!c.autoId;
  const open = () => isAuto ? nav.sheet({ type: "automation", id: c.autoId }) : nav.sheet({ type: "txn", tx: c });
  return (
    <button className="press" onClick={open} style={{ width: "100%", textAlign: "left", background: "none", border: "none", display: "grid", gridTemplateColumns: "auto 1fr auto", gap: 11, alignItems: "center", padding: "9px 0", cursor: "pointer", borderBottom: last ? "none" : "1px solid var(--rule)" }}>
      <RowIcon icon={c.icon} auto={isAuto} />
      <div style={{ minWidth: 0 }}>
        <div style={{ fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 500, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{c.title}</div>
        <div style={{ fontFamily: "var(--f-display)", fontSize: 11, color: "var(--ink-3)", marginTop: 3, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{c.sub}</div>
      </div>
      <div style={{ textAlign: "right", whiteSpace: "nowrap" }}>
        <Money value={c.tone === "out" ? -c.amount : c.amount} size={12.5} sign={c.tone === "in"} color={c.tone === "in" ? "var(--accent-pos)" : "var(--ink)"} dim="var(--ink-3)" />
        <div style={{ fontFamily: "var(--f-mono)", fontSize: 9.5, color: "var(--ink-3)", marginTop: 3 }}>{c.when}</div>
      </div>
    </button>);

};

/* ---- recent-activity transaction row (flat ledger, no pill) --------------- */
const TxnRow = ({ t, last, nav }) =>
<button className="press" onClick={() => nav.sheet({ type: "txn", tx: t })} style={{ width: "100%", textAlign: "left", background: "none", border: "none", display: "grid", gridTemplateColumns: "auto 1fr auto", gap: 11, alignItems: "center", padding: "9px 0", cursor: "pointer", borderBottom: last ? "none" : "1px solid var(--rule)" }}>
    <RowIcon icon={t.icon} />
    <div style={{ minWidth: 0 }}>
      <div style={{ fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 500, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{t.title}</div>
      <div style={{ fontFamily: "var(--f-display)", fontSize: 11, color: "var(--ink-3)", marginTop: 3, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{t.detail}</div>
    </div>
    <div style={{ textAlign: "right", whiteSpace: "nowrap" }}>
      {t.net !== 0 ?
    <Money value={t.net} size={12.5} sign color={t.net > 0 ? "var(--accent-pos)" : "var(--ink)"} dim="var(--ink-3)" /> :
    <span style={{ fontFamily: "var(--f-display)", fontSize: 11, color: "var(--ink-3)" }}>moved</span>}
      <div style={{ fontFamily: "var(--f-mono)", fontSize: 9.5, color: "var(--ink-3)", marginTop: 3 }}>{t.when}</div>
    </div>
  </button>;

/* ---- transaction / scheduled-item detail · a receipt-style bottom sheet --- */
const TXN_CATEGORY = { receipt: "Spending", down: "Income", swap: "Transfer", trade: "Investment", bolt: "Automation" };
const TxnDetailSheet = ({ tx, onClose, nav }) => {
  const upcoming = tx.net == null;
  const amount = tx.net != null ? tx.net : (tx.tone === "out" ? -tx.amount : tx.amount);
  const category = TXN_CATEGORY[tx.icon] || (tx.cat ? tx.cat.charAt(0).toUpperCase() + tx.cat.slice(1) : "Activity");
  const method = tx.detail || tx.sub || "";
  const ask = () => { onClose(); nav.ask(`Tell me about this ${upcoming ? "scheduled item" : "transaction"}: ${tx.title}.`, `Here's what I have on "${tx.title}" — ${upcoming ? "it's scheduled" : "it settled"} ${tx.when}, ${amount >= 0 ? "a credit" : "a debit"} of ${usd(Math.abs(amount))} via ${method || category}. Want me to find related activity, set an alert, or categorize it differently?`); };
  return (
    <>
      <div className="yo-focus-backdrop" onClick={onClose} style={{ position: "absolute", inset: 0, background: "rgba(0,0,0,0.5)", zIndex: 300 }} />
      <div style={{ position: "absolute", left: 0, right: 0, bottom: 0, zIndex: 301, background: "var(--bg)", borderTop: "1px solid var(--accent)", maxHeight: "88%", display: "flex", flexDirection: "column" }} data-screen-label="Transaction detail">
        <div style={{ display: "flex", justifyContent: "center", paddingTop: 8, flex: "none" }}><span style={{ width: 36, height: 4, background: "var(--rule-2)", borderRadius: 999 }} /></div>
        <div className="scroll" style={{ padding: "12px 20px 26px" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <span style={{ fontFamily: "var(--f-display)", fontSize: 17, fontWeight: 600, letterSpacing: "-0.02em", flex: 1, minWidth: 0 }}>{tx.title}</span>
            <button className="press" onClick={onClose} aria-label="Close" style={{ background: "none", border: "none", display: "flex", color: "var(--ink-3)" }}><Icon name="close" size={19} /></button>
          </div>
          <div style={{ marginTop: 14 }}>
            <Money value={amount} size={38} weight={500} sign={amount > 0} color={amount > 0 ? "var(--accent-pos)" : "var(--ink)"} dim="var(--ink-3)" />
          </div>
          <Eyebrow style={{ marginTop: 7, color: upcoming ? "var(--accent)" : "var(--ink-3)" }}>{upcoming ? "Scheduled" : "Settled"} · {tx.when}</Eyebrow>

          <div style={{ marginTop: 18, border: "1px solid var(--rule)" }}>
            <ReviewRow label="Status" value={upcoming ? "Scheduled" : "Settled"} accent={upcoming ? "var(--accent)" : "var(--accent-pos)"} />
            <ReviewRow label="Date" value={tx.when} />
            <ReviewRow label="Category" value={category} />
            {method && <ReviewRow label="Method" value={method} />}
            <ReviewRow label="Amount" value={`${amount >= 0 ? "+" : "−"}${usd(Math.abs(amount))}`} last />
          </div>

          <div style={{ marginTop: 14 }}><Btn kind="ghost" full onClick={ask}>Ask Yoshi about this</Btn></div>
        </div>
      </div>
    </>);

};


/* ---- automation status pill + row ----------------------------------------- */
const StatusPill = ({ status }) => {
  const map = {
    active: ["●", "Active", "var(--accent)"],
    watching: ["○", "Watching", "var(--ink-3)"],
    paused: ["○", "Paused", "var(--ink-3)"]
  };
  const [dot, label, color] = map[status] || map.active;
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 3, padding: "1px 5px", borderRadius: 999, border: "1px solid var(--rule-2)", fontFamily: "var(--f-display)", fontSize: 7.5, fontWeight: 700, letterSpacing: "0.05em", textTransform: "uppercase", color, flex: "none" }}>
      <span style={{ fontSize: 5.5, lineHeight: 1 }}>{dot}</span>{label}
    </span>);

};

const AutomationRow = ({ a, onOpen }) =>
<button className="press" onClick={onOpen} style={{
  width: "100%", textAlign: "left", background: "var(--bg-card)", border: "1px solid var(--rule)", borderRadius: 10,
  display: "grid", gridTemplateColumns: "1fr auto auto", gap: 9, alignItems: "center", padding: "10px 11px 11px"
}}>
    <div style={{ minWidth: 0 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 7 }}>
        <span style={{ fontFamily: "var(--f-display)", fontSize: 13, fontWeight: 600, letterSpacing: "-0.01em", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.name}</span>
        <StatusPill status={a.status} />
      </div>
    </div>
    <div style={{ textAlign: "right" }}>
      <div style={{ fontFamily: "var(--f-mono)", fontSize: 13, color: a.measure.startsWith("+") ? "var(--accent-pos)" : "var(--ink-2)", fontVariantNumeric: "tabular-nums" }}>{a.measure}</div>
    </div>
    <Icon name="back" size={15} color="var(--ink-3)" style={{ transform: "scaleX(-1)" }} />
  </button>;


/* ---- automation row in the merged feed (flat, tappable, ◆ marker) ---------
   Mirrors TxnRow's two-line layout on both sides so row heights line up. */
const FeedAutoRow = ({ a, onOpen, last }) =>
<button className="press" onClick={onOpen} style={{
  width: "100%", textAlign: "left", background: "none", border: "none",
  display: "grid", gridTemplateColumns: "auto 1fr auto", gap: 11, alignItems: "center", padding: "9px 0", cursor: "pointer", borderBottom: last ? "none" : "1px solid var(--rule)"
}}>
    <RowIcon auto />
    <div style={{ minWidth: 0 }}>
      <div style={{ fontFamily: "var(--f-display)", fontSize: 13.5, fontWeight: 500, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.name}</div>
      <div style={{ fontFamily: "var(--f-display)", fontSize: 11, color: "var(--ink-3)", marginTop: 3, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{a.cadence}</div>
    </div>
    <div style={{ textAlign: "right", whiteSpace: "nowrap" }}>
      <div style={{ fontFamily: "var(--f-mono)", fontSize: 12.5, color: a.measure.startsWith("+") ? "var(--accent-pos)" : "var(--ink-3)", fontVariantNumeric: "tabular-nums" }}>{a.measure}</div>
      <div style={{ fontFamily: "var(--f-mono)", fontSize: 9.5, color: "var(--ink-3)", marginTop: 3 }}>{a.sub}</div>
    </div>
  </button>;


/* ---- automation detail sheet ---------------------------------------------- */
const AutomationSheet = ({ automation, onClose, nav, flash }) => {
  const a = automation;
  return (
    <>
      <div className="yo-focus-backdrop" onClick={onClose} style={{ position: "absolute", inset: 0, background: "rgba(0,0,0,0.5)", zIndex: 300 }} />
      <div style={{ position: "absolute", left: 0, right: 0, bottom: 0, zIndex: 301, background: "var(--bg)", borderTop: "1px solid var(--accent)", maxHeight: "92%", display: "flex", flexDirection: "column", animation: "sheet-in 320ms cubic-bezier(0.16,1,0.30,1) both" }}>
        <div style={{ display: "flex", justifyContent: "center", paddingTop: 8, flex: "none" }}><span style={{ width: 36, height: 4, background: "var(--rule-2)", borderRadius: 999 }} /></div>

        <div className="scroll" style={{ padding: "10px 20px 0" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <StatusPill status={a.status} />
            <span style={{ marginLeft: "auto", fontFamily: "var(--f-display)", fontSize: 10, fontWeight: 600, letterSpacing: "0.06em", color: "var(--ink-3)" }}>Automation</span>
          </div>
          <div style={{ fontFamily: "var(--f-display)", fontSize: 22, fontWeight: 600, letterSpacing: "-0.025em", marginTop: 9 }}>{a.name}</div>
          <div style={{ fontFamily: "var(--f-display)", fontSize: 13, color: "var(--ink-2)", marginTop: 6, lineHeight: 1.5 }}>{a.summary}</div>

          <Eyebrow style={{ margin: "16px 0 8px" }}>Performance</Eyebrow>
          {(() => {
            const hi = a.perf.findIndex(([k, v]) => v.replace(/\s/g, "").startsWith(a.measure.replace(/\s/g, "")));
            const headline = hi >= 0 ? a.perf[hi] : ["Return", a.measure];
            const rest = a.perf.filter((_, i) => i !== hi);
            const pos = headline[1].trim().startsWith("+");
            return (
              <div style={{ border: "1px solid var(--rule)" }}>
                {/* hero return */}
                <div style={{ display: "flex", alignItems: "baseline", gap: 10, padding: "13px 14px", borderBottom: rest.length ? "1px solid var(--rule)" : "none" }}>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontFamily: "var(--f-display)", fontSize: 10, fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--ink-3)" }}>{headline[0]}</div>
                    <div style={{ fontFamily: "var(--f-mono)", fontSize: 24, fontWeight: 500, marginTop: 4, fontVariantNumeric: "tabular-nums", color: pos ? "var(--accent-pos)" : "var(--ink)" }}>{headline[1]}</div>
                  </div>
                  <span style={{ marginLeft: "auto", fontFamily: "var(--f-display)", fontSize: 11.5, color: "var(--ink-3)", whiteSpace: "nowrap" }}>{a.sub}</span>
                </div>
                {/* supporting stats */}
                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr" }}>
                  {rest.map(([k, v], i) =>
                  <div key={k} style={{ padding: "11px 12px", borderBottom: i < rest.length - 2 ? "1px dashed var(--rule)" : "none", borderLeft: i % 2 ? "1px dashed var(--rule)" : "none" }}>
                      <div style={{ fontFamily: "var(--f-display)", fontSize: 10, fontWeight: 600, letterSpacing: "0.06em", textTransform: "uppercase", color: "var(--ink-3)" }}>{k}</div>
                      <div style={{ fontFamily: "var(--f-mono)", fontSize: 13.5, fontWeight: 500, marginTop: 3, color: v.trim().startsWith("+") ? "var(--accent-pos)" : "var(--ink)", fontVariantNumeric: "tabular-nums" }}>{v}</div>
                    </div>
                  )}
                </div>
              </div>);
          })()}
        </div>

        <div style={{ flex: "none", padding: "14px 20px 20px" }}>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 8 }}>
            <Btn kind="ghost" onClick={() => {onClose();nav.ask(`Analyze my "${a.name}" automation`, `Here's how "${a.name}" is doing: ${a.perf.map((p) => p.join(" ")).join(", ")}. Net it's pulling its weight. Want me to tune the cadence or the limits?`);}}>Analyze</Btn>
            <Btn kind="ghost" onClick={() => {onClose();nav.ask(`Edit my "${a.name}" automation`, `Sure, what should change on "${a.name}"? Right now it's set to: ${a.summary} (${a.next}). You can tell me a new schedule, amount, or scope (for example "make it $750 every other Friday" or "only run when cash is above $20k") and I'll update it and confirm.`);}}>Edit</Btn>
          </div>
          <Btn kind="danger" full onClick={() => {onClose();flash("Paused · " + a.name);}} style={{ marginTop: 8, color: "var(--signal-danger)", borderColor: "color-mix(in srgb, var(--signal-danger) 45%, transparent)" }}>Cancel automation</Btn>
        </div>
      </div>
    </>);

};

window.AutomationSheet = AutomationSheet;

window.Home = Home;