// Chat screens — default + space (with right rail and sessions dropdown)

function ChatBubble({ msg }) {
  if (msg.role === "user") {
    return <div className="self-end max-w-[82%] bg-ink text-cream px-3.5 py-2.5 rounded-[14px_14px_4px_14px] text-[14.5px] leading-[1.55] whitespace-pre-wrap break-words">{msg.text}</div>;
  }
  return <div className="self-start max-w-[88%] text-body text-[14.5px] leading-[1.65] pl-0.5 whitespace-pre-wrap break-words">{msg.text}</div>;
}

function ReflectionStack({ reflections }) {
  const { dispatch, state } = useApp();
  if (!reflections || !reflections.length) return null;
  return (
    <div className="self-end max-w-[82%] flex flex-col gap-1.5 -mt-2 pr-1">
      {reflections.map((r, j) => {
        const doc = state.docs.find(d => d.id === r.docId);
        return (
          <button
            key={j}
            onClick={() => doc && dispatch({ type: "GO", view: { type: "doc", docId: r.docId } })}
            className="flex items-center gap-2 text-[11.5px] text-[#6B6253] bg-chipBg2 border border-chipBord px-2.5 py-1.5 rounded-lg text-left hover:bg-[#E7DDB9] transition group"
          >
            <Pulse tone={r.kind === "create" ? "warn" : "ok"} />
            <span className="truncate">
              <span className="text-ink font-medium">「{r.doc}」</span>
              <span className="text-dim ml-1">{r.kind === "create" ? "새 문서" : "반영"}</span>
            </span>
            <span className="ml-auto text-dim underline decoration-dotted opacity-0 group-hover:opacity-100 transition">열기 →</span>
          </button>
        );
      })}
    </div>
  );
}

// ─── Default chat ───────────────────────────────────────────
function DefaultChatView() {
  const { state, dispatch } = useApp();
  const bp = useBreakpoint();
  const ds = state.defaultSessions;
  const sessionId = state.view.sessionId || ds.find(s => s.active)?.id || ds[0]?.id;
  const session = ds.find(s => s.id === sessionId) || ds[0];
  const messages = (session && session.messages) || [];
  const scrollRef = React.useRef();
  React.useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [messages.length, sessionId]);

  return (
    <>
      <Topbar
        mobileTitle={session ? session.title : "기본 채팅"}
        mobileRight={
          <button
            onClick={() => dispatch({ type: "OPEN_MODAL", modal: { type: "move-session", fromSpaceId: "__default__", title: session?.title } })}
            aria-label="공간으로 옮기기"
            title="공간으로 옮기기"
            className="w-10 h-10 inline-flex items-center justify-center text-ink2"
          >
            <svg width="17" height="17" viewBox="0 0 17 17" fill="none"><path d="M4 11h7m0 0L8 8m3 3-3 3M7 3h6a2 2 0 0 1 2 2v2" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
          </button>
        }
        left={
          <Crumb>
            <Dot color="#8B7F6C" size={6} />
            <span className="text-ink font-medium">기본 채팅</span>
            <span className="text-dim mx-1">›</span>
            <DefaultSessionPicker session={session} />
          </Crumb>
        }
        right={
          <button
            onClick={() => dispatch({ type: "OPEN_MODAL", modal: { type: "move-session", fromSpaceId: "__default__", title: session?.title } })}
            className="hover:text-ink transition flex items-center gap-1.5"
          >공간으로 옮기기</button>
        }
      />
      <div ref={scrollRef} className="flex-1 overflow-y-auto scroll-paper flex justify-center px-3 sm:px-6 py-6 sm:py-8">
        <div className="w-full max-w-[700px] flex flex-col gap-5">
          <div className="text-center text-[11px] text-dim">{session?.when || "방금"}</div>
          {messages.length === 0 && (
            <div className="text-center text-[13px] text-dim py-10 flex flex-col items-center gap-2">
              <Dot color="#C4BAA3" size={10} />
              <div className="text-ink2 text-[14px] font-medium">새 기본 채팅</div>
              <div className="leading-[1.65] max-w-[360px]">
                아무거나 적어보세요. 정리할 만한 게 보이면 알려드릴게요.<br />
                <span className="text-mute">이 대화는 문서로 저장되지 않아요.</span>
              </div>
            </div>
          )}
          {messages.map(m => <ChatBubble key={m.id} msg={m} />)}
          {messages.length > 0 && (
            <div className="text-center text-[11px] text-dim pt-1">· 기본 채팅의 내용은 문서로 정리되지 않아요 ·</div>
          )}
        </div>
      </div>
      <ChatComposer
        placeholder="아무거나 적어보세요. 정리는 알아서."
        hint={null}
        onSend={(text) => dispatch({ type: "SEND_DEFAULT", text, sessionId: session?.id })}
      />
    </>
  );
}

// Picker dropdown for default sessions
function DefaultSessionPicker({ session }) {
  const { state, dispatch } = useApp();
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef();
  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);
  const sessions = state.defaultSessions;
  return (
    <div ref={ref} className="relative">
      <button
        onClick={() => setOpen(o => !o)}
        className={cn(
          "inline-flex items-center gap-1.5 px-2.5 py-[5px] rounded-md border text-[12.5px] text-ink font-medium transition max-w-[300px]",
          open ? "bg-chipBg border-rule" : "bg-paper border-rule hover:bg-[#FAF6EC]"
        )}
      >
        <span className="truncate">{session?.title || "기본 채팅"}</span>
        <span className="text-mute text-[11px]">▾</span>
      </button>
      {open && (
        <div className="absolute z-30 top-full left-0 mt-1.5 w-[340px] max-w-[calc(100vw-24px)] bg-paper border border-rule rounded-xl shadow-pop p-1.5">
          <div className="px-2.5 pt-2 pb-1 text-[10.5px] text-mute uppercase tracking-[0.08em] font-medium">기본 채팅의 세션</div>
          <div className="max-h-[280px] overflow-auto scroll-paper">
            {sessions.map(s => (
              <div
                key={s.id}
                className={cn(
                  "group flex items-start gap-2.5 px-2.5 py-2 rounded-md text-left transition",
                  s.id === session?.id ? "bg-chipBg" : "hover:bg-cream"
                )}
              >
                <button
                  onClick={() => { dispatch({ type: "PICK_DEFAULT_SESSION", sessionId: s.id }); setOpen(false); }}
                  className="flex-1 flex items-start gap-2.5 text-left min-w-0"
                >
                  <Dot color={s.id === session?.id ? "#3E9E72" : "#C4BAA3"} size={6} className="mt-1.5" />
                  <div className="flex-1 min-w-0">
                    <div className="flex items-baseline gap-2">
                      <span className={cn("text-[13px] text-ink truncate", s.id === session?.id ? "font-semibold" : "font-medium")}>{s.title}</span>
                      {s.id === session?.id && <span className="text-[10.5px] text-[#3E7C5C] font-medium shrink-0">지금</span>}
                    </div>
                    <div className="text-[11px] text-dim mt-0.5">{s.when} · {s.messages.length}개 메시지</div>
                  </div>
                </button>
                <div className="flex items-center -mr-1 shrink-0 opacity-0 group-hover:opacity-100 transition">
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      dispatch({ type: "OPEN_MODAL", modal: { type: "rename-session", kind: "default", sessionId: s.id, currentTitle: s.title } });
                      setOpen(false);
                    }}
                    aria-label="이름 바꾸기"
                    title="이름 바꾸기"
                    className="w-6 h-6 inline-flex items-center justify-center rounded text-mute hover:text-ink hover:bg-paper"
                  >
                    <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M8.5 2 10 3.5 4 9.5 2 10l.5-2Z" stroke="currentColor" strokeWidth="1.2" strokeLinejoin="round"/></svg>
                  </button>
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      if (!confirm(`「${s.title}」 세션을 삭제할까요? 메시지 기록이 사라져요.`)) return;
                      dispatch({ type: "DELETE_SESSION", kind: "default", sessionId: s.id });
                    }}
                    aria-label="세션 삭제"
                    className="w-6 h-6 inline-flex items-center justify-center rounded text-mute hover:text-[#C5524C] hover:bg-paper"
                  >
                    <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="m3 3 6 6m0-6-6 6" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>
                  </button>
                </div>
              </div>
            ))}
          </div>
          <div className="h-px bg-rule my-1.5 mx-2" />
          <button
            onClick={() => { dispatch({ type: "NEW_DEFAULT_SESSION" }); setOpen(false); }}
            className="w-full flex items-center gap-2 px-2.5 py-2 rounded-md text-[13px] text-ink font-medium hover:bg-cream"
          >
            <span className="w-3 text-center text-mute">＋</span>
            새 잡담 시작
          </button>
        </div>
      )}
    </div>
  );
}

// ─── Space chat ─────────────────────────────────────────────
function SpaceChatView() {
  const { state, dispatch, getSpace, getSession, docsForSpace } = useApp();
  const bp = useBreakpoint();
  const view = state.view;
  const space = getSpace(view.spaceId);
  const session = getSession(view.spaceId, view.sessionId);
  const messages = (session && session.messages) || [];
  const scrollRef = React.useRef();
  React.useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [messages.length]);

  // Touched docs = those referenced in last reflection set
  const touched = new Set();
  messages.forEach(m => (m.reflections || []).forEach(r => touched.add(r.docId)));

  if (!space || !session) {
    return <DefaultChatView />;
  }

  const ddocs = docsForSpace(space.id);
  const totalDocs = ddocs.length;

  return (
    <>
      <Topbar
        mobileTitle={`${space.name} · ${session.title}`}
        onBack={() => dispatch({ type: "GO", view: { type: "explore", spaceId: space.id } })}
        left={
          <>
            <button
              onClick={() => dispatch({ type: "GO", view: { type: "explore", spaceId: space.id } })}
              className="flex items-center gap-2 text-[13px] text-mute hover:text-ink transition shrink-0"
            >
              <Dot color={space.dot} />
              <span className="text-ink font-medium">{space.name}</span>
            </button>
            <span className="text-dim mx-1">›</span>
            <SessionPicker space={space} session={session} />
          </>
        }
        mobileRight={
          <>
            <button
              onClick={() => dispatch({ type: "TOGGLE_AUTO_ORGANIZE", spaceId: space.id, sessionId: session.id })}
              aria-label={session.autoOrganize === false ? "자동 정리 켜기" : "자동 정리 끄기"}
              title={session.autoOrganize === false ? "자동 정리 꺼짐 — 켜기" : "자동 정리 활성 — 끄기"}
              className="w-10 h-10 inline-flex items-center justify-center"
            >
              {session.autoOrganize === false
                ? <span className="w-2 h-2 rounded-full border-2 border-mute" />
                : <Pulse tone="ok" />
              }
            </button>
            <button
              onClick={() => dispatch({ type: "OPEN_MODAL", modal: { type: "move-session", fromSpaceId: space.id, sessionId: session.id, title: session.title } })}
              aria-label="세션 옮기기"
              title="세션 옮기기"
              className="w-10 h-10 inline-flex items-center justify-center text-ink2"
            >
              <svg width="17" height="17" viewBox="0 0 17 17" fill="none"><path d="M4 11h7m0 0L8 8m3 3-3 3M7 3h6a2 2 0 0 1 2 2v2" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
            </button>
          </>
        }
        right={
          <>
            <button
              onClick={() => dispatch({ type: "TOGGLE_AUTO_ORGANIZE", spaceId: space.id, sessionId: session.id })}
              className={cn(
                "inline-flex items-center gap-1.5 rounded-full px-2.5 py-[3px] text-[11.5px] font-medium transition border",
                session.autoOrganize === false
                  ? "bg-cream text-mute border-rule hover:text-ink"
                  : "bg-okSoft text-[#3E7C5C] border-okBord hover:bg-[#D7E9DD]"
              )}
              title={session.autoOrganize === false ? "이 세션은 정리 없이 흘러갑니다 — 켜기" : "자동 정리 끄기"}
            >
              {session.autoOrganize === false ? (
                <>
                  <span className="w-1.5 h-1.5 rounded-full bg-[#B6AB94]" />
                  자동 정리 꺼짐
                </>
              ) : (
                <><Pulse tone="ok" />자동 정리 활성</>
              )}
            </button>
            <button
              onClick={() => dispatch({ type: "OPEN_MODAL", modal: { type: "move-session", fromSpaceId: space.id, sessionId: session.id, title: session.title } })}
              className="hover:text-ink transition">세션 옮기기</button>
          </>
        }
      />

      <div className="flex-1 flex min-h-0">
        {/* Chat column */}
        <div className="flex-1 min-w-0 flex flex-col">
          <div ref={scrollRef} className="flex-1 overflow-y-auto scroll-paper flex justify-center px-3 sm:px-6 py-6 sm:py-8">
            <div className="w-full max-w-[620px] flex flex-col gap-5">
              <div className="text-center text-[11px] text-dim">
                {space.name} 공간 · 오늘 · {ddocs.filter(d => d.autoReflected).length}개 문서가 맥락에 활성화됨
              </div>
              {messages.length === 0 && (
                <div className="text-center text-[12.5px] text-dim py-10">
                  이 세션에는 아직 메시지가 없어요. 아래에 입력해보세요.
                </div>
              )}
              {messages.map(m => (
                <React.Fragment key={m.id}>
                  <ChatBubble msg={m} />
                  {m.reflections && <ReflectionStack reflections={m.reflections} />}
                </React.Fragment>
              ))}
            </div>
          </div>
          <ChatComposer
            placeholder={`${space.name} 공간에 이어 적기…`}
            hint={<span className="hidden sm:inline">⌘L 잠금 · ⌘K 검색</span>}
            onSend={(text) => dispatch({ type: "SEND_SPACE", spaceId: space.id, sessionId: session.id, text })}
          />
        </div>

        {/* Right rail (desktop only) — docs in this space */}
        {bp === "desktop" && (
          <aside className="w-[280px] shrink-0 border-l border-ruleSoft bg-parch2 px-4 py-5 flex flex-col gap-1 overflow-hidden">
            <div className="flex items-baseline justify-between px-1 pb-1.5">
              <div className="text-[11.5px] text-mute uppercase tracking-[0.06em] font-medium">이 공간의 문서</div>
              <div className="text-[11.5px] text-dim">{totalDocs}</div>
            </div>
            <div className="flex flex-col gap-1 overflow-auto scroll-paper -mx-1 px-1 flex-1">
              {ddocs.slice(0, 12).map(d => {
                const isTouched = touched.has(d.id) || state.flashDocIds.has(d.id);
                const isNew = d.isNew;
                return (
                  <button
                    key={d.id}
                    onClick={() => dispatch({ type: "GO", view: { type: "doc", docId: d.id } })}
                    className={cn(
                      "text-left rounded-md px-2.5 py-2 flex flex-col gap-0.5 transition border",
                      isTouched ? "bg-paper border-rule" : "border-transparent hover:bg-paper hover:border-ruleSoft"
                    )}
                  >
                    <div className="flex items-center gap-1.5">
                      {isTouched && <Pulse tone={isNew ? "warn" : "ok"} />}
                      <div className={cn("text-[12.5px] truncate flex-1", isTouched ? "text-ink font-medium" : "text-ink2")}>{d.title}</div>
                      {d.locked && <span className="text-[10px] text-dim">잠금</span>}
                    </div>
                    <div className={cn("text-[11px] truncate", isTouched ? "text-[#6B6253]" : "text-dim")}>
                      {isNew ? "방금 새로 생성됨" : isTouched ? "방금 자동 반영" : d.updated}
                    </div>
                  </button>
                );
              })}
            </div>
            <div className="pt-2.5 mt-1 border-t border-rule text-[11px] text-dim leading-[1.5] px-1">
              {touched.size > 0
                ? <>이번 턴이 <span className="text-ink font-medium">{touched.size}개 문서</span>에 반영됐어요.<br/>모든 자동 변경은 이력에 남고 되돌릴 수 있습니다.</>
                : <>이 공간에 메시지를 보내면 관련 문서에 자동 반영됩니다.</>
              }
            </div>
          </aside>
        )}
      </div>
    </>
  );
}

// ─── Session picker (dropdown) ──────────────────────────────
function SessionPicker({ space, session }) {
  const { state, dispatch } = useApp();
  const open = state.sessionsOpen;
  const sessions = state.sessions[space.id] || [];
  const ref = React.useRef();
  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) dispatch({ type: "CLOSE_SESSIONS" }); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);

  return (
    <div ref={ref} className="relative">
      <button
        onClick={() => dispatch({ type: "TOGGLE_SESSIONS" })}
        className={cn(
          "inline-flex items-center gap-1.5 px-2.5 py-[5px] rounded-md border text-[12.5px] text-ink font-medium transition max-w-[300px]",
          open ? "bg-chipBg border-rule" : "bg-paper border-rule hover:bg-[#FAF6EC]"
        )}
      >
        <Pulse tone="ok" />
        <span className="truncate">{session.title}</span>
        <span className="text-dim text-[11px] shrink-0">· {session.turns}턴</span>
        <span className="text-mute text-[11px] ml-0.5">▾</span>
      </button>
      {open && (
        <div className="absolute z-30 top-full left-0 mt-1.5 w-[360px] max-w-[calc(100vw-24px)] bg-paper border border-rule rounded-xl shadow-pop p-1.5">
          <div className="px-2.5 pt-2 pb-1 text-[10.5px] text-mute uppercase tracking-[0.08em] font-medium">{space.name} 공간의 세션</div>
          <div className="max-h-[280px] overflow-auto scroll-paper">
            {sessions.length === 0 && <div className="px-3 py-2 text-[12.5px] text-dim">세션이 없습니다.</div>}
            {sessions.map(s => (
              <div
                key={s.id}
                className={cn(
                  "group flex items-start gap-2.5 px-2.5 py-2 rounded-md text-left transition",
                  s.id === session.id ? "bg-chipBg" : "hover:bg-cream"
                )}
              >
                <button
                  onClick={() => dispatch({ type: "PICK_SESSION", spaceId: space.id, sessionId: s.id })}
                  className="flex-1 flex items-start gap-2.5 text-left min-w-0"
                >
                  <Dot color={s.id === session.id ? "#3E9E72" : "#C4BAA3"} size={6} className="mt-1.5" />
                  <div className="flex-1 min-w-0">
                    <div className="flex items-baseline gap-2">
                      <span className={cn("text-[13px] text-ink truncate", s.id === session.id ? "font-semibold" : "font-medium")}>{s.title}</span>
                      {s.id === session.id && <span className="text-[10.5px] text-[#3E7C5C] font-medium shrink-0">지금</span>}
                    </div>
                    <div className="text-[11px] text-dim mt-0.5 flex flex-wrap gap-1.5">
                      <span>{s.when}</span><span>·</span>
                      <span>{s.turns}턴</span><span>·</span>
                      <span>{s.docsTouched === 0 ? "문서 변경 없음" : `문서 ${s.docsTouched}건 영향`}</span>
                    </div>
                    {s.note && <div className="text-[11px] text-mute italic mt-0.5">{s.note}</div>}
                  </div>
                </button>
                <div className="flex items-center -mr-1 shrink-0 opacity-0 group-hover:opacity-100 transition">
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      dispatch({ type: "OPEN_MODAL", modal: { type: "rename-session", kind: "space", spaceId: space.id, sessionId: s.id, currentTitle: s.title } });
                    }}
                    aria-label="이름 바꾸기"
                    title="이름 바꾸기"
                    className="w-6 h-6 inline-flex items-center justify-center rounded text-mute hover:text-ink hover:bg-paper"
                  >
                    <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M8.5 2 10 3.5 4 9.5 2 10l.5-2Z" stroke="currentColor" strokeWidth="1.2" strokeLinejoin="round"/></svg>
                  </button>
                  <button
                    onClick={(e) => {
                      e.stopPropagation();
                      if (!confirm(`「${s.title}」 세션을 삭제할까요? 메시지 기록이 사라져요.`)) return;
                      dispatch({ type: "DELETE_SESSION", kind: "space", spaceId: space.id, sessionId: s.id });
                    }}
                    aria-label="세션 삭제"
                    className="w-6 h-6 inline-flex items-center justify-center rounded text-mute hover:text-[#C5524C] hover:bg-paper"
                  >
                    <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="m3 3 6 6m0-6-6 6" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg>
                  </button>
                </div>
              </div>
            ))}
          </div>
          <div className="h-px bg-rule my-1.5 mx-2" />
          <button
            onClick={() => dispatch({ type: "NEW_SESSION", spaceId: space.id, title: "새 세션" })}
            className="w-full flex items-center gap-2 px-2.5 py-2 rounded-md text-[13px] text-ink font-medium hover:bg-cream"
          >
            <span className="w-3 text-center text-mute">＋</span>
            새 세션 시작
          </button>
          <div className="text-[11px] text-dim px-3 pt-1 pb-1.5 leading-[1.5]">
            세션은 흐름 보존용 — 검색에는 잡히지 않아요.
          </div>
        </div>
      )}
    </div>
  );
}

function SessionMobileMenu({ space, session }) {
  const { dispatch } = useApp();
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef();
  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, [open]);
  const autoOn = session.autoOrganize !== false;
  return (
    <div ref={ref} className="relative">
      <button
        onClick={() => setOpen(o => !o)}
        aria-label="세션 메뉴"
        className="w-10 h-10 inline-flex items-center justify-center text-ink2"
      >
        <svg width="18" height="18" viewBox="0 0 18 18" fill="none"><circle cx="9" cy="4" r="1.4" fill="currentColor"/><circle cx="9" cy="9" r="1.4" fill="currentColor"/><circle cx="9" cy="14" r="1.4" fill="currentColor"/></svg>
      </button>
      {open && (
        <div className="absolute right-1 top-full mt-1 w-[230px] bg-paper border border-rule rounded-xl shadow-pop py-1 z-30">
          <button
            onClick={() => { dispatch({ type: "TOGGLE_AUTO_ORGANIZE", spaceId: space.id, sessionId: session.id }); setOpen(false); }}
            className="w-full flex items-center gap-2.5 px-3 py-2.5 text-left text-[13.5px] text-ink hover:bg-cream"
          >
            <span className={cn("w-1.5 h-1.5 rounded-full ml-0.5 mr-0.5", autoOn ? "bg-ok" : "bg-[#B6AB94]")} />
            <span className="flex-1">자동 정리 {autoOn ? "활성" : "꺼짐"}</span>
            <span className="text-[11.5px] text-dim">{autoOn ? "끄기" : "켜기"}</span>
          </button>
          <button
            onClick={() => { dispatch({ type: "OPEN_MODAL", modal: { type: "rename-session", kind: "space", spaceId: space.id, sessionId: session.id, currentTitle: session.title } }); setOpen(false); }}
            className="w-full flex items-center gap-2.5 px-3 py-2.5 text-left text-[13.5px] text-ink hover:bg-cream"
          >
            <span className="w-2.5 text-center text-mute">✎</span>
            <span className="flex-1">이름 바꾸기</span>
          </button>
          <button
            onClick={() => { dispatch({ type: "OPEN_MODAL", modal: { type: "move-session", fromSpaceId: space.id, sessionId: session.id, title: session.title } }); setOpen(false); }}
            className="w-full flex items-center gap-2.5 px-3 py-2.5 text-left text-[13.5px] text-ink hover:bg-cream"
          >
            <span className="w-2.5 text-center text-mute">↗</span>
            <span className="flex-1">세션 옮기기</span>
          </button>
          <div className="h-px bg-rule my-1 mx-2" />
          <button
            onClick={() => {
              if (!confirm(`「${session.title}」 세션을 삭제할까요? 메시지 기록이 사라져요.`)) return;
              dispatch({ type: "DELETE_SESSION", kind: "space", spaceId: space.id, sessionId: session.id });
              setOpen(false);
            }}
            className="w-full flex items-center gap-2.5 px-3 py-2.5 text-left text-[13.5px] text-[#C5524C] hover:bg-[#FBEEEC]"
          >
            <span className="w-2.5 text-center">×</span>
            <span className="flex-1">세션 삭제</span>
          </button>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { ChatBubble, ReflectionStack, DefaultChatView, DefaultSessionPicker, SpaceChatView, SessionPicker, SessionMobileMenu });
