/* anim-memory.jsx — Memory & state animation
 * Shows: short-term buffer fills up → summary memory compresses →
 *        long-term semantic memory writes to vector store
 */

const MemorySim = () => {
  // 8 messages flow through, buffer shows last 4, summary updates,
  // and 2 of them get embedded into the vector store
  const MESSAGES = [
    { role: "user", text: "I'm planning a trip to Japan in May.", embed: true, embedAs: "user_pref: travel_plan_japan_may" },
    { role: "assistant", text: "Great! Cities, food, or temples first?", embed: false },
    { role: "user", text: "I love ramen and quiet gardens.", embed: true, embedAs: "user_pref: likes_ramen_quiet_gardens" },
    { role: "assistant", text: "Kyoto's perfect — Ryōan-ji and Ippudo near Gion.", embed: false },
    { role: "user", text: "How long should I stay there?", embed: false },
    { role: "assistant", text: "4 nights covers the highlights.", embed: false },
    { role: "user", text: "And in Tokyo?", embed: false },
    { role: "assistant", text: "3 nights — Asakusa + Shibuya + a day trip.", embed: false },
  ];

  const STEPS = MESSAGES.length;
  const { step, playing, toggle, next, prev, reset, containerRef } = useStepper({ steps: STEPS, intervalMs: 1600 });

  // Visible buffer = last 4 messages up to step
  const visible = MESSAGES.slice(0, step + 1);
  const buffer = visible.slice(-4);
  const evicted = visible.length > 4 ? visible.slice(0, visible.length - 4) : [];
  const summary = evicted.length > 0
    ? "User plans Japan trip in May. Likes ramen + gardens. Recommended Kyoto (Ryōan-ji, Ippudo)."
    : null;
  const semanticWrites = MESSAGES.slice(0, step + 1).filter(m => m.embed);

  return (
    <div ref={containerRef}>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 16, alignItems: "stretch" }}>
        {/* SHORT-TERM BUFFER */}
        <div style={panel}>
          <div style={panelLabel}>SHORT-TERM · buffer (window=4)</div>
          <div style={{ minHeight: 200, display: "flex", flexDirection: "column", gap: 6, padding: 12 }}>
            {buffer.map((m, i) => (
              <MsgChip key={`${step}-${i}`} m={m} fresh={i === buffer.length - 1} />
            ))}
            {buffer.length < 4 && Array.from({ length: 4 - buffer.length }).map((_, i) => (
              <div key={`e-${i}`} style={emptySlot}></div>
            ))}
          </div>
          <div style={panelFoot}>oldest evicted →</div>
        </div>

        {/* SUMMARY MEMORY */}
        <div style={panel}>
          <div style={panelLabel}>SUMMARY · running gist</div>
          <div style={{ padding: 14, minHeight: 200, fontSize: 13, color: "#3d3d3a", lineHeight: 1.55 }}>
            {summary ? (
              <>
                <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 10, color: "#a3a39d", marginBottom: 8 }}>
                  // compressed by LLM after eviction
                </div>
                <div style={{ animation: "fadeIn 0.5s" }}>{summary}</div>
              </>
            ) : (
              <div style={{ color: "#a3a39d", fontStyle: "italic", fontSize: 13 }}>
                — empty until messages start being evicted —
              </div>
            )}
          </div>
          <div style={panelFoot}>{summary ? `${evicted.length} message(s) condensed` : "0 evicted"}</div>
        </div>

        {/* LONG-TERM VECTOR STORE */}
        <div style={panel}>
          <div style={panelLabel}>LONG-TERM · vector store</div>
          <div style={{ padding: 12, minHeight: 200 }}>
            {semanticWrites.length === 0 && (
              <div style={{ color: "#a3a39d", fontStyle: "italic", fontSize: 13 }}>
                — no facts written yet —
              </div>
            )}
            {semanticWrites.map((m, i) => (
              <VectorRow key={i} text={m.embedAs} fresh={i === semanticWrites.length - 1 && MESSAGES[step]?.embed} />
            ))}
          </div>
          <div style={panelFoot}>{semanticWrites.length} fact(s), retrievable across threads</div>
        </div>
      </div>

      <div style={{ marginTop: 20, fontSize: 13, color: "#6b6b66", textAlign: "center", fontFamily: "JetBrains Mono, monospace" }}>
        message {String(step + 1).padStart(2, "0")} / {STEPS} &nbsp;·&nbsp;
        <span style={{ color: "#1a1a1a" }}>{MESSAGES[step].role}:</span> "{MESSAGES[step].text}"
      </div>
    </div>
  );
};

const panel = {
  background: "#fbfbfa",
  border: "1px solid #e7e7e2",
  borderRadius: 8,
  display: "flex", flexDirection: "column",
  overflow: "hidden",
};
const panelLabel = {
  fontFamily: "JetBrains Mono, monospace",
  fontSize: 10,
  letterSpacing: "0.06em",
  textTransform: "uppercase",
  color: "#6b6b66",
  padding: "10px 14px",
  borderBottom: "1px solid #e7e7e2",
  background: "#f4f4f1",
};
const panelFoot = {
  marginTop: "auto",
  padding: "8px 14px",
  borderTop: "1px solid #e7e7e2",
  background: "#f4f4f1",
  fontSize: 11,
  color: "#a3a39d",
  fontFamily: "JetBrains Mono, monospace",
};
const emptySlot = {
  border: "1px dashed #e7e7e2",
  borderRadius: 4,
  height: 36,
};

const MsgChip = ({ m, fresh }) => (
  <div style={{
    background: m.role === "user" ? "#fff" : "#e8f0fe",
    border: `1px solid ${m.role === "user" ? "#e7e7e2" : "#c5d8f5"}`,
    borderRadius: 4,
    padding: "6px 10px",
    fontSize: 12,
    color: "#1a1a1a",
    animation: fresh ? "slideIn 0.4s ease" : undefined,
    display: "flex", flexDirection: "column", gap: 2,
  }}>
    <div style={{ fontFamily: "JetBrains Mono, monospace", fontSize: 9, color: "#6b6b66", textTransform: "uppercase" }}>
      {m.role}
    </div>
    <div style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{m.text}</div>
  </div>
);

const VectorRow = ({ text, fresh }) => (
  <div style={{
    display: "flex", gap: 8, alignItems: "center",
    padding: "8px 10px",
    borderRadius: 4,
    background: fresh ? "#e3f1e8" : "#fff",
    border: "1px solid #e7e7e2",
    marginBottom: 6,
    fontFamily: "JetBrains Mono, monospace",
    fontSize: 11,
    animation: fresh ? "slideIn 0.4s ease" : undefined,
  }}>
    <span style={{ color: "#2e7d4f" }}>▸</span>
    <span style={{ color: "#3d3d3a" }}>{text}</span>
  </div>
);

window.MemorySim = MemorySim;
