'use client';

import { create } from 'zustand';

/**
 * 助手窗的外部控制口 —— 让**业务代码**能打开助手并塞一句话进去。
 *
 * ── 为什么必须有这个 store ──────────────────────────────────
 * 在此之前助手窗是完全自闭的:
 *   · `AssistantWidget` 的 `open` 是组件内 `useState`,外面打不开;
 *   · `useAssistantChat()` 在 `AssistantChat` 内部实例化,`send` 不外露。
 * 于是「在召回池点一下,把这批人移交给助手」这件事**根本无处落地** ——
 * 不是难写,是没有接口。这 30 行就是那个接口。
 *
 * ── 为什么用 seq 而不是"消费完置空" ─────────────────────────
 * 与 `plan-sync-store` 同款:自增序号触发订阅,消费方按 seq 变化执行一次。
 * 用"置空"表达已消费需要消费方回写 store,那是双向数据流,
 * StrictMode 双执行下会变成"发一次跑两次 / 或一次都不跑"。
 *
 * ⚠️ `AssistantWidget` 收起时是 **CSS 隐藏而非卸载**(见那里的注释:对话/工具步骤/
 * 听写状态全靠这个保留)。store 化之后**必须保持这个特性** ——
 * 若顺手改成条件渲染,主管每收一次助手就丢一次对话,而这在代码上看不出任何异常。
 */
interface AssistantState {
  open: boolean;
  setOpen: (open: boolean) => void;
  /**
   * 待发送的一句话。`seq` 自增即为"有新请求";`text` 是要替主管说的话。
   * null = 没有待处理请求。
   */
  pending: { text: string; seq: number } | null;
  /** 打开助手并发一句话(移交入口用) */
  ask: (text: string) => void;
  /** 消费方(AssistantChat)发完后调,避免重复发送 */
  consume: (seq: number) => void;
}

export const useAssistantStore = create<AssistantState>((set, get) => ({
  open: false,
  setOpen: (open) => set({ open }),
  pending: null,
  ask: (text) => {
    const seq = (get().pending?.seq ?? 0) + 1;
    // 先开窗再挂待办:窗没开就发消息,主管会看到助手"自己动了"却不知道在哪
    set({ open: true, pending: { text, seq } });
  },
  consume: (seq) => {
    // 只清掉自己那一条 —— 期间若又来了新请求(seq 更大),不能连它一起清
    if (get().pending?.seq === seq) set({ pending: null });
  },
}));
