/**
 * Auto-recall hook — injects PULSE brain context before each agent turn.
 *
 * Hooks into `before_prompt_build` to prepend brain briefing as system context.
 * Truncates to maxContextTokens (~4 chars per token) to avoid context bloat.
 */

import type { PulseClient } from "../client.js";

interface RecallConfig {
  maxContextTokens: number;
}

/** Extract a search query from the last user message. */
export function extractQuery(messages: any[]): string {
  if (!messages?.length) return "";
  const lastUser = [...messages].reverse().find((m: any) => m.role === "user");
  if (!lastUser) return "";
  const content =
    typeof lastUser.content === "string"
      ? lastUser.content
      : JSON.stringify(lastUser.content);
  // Use first 500 chars as search query
  return content.slice(0, 500).trim();
}

/** Create the before_prompt_build handler. */
export function createAutoRecallHandler(
  client: PulseClient,
  config: RecallConfig
) {
  let lastBriefing = "";

  return async (event: any) => {
    try {
      const query = extractQuery(event.messages);
      if (!query || query.length < 3) return {};

      const briefing = await client.getBriefing(query);
      if (!briefing) return {};

      // Cache for timeout fallback
      lastBriefing = briefing;

      // Truncate to token budget (~4 chars per token)
      const maxChars = config.maxContextTokens * 4;
      const truncated =
        briefing.length > maxChars
          ? briefing.slice(0, maxChars) + "\n...(truncated)"
          : briefing;

      return {
        prependSystemContext: `<pulse_brain>\n${truncated}\n</pulse_brain>`,
      };
    } catch {
      // On timeout/error, use cached briefing if available
      if (lastBriefing) {
        const maxChars = config.maxContextTokens * 4;
        const truncated = lastBriefing.slice(0, maxChars);
        return {
          prependSystemContext: `<pulse_brain cached="true">\n${truncated}\n</pulse_brain>`,
        };
      }
      return {};
    }
  };
}
