import crypto from "node:crypto";
import { openPlanningStores } from "./persistence/planning-open.js";
import { planningConcurrencySaveOpts } from "./mutation-utils.js";
import { validateKnownTaskTypeRequirements } from "./task-type-validation.js";
import { TRANSCRIPT_CHURN_TASK_TYPE } from "./transcript-churn.js";
import { CLI_REMEDIATION_INSTRUCTIONS } from "../../core/cli-remediation.js";
function isNonEmptyString(x) {
    return typeof x === "string" && x.trim().length > 0;
}
/**
 * Convert **`transcript_churn` / `research`** → **`improvement` / `proposed`** after investigation.
 * Caller must enforce **`planningGenerationPolicy`** (see task-engine-internal).
 */
export async function runSynthesizeTranscriptChurnCommand(ctx, args) {
    const taskId = typeof args.taskId === "string" ? args.taskId.trim() : "";
    const synthesis = args.synthesis;
    if (!taskId || !synthesis || typeof synthesis !== "object" || Array.isArray(synthesis)) {
        return {
            ok: false,
            code: "invalid-task-schema",
            message: "synthesize-transcript-churn requires taskId and synthesis object",
            remediation: { instructionPath: CLI_REMEDIATION_INSTRUCTIONS.synthesizeTranscriptChurn }
        };
    }
    const syn = synthesis;
    if (!isNonEmptyString(syn.approach) ||
        !Array.isArray(syn.technicalScope) ||
        !Array.isArray(syn.acceptanceCriteria) ||
        !syn.metadata ||
        typeof syn.metadata !== "object" ||
        Array.isArray(syn.metadata)) {
        return {
            ok: false,
            code: "invalid-task-schema",
            message: "synthesis requires approach, technicalScope[], acceptanceCriteria[], metadata{}",
            remediation: { instructionPath: CLI_REMEDIATION_INSTRUCTIONS.synthesizeTranscriptChurn }
        };
    }
    const metaIn = syn.metadata;
    if (!isNonEmptyString(metaIn.issue) || !isNonEmptyString(metaIn.supportingReasoning)) {
        return {
            ok: false,
            code: "invalid-task-schema",
            message: "synthesis.metadata requires non-empty issue and supportingReasoning strings",
            remediation: { instructionPath: CLI_REMEDIATION_INSTRUCTIONS.synthesizeTranscriptChurn }
        };
    }
    const planning = await openPlanningStores(ctx);
    const store = planning.taskStore;
    const task = store.getTask(taskId);
    if (!task) {
        return { ok: false, code: "task-not-found", message: `Task '${taskId}' not found` };
    }
    if (task.type !== TRANSCRIPT_CHURN_TASK_TYPE || task.status !== "research") {
        return {
            ok: false,
            code: "invalid-task-schema",
            message: `synthesize-transcript-churn requires type '${TRANSCRIPT_CHURN_TASK_TYPE}' and status 'research' (got '${task.type}' / '${task.status}')`
        };
    }
    const priorMeta = task.metadata && typeof task.metadata === "object" && !Array.isArray(task.metadata)
        ? { ...task.metadata }
        : {};
    const researchForensics = typeof priorMeta.issue === "string" ? priorMeta.issue : "";
    const proposedSolutions = Array.isArray(metaIn.proposedSolutions) && metaIn.proposedSolutions.length > 0
        ? metaIn.proposedSolutions.filter((x) => isNonEmptyString(x))
        : Array.isArray(priorMeta.proposedSolutions)
            ? priorMeta.proposedSolutions.filter((x) => isNonEmptyString(x))
            : [];
    const nextMeta = {
        ...priorMeta,
        researchForensicsSnapshot: researchForensics,
        issue: metaIn.issue.trim(),
        supportingReasoning: metaIn.supportingReasoning.trim(),
        synthesizedFromTranscriptChurn: true
    };
    if (proposedSolutions.length > 0) {
        nextMeta.proposedSolutions = proposedSolutions;
    }
    const next = {
        ...task,
        type: "improvement",
        status: "proposed",
        title: isNonEmptyString(syn.title) ? syn.title.trim() : task.title,
        approach: syn.approach.trim(),
        technicalScope: syn.technicalScope.filter((x) => isNonEmptyString(x)),
        acceptanceCriteria: syn.acceptanceCriteria.filter((x) => isNonEmptyString(x)),
        metadata: nextMeta,
        updatedAt: new Date().toISOString()
    };
    const verr = validateKnownTaskTypeRequirements(next);
    if (verr) {
        return { ok: false, code: verr.code, message: verr.message };
    }
    store.updateTask(next);
    const ts = next.updatedAt;
    store.addEvidence({
        transitionId: `${taskId}-${ts}-${crypto.randomUUID().slice(0, 8)}`,
        taskId,
        fromState: "research",
        toState: "proposed",
        action: "synthesize-transcript-churn",
        guardResults: [{ allowed: true, guardName: "synthesize-transcript-churn" }],
        dependentsUnblocked: [],
        timestamp: ts,
        actor: typeof args.actor === "string" ? args.actor : ctx.resolvedActor
    });
    await store.save(planningConcurrencySaveOpts(args));
    return {
        ok: true,
        code: "transcript-churn-synthesized",
        message: `${taskId}: transcript_churn/research → improvement/proposed`,
        data: { task: store.getTask(taskId) }
    };
}
