import { getSession } from "../lib/neo4j.js";
import { notTrashed } from "../../../../../lib/graph-trash/dist/index.js";
const DEFAULT_WINDOW_HOURS = 24;
const MAX_WINDOW_HOURS = 720;
const DEFAULT_LIMIT = 50;
const MAX_LIMIT = 200;
export async function memorySignalsRecent(params) {
    const { accountId } = params;
    const windowHours = Math.min(Math.max(params.windowHours ?? DEFAULT_WINDOW_HOURS, 1), MAX_WINDOW_HOURS);
    const limit = Math.min(Math.max(params.limit ?? DEFAULT_LIMIT, 1), MAX_LIMIT);
    const session = getSession();
    try {
        // Mentions: :Message-[:MENTIONS]->Entity edges written by signal-detector
        // since the cutoff. Excerpt is the first 120 chars of the message body
        // so the operator sees enough to recognise context without a separate read.
        const mentionsResult = await session.run(`MATCH (m:Message)-[r:MENTIONS]->(e)
       WHERE m.accountId = $accountId
         AND r.createdByAgent = 'signal-detector'
         AND r.createdAt > datetime() - duration({hours: $windowHours})
         AND ${notTrashed("m")}
         AND ${notTrashed("e")}
       RETURN labels(e) AS entityLabels,
              coalesce(e.name, e.title, '<unnamed>') AS entityName,
              m.conversationId AS conversationId,
              elementId(m) AS messageId,
              substring(coalesce(m.body, m.text, ''), 0, 120) AS messageExcerpt,
              toString(r.createdAt) AS observedAt
       ORDER BY r.createdAt DESC
       LIMIT $limit`, { accountId, windowHours, limit });
        const mentions = mentionsResult.records.map((rec) => ({
            kind: "mention",
            entityLabel: (rec.get("entityLabels") ?? []).find((l) => l !== "Trashed") ?? "Unknown",
            entityName: String(rec.get("entityName") ?? ""),
            conversationId: String(rec.get("conversationId") ?? ""),
            messageId: String(rec.get("messageId") ?? ""),
            messageExcerpt: String(rec.get("messageExcerpt") ?? ""),
            observedAt: String(rec.get("observedAt") ?? ""),
        }));
        // Ideas: :Idea nodes written by signal-detector since the cutoff.
        const ideasResult = await session.run(`MATCH (i:Idea)
       WHERE i.accountId = $accountId
         AND i.createdByAgent = 'signal-detector'
         AND i.createdAt > datetime() - duration({hours: $windowHours})
         AND ${notTrashed("i")}
       RETURN coalesce(i.conversationId, '<none>') AS conversationId,
              coalesce(i.body, '') AS ideaBody,
              toString(i.createdAt) AS observedAt
       ORDER BY i.createdAt DESC
       LIMIT $limit`, { accountId, windowHours, limit });
        const ideas = ideasResult.records.map((rec) => ({
            kind: "idea",
            conversationId: String(rec.get("conversationId") ?? ""),
            ideaBody: String(rec.get("ideaBody") ?? ""),
            observedAt: String(rec.get("observedAt") ?? ""),
        }));
        // Interleaved by observedAt desc so the operator scans a single
        // chronological feed instead of two separate sections.
        const rows = [...mentions, ...ideas].sort((a, b) => a.observedAt < b.observedAt ? 1 : a.observedAt > b.observedAt ? -1 : 0);
        return {
            rows: rows.slice(0, limit),
            windowHours,
            counts: {
                mentions: mentions.length,
                ideas: ideas.length,
                total: mentions.length + ideas.length,
            },
        };
    }
    finally {
        await session.close();
    }
}
//# sourceMappingURL=memory-signals-recent.js.map