import { randomUUID } from "node:crypto";
import { extractCandidatesFromWorkflowOutcome, } from "@oscharko-dev/keiko-memory-capture";
import { retrieveMemoryContext } from "@oscharko-dev/keiko-memory-retrieval";
import { recordMemoryAudit } from "./memory-audit-handler.js";
import { vaultAsQueryPort } from "./memory-conv-handlers.js";
import { LOCAL_CONVERSATION_MEMORY_USER_ID } from "./memory-conversation-context.js";
import { buildMemoryRecordFromProposal } from "./memory-record-builders.js";
function recordRetrievedAudit(options, now, scopes, matchedMemoryIds) {
    if (matchedMemoryIds.length === 0) {
        return;
    }
    recordMemoryAudit({
        evidenceStore: options.evidenceStore,
        redactString: options.redactString,
        now,
    }, {
        schemaVersion: "1",
        kind: "memory:retrieved",
        eventId: randomUUID(),
        occurredAt: now(),
        initiatorSurface: "workflow",
        summary: matchedMemoryIds.length === 1
            ? "Retrieved 1 memory for workflow context."
            : `Retrieved ${String(matchedMemoryIds.length)} memories for workflow context.`,
        scopes,
        matchedMemoryIds,
    });
}
function recordWorkflowUsedAudit(options, now, event) {
    recordMemoryAudit({
        evidenceStore: options.evidenceStore,
        redactString: options.redactString,
        now,
    }, {
        schemaVersion: "1",
        kind: "memory:workflow-used",
        eventId: randomUUID(),
        occurredAt: now(),
        initiatorSurface: "workflow",
        summary: event.memoryIds.length === 1
            ? `Workflow used 1 memory (${event.reason}).`
            : `Workflow used ${String(event.memoryIds.length)} memories (${event.reason}).`,
        workflowRunId: options.runId,
        usedMemoryIds: event.memoryIds,
    });
}
function persistWorkflowCandidates(options, event, capturedAt) {
    const outcomes = extractCandidatesFromWorkflowOutcome({
        runId: options.runId,
        outcomeKind: event.source === "workflow-correction" ? "corrected" : "success",
        structuredReport: event.proposalSummary,
        capturedAt,
    }, captureContextFor(event.scope, capturedAt, options.runId), { scopeKind: event.scope.kind });
    for (const outcome of outcomes) {
        if (outcome.kind !== "candidate") {
            continue;
        }
        const proposalId = outcome.proposal.proposalId;
        const record = buildMemoryRecordFromProposal(proposalId, outcome);
        if (record !== null) {
            options.vault.insertMemory(record);
        }
    }
}
function captureContextFor(scope, nowMs, runId) {
    return {
        userId: LOCAL_CONVERSATION_MEMORY_USER_ID,
        ...(scope.kind === "workspace" ? { workspaceId: scope.workspaceId } : {}),
        ...(scope.kind === "project" ? { projectId: scope.projectId } : {}),
        ...(scope.kind === "workflow"
            ? {
                workflowDefinitionId: scope.workflowDefinitionId,
                sourceWorkflowRunId: runId,
            }
            : {}),
        nowMs,
        newMemoryId: () => randomUUID(),
        newProposalId: () => randomUUID(),
    };
}
export function createWorkflowMemoryPort(options) {
    const now = options.now ?? Date.now;
    const queryPort = vaultAsQueryPort(options.vault);
    return {
        getContextForWorkflow(scopes, queryText, budgetTokens) {
            const result = retrieveMemoryContext({
                scopes,
                nowMs: now(),
                ...(queryText === undefined ? {} : { queryText }),
                ...(budgetTokens === undefined ? {} : { budgetTokens }),
            }, queryPort);
            recordRetrievedAudit(options, now, scopes, result.included.map((item) => item.memoryId));
            return Promise.resolve({
                text: result.contextBlock.text,
                includedMemoryIds: result.contextBlock.memories.map((item) => item.memoryId),
            });
        },
        onMemoryUsed(event) {
            recordWorkflowUsedAudit(options, now, event);
        },
        onMemoryWriteCandidate(event) {
            persistWorkflowCandidates(options, event, now());
        },
    };
}
