import { randomUUID } from 'crypto';
import { nexusEventBus } from '../../engines/event-bus.js';
import { insertBlueprint, insertWorkItem, insertWorklist, getBlueprint, getWorklist } from '../worklist/crud.js';
function interpolate(value, variables) {
    return value.replace(/\{\{(\w+)\}\}/g, (_, key) => variables[key] ?? '');
}
export function instantiateBlueprint(db, providers, input) {
    const workflow = providers.workflowRuntime.getArtifact(input.workflowId) ?? providers.workflowRuntime.findByName(input.workflowId);
    if (!workflow) {
        throw new Error(`[Architects] Unknown workflowId: ${input.workflowId}`);
    }
    const blueprintId = randomUUID();
    const worklistId = randomUUID();
    const variables = input.variables ?? {};
    const items = db.transaction(() => {
        insertBlueprint(db, {
            id: blueprintId,
            strikeTeamId: input.strikeTeamId ?? null,
            title: input.title,
            workflowId: workflow.workflowId,
            status: 'active',
            variables,
            worklistId,
        });
        insertWorklist(db, {
            id: worklistId,
            blueprintId,
            title: input.title,
        });
        let previousItemId = null;
        return workflow.steps.map((step) => {
            const item = insertWorkItem(db, {
                id: randomUUID(),
                worklistId,
                title: interpolate(step.title, variables),
                parentWorkItemId: previousItemId,
                correlationId: blueprintId,
                ancestryPath: previousItemId ? [blueprintId, previousItemId] : [blueprintId],
                status: 'todo',
                dependsOn: previousItemId ? [previousItemId] : [],
                assignedOperativeId: null,
                constructionLockId: null,
                branch: null,
                mergedAt: null,
                createdAt: new Date().toISOString(),
            });
            previousItemId = item.id;
            return item;
        });
    })();
    nexusEventBus.emit('architects.blueprint.instantiated', {
        blueprintId,
        worklistId,
        workItemCount: items.length,
    });
    nexusEventBus.emit('architects.worklist.created', {
        worklistId,
        blueprintId,
    });
    return {
        blueprint: getBlueprint(db, blueprintId),
        worklist: getWorklist(db, worklistId),
        items,
    };
}
